package routers

//2026-4-2开始每个功能的数据表在各自的api路由下初始化

import (
	"encoding/json"
	"ops/models"
	"slices"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/mitchellh/mapstructure"
	"gorm.io/gorm"
)

type TabSchedule struct {
	ID        uint   `gorm:"primarykey"`
	UserID    uint   `gorm:"not null;comment:创建人ID"`
	Title     string `gorm:"size:200;not null;comment:日程标题"`
	StartDate string `gorm:"size:10;not null;index;comment:开始日期 YYYY-MM-DD"`
	EndDate   string `gorm:"size:10;not null;index;comment:结束日期 YYYY-MM-DD"`
	BgColor   string `gorm:"size:50;default:#3788d9;comment:背景颜色"`
	Remark    string `gorm:"type:text;comment:备注"`

	CreatedAt *time.Time     `gorm:"type:datetime;autoCreateTime;comment:创建时间"`
	UpdatedAt *time.Time     `gorm:"type:datetime;autoUpdateTime;comment:最后修改时间"`
	DeletedAt gorm.DeletedAt `gorm:"index"`
}

type TabScheduleLog struct {
	ID         uint   `gorm:"primarykey"`
	ScheduleID uint   `gorm:"not null;index;comment:关联日程ID"`
	UserID     uint   `gorm:"not null;comment:操作人ID"`
	ActionType string `gorm:"size:50;not null;comment:操作类型: create-创建 update-修改 delete-删除 query-查询"`
	OldContent string `gorm:"type:text;comment:修改前内容(JSON)"`
	NewContent string `gorm:"type:text;comment:修改后内容(JSON)"`
	IP         string `gorm:"size:50;comment:操作IP"`
	Remark     string `gorm:"size:500;comment:备注/操作描述"`

	CreatedAt *time.Time `gorm:"type:datetime;autoCreateTime;comment:操作时间"`
}
type fromAddEvent struct {
	ID    uint   `json:"id"`
	Title string `json:"title" binding:"required"` // 日程标题
	Start string `json:"start" binding:"required"` // 开始日期
	End   string `json:"end" binding:"required"`   // 结束日期
	Color string `json:"color" binding:"required"` // 背景颜色
}

type fromGetEvents struct {
	Start string `json:"start" binding:"required"` // 开始日期
	End   string `json:"end" binding:"required"`   // 结束日期
}

var (
	userGroup      TabUserGroups
	scheduleAdmins []uint
)

// 更新管理员成员缓存
func ScheduleUpdateAdminsCash() {
	//先清空切片
	scheduleAdmins = nil

	//获取管理员用户组id
	//id 1是系统管理员 直接appen
	scheduleAdmins = append(scheduleAdmins, 1)
	//读取所有绑定了这个用户组的用户id
	var usergroupbind []TabUserGroupBinds
	usergroupbindfind := TabUserGroupBinds{
		GroupID: userGroup.ID,
	}
	models.DB.Where(&usergroupbindfind).Find(&usergroupbind)
	for _, item := range usergroupbind {
		if !slices.Contains(scheduleAdmins, item.UserID) {
			scheduleAdmins = append(scheduleAdmins, item.UserID)
		}
	}

}

func ApiScheduleInit() {
	//先初始化数据表
	// models.DB.AutoMigrate(&TabSchedule{})
	// models.DB.AutoMigrate(&TabScheduleLog{})

	// //先检查用户组有没有这个key
	// userGroup.Name = "schedule_admin"
	// if models.DB.Where(&userGroup).First(&userGroup).Error == nil {
	// 	ScheduleUpdateAdminsCash()
	// } else {
	// 	userGroup.Type = "usergroup"
	// 	models.DB.Create(&userGroup)
	// }
}

func ApiSchedule(r *gin.RouterGroup) {

	r.Use(func(ctx *gin.Context) { //此模块已停用，拦截所有请求
		ReturnJson(ctx, "App off", nil)
		ctx.Abort()

	})

	r.POST("/getevents", func(ctx *gin.Context) {
		data, cookie := SeparateData(ctx)
		user, er := AuthenticationAuthorityFromCookie(cookie)

		var from fromGetEvents
		if err := mapstructure.Decode(data, &from); err == nil {
			//fmt.Println(from)
			//从数据库获取相关数据
			var list []TabSchedule
			models.DB.Where("start_date <= ? AND end_date >= ?", from.End, from.Start).Where("deleted_at IS NULL").Find(&list)
			var relist []map[string]interface{}
			for _, item := range list {
				data, _ := json.Marshal(item)
				var temp map[string]interface{}
				json.Unmarshal(data, &temp)
				// 加自定义字段
				if er == nil {
					//已登录 进一步判断编辑权限
					temp["edit"] = false

					if slices.Contains(scheduleAdmins, user.ID) {
						temp["edit"] = true
					}
					if item.UserID == user.ID {
						temp["edit"] = true
					}

					// user_group_find := models.TabUserGroupBinds_{}
					// if models.DB.Where("user_id = ? AND group_id = ?", user.ID, userGroup.ID).First(&user_group_find).Error == nil { //是应用管理员
					// 	temp["edit"] = true
					// }
				} else {
					temp["edit"] = false
				}

				relist = append(relist, temp)

			}

			//ReturnJson(ctx, "ApiOK", list)
			ReturnJson(ctx, "apiOK", gin.H{"list": relist})

		} else {
			ReturnJson(ctx, "jsonErr", nil)
		}

	})

	r.POST("/deleevent", func(ctx *gin.Context) {
		isAuth, user, data := AuthenticationAuthority(ctx)
		if isAuth {
			var from fromAddEvent
			if err := mapstructure.Decode(data, &from); err == nil {
				//先从数据库拉取原始event数据
				oldEvent := TabSchedule{}
				if models.DB.Where("id = ?", from.ID).First(&oldEvent).Error == nil {
					//需要先判断修改权限
					var isCanEdit = false
					if slices.Contains(scheduleAdmins, user.ID) { //用户id是管理员
						isCanEdit = true
					}
					if oldEvent.UserID == user.ID { //event是用户创建的
						isCanEdit = true
					}
					if isCanEdit {
						tosql := TabSchedule{}
						tosql.DeletedAt.Scan(time.Now())
						//fmt.Println(tosql)
						findEvent := TabSchedule{
							ID: oldEvent.ID,
						}
						if models.DB.Where(&findEvent).Updates(&tosql).Error == nil {
							//应该修改完了  写日志
							//把最新数据再读出来
							models.DB.Where(&findEvent).First(&findEvent)
							newContent, _ := json.Marshal(findEvent) //转 JSON
							oldContent, _ := json.Marshal(oldEvent)  //转 JSON
							tosqllog := TabScheduleLog{
								UserID:     user.ID,
								ScheduleID: oldEvent.ID,
								ActionType: "delete",
								NewContent: string(newContent),
								OldContent: string(oldContent),
								IP:         ctx.ClientIP(),
							}
							models.DB.Create(&tosqllog)
							ReturnJson(ctx, "apiOK", nil)
						} else {
							ReturnJson(ctx, "apiErr", nil)
						}
					} else {
						ReturnJson(ctx, "schedule_permission_denied", nil)
					}
				} else {
					ReturnJson(ctx, "schedule_event_not_find", nil)
				}
			} else {
				ReturnJson(ctx, "jsonErr", nil)
			}
		} else {
			ReturnJson(ctx, "userCookieError", nil)
		}

	})

	r.POST("/editevent", func(ctx *gin.Context) {
		isAuth, user, data := AuthenticationAuthority(ctx)
		if isAuth {

			var from fromAddEvent
			if err := mapstructure.Decode(data, &from); err == nil {
				//先从数据库拉取原始event数据
				oldEvent := TabSchedule{}
				if models.DB.Where("id = ?", from.ID).First(&oldEvent).Error == nil {
					//需要先判断修改权限
					var isCanEdit = false
					if slices.Contains(scheduleAdmins, user.ID) { //用户id是管理员
						isCanEdit = true
					}
					if oldEvent.UserID == user.ID { //event是用户创建的
						isCanEdit = true
					}

					if isCanEdit {
						tosql := TabSchedule{
							// UserID:    user.ID,  //如果是管理员修改的话会覆盖掉创建者的id
							Title:     from.Title,
							StartDate: from.Start,
							EndDate:   from.End,
							BgColor:   from.Color,
						}
						//fmt.Println(tosql)

						findEvent := TabSchedule{
							ID: oldEvent.ID,
						}

						if models.DB.Where(&findEvent).Updates(&tosql).Error == nil {
							//应该修改完了  写日志
							//把最新数据再读出来
							models.DB.Where(&findEvent).First(&findEvent)
							newContent, _ := json.Marshal(findEvent) //转 JSON
							oldContent, _ := json.Marshal(oldEvent)  //转 JSON
							tosqllog := TabScheduleLog{
								UserID:     user.ID,
								ScheduleID: oldEvent.ID,
								ActionType: "update",
								NewContent: string(newContent),
								OldContent: string(oldContent),
								IP:         ctx.ClientIP(),
							}
							models.DB.Create(&tosqllog)
							ReturnJson(ctx, "apiOK", nil)

						} else {
							ReturnJson(ctx, "apiErr", nil)
						}

					} else {
						ReturnJson(ctx, "schedule_permission_denied", nil)
					}

				} else {
					ReturnJson(ctx, "schedule_event_not_find", nil)
				}

			} else {
				ReturnJson(ctx, "jsonErr", nil)
			}
		} else {
			ReturnJson(ctx, "userCookieError", nil)
		}
	})
	r.POST("/addevent", func(ctx *gin.Context) {
		isAuth, user, data := AuthenticationAuthority(ctx)
		if isAuth {

			var from fromAddEvent
			if err := mapstructure.Decode(data, &from); err == nil {

				tosql := TabSchedule{
					UserID:    user.ID,
					Title:     from.Title,
					StartDate: from.Start,
					EndDate:   from.End,
					BgColor:   from.Color,
				}
				if models.DB.Create(&tosql).Error == nil {
					//记录日志
					newContent, _ := json.Marshal(tosql) // 👈 转 JSON
					tosqllog := TabScheduleLog{
						UserID:     user.ID,
						ScheduleID: tosql.ID,
						ActionType: "create",
						NewContent: string(newContent), // 👈 直接赋值
						OldContent: "",
						IP:         ctx.ClientIP(),
					}
					models.DB.Create(&tosqllog)
					ReturnJson(ctx, "apiOK", nil)
				} else {
					ReturnJson(ctx, "apiErr", nil)
				}

			} else {
				ReturnJson(ctx, "jsonErr", nil)
			}
		} else {
			ReturnJson(ctx, "userCookieError", nil)
		}

	})

}
