package routers

import (
	"ops/models"
	"sort"
	"time"

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

// InitSysAdminRouter 初始化系统管理员路由
func ApiSysAdmin(r *gin.RouterGroup) {
	// 获取系统管理员列表（仅系统管理员可访问）
	r.POST("/sysadmins", func(ctx *gin.Context) {
		isAuth, user, _ := AuthenticationAuthority(ctx)
		if !isAuth {
			ReturnJson(ctx, "userNoLogin", nil)
			return
		}

		// 检查是否为系统管理员
		if !SysAdminCheck(user.ID) {
			ReturnJson(ctx, "permission_denied", nil)
			return
		}

		var redata map[string]interface{} = make(map[string]interface{})
		redata["sysAdmins"] = sysAdmins
		ReturnJson(ctx, "apiOK", redata)
	})

	// 获取用户列表（仅系统管理员可访问）
	r.POST("/users", func(ctx *gin.Context) {
		isAuth, user, data := AuthenticationAuthority(ctx)
		if !isAuth {
			ReturnJson(ctx, "userNoLogin", nil)
			return
		}

		// 检查是否为系统管理员
		if !SysAdminCheck(user.ID) {
			ReturnJson(ctx, "permission_denied", nil)
			return
		}

		// 解析分页和搜索参数
		var params struct {
			Page     int    `json:"page"`
			PageSize int    `json:"page_size"`
			Search   string `json:"search"`
		}
		if err := mapstructure.Decode(data, &params); err != nil {
			params.Page = 1
			params.PageSize = 20
		}
		if params.Page < 1 {
			params.Page = 1
		}
		if params.PageSize < 1 || params.PageSize > 100 {
			params.PageSize = 20
		}

		offset := (params.Page - 1) * params.PageSize

		// 构建查询
		var users []TabUser
		var total int64
		query := models.DB.Model(&TabUser{})

		// 搜索条件
		if params.Search != "" {
			search := "%" + params.Search + "%"
			query = query.Where("name LIKE ? OR email LIKE ?", search, search)
		}

		// 获取总数
		query.Count(&total)

		// 获取分页数据
		query.Order("id DESC").Offset(offset).Limit(params.PageSize).Find(&users)

		// 获取用户详细信息（包括头像）
		var userList []map[string]interface{}
		for _, u := range users {
			userInfo := GetUserInfoFromUserID(u.ID)
			userData := map[string]interface{}{
				"id":         u.ID,
				"name":       u.Name,
				"email":      u.Email,
				"type":       u.Type,
				"date":       u.Date,
				"username":   "",
				"avatarPath": "",
			}
			if userInfo != nil {
				userData["username"] = userInfo.Username
				userData["avatarPath"] = userInfo.AvatarPath
			}
			userList = append(userList, userData)
		}

		var redata map[string]interface{} = make(map[string]interface{})
		redata["users"] = userList
		redata["total"] = total
		redata["page"] = params.Page
		redata["page_size"] = params.PageSize

		ReturnJson(ctx, "apiOK", redata)
	})

	// 获取所有用户组列表（仅系统管理员可访问）
	r.POST("/groups", func(ctx *gin.Context) {
		isAuth, _, _ := AuthenticationAuthority(ctx)
		if !isAuth {
			ReturnJson(ctx, "userNoLogin", nil)
			return
		}

		var groups []TabUserGroups
		models.DB.Order("id ASC").Find(&groups)

		var list []map[string]interface{}
		for _, g := range groups {
			// 统计成员数量
			var memberCount int64
			models.DB.Model(&TabUserGroupBinds{}).Where("group_id = ?", g.ID).Count(&memberCount)

			// 获取部分成员（最多5个）
			var binds []TabUserGroupBinds
			models.DB.Where("group_id = ?", g.ID).Limit(5).Find(&binds)
			var memberIDs []uint
			for _, b := range binds {
				memberIDs = append(memberIDs, b.UserID)
			}

			list = append(list, map[string]interface{}{
				"id":          g.ID,
				"name":        g.Name,
				"email":       g.Email,
				"type":        g.Type,
				"date":        g.Date,
				"memberCount": memberCount,
				"memberIDs":   memberIDs,
			})
		}

		var redata map[string]interface{} = make(map[string]interface{})
		redata["groups"] = list
		ReturnJson(ctx, "apiOK", redata)
	})

	// 获取用户组成员列表（仅系统管理员可访问）
	r.POST("/group_members", func(ctx *gin.Context) {
		isAuth, authUser, data := AuthenticationAuthority(ctx)
		if !isAuth {
			ReturnJson(ctx, "userNoLogin", nil)
			return
		}

		// 检查是否为系统管理员
		if !SysAdminCheck(authUser.ID) {
			ReturnJson(ctx, "permission_denied", nil)
			return
		}

		var params struct {
			GroupID  float64 `json:"group_id" mapstructure:"group_id"`
			Page     float64 `json:"page" mapstructure:"page"`
			PageSize float64 `json:"page_size" mapstructure:"page_size"`
		}
		if err := mapstructure.Decode(data, &params); err != nil {
			params.Page = 1
			params.PageSize = 20
		}
		if params.Page < 1 {
			params.Page = 1
		}
		if params.PageSize < 1 || params.PageSize > 100 {
			params.PageSize = 20
		}

		// 验证用户组是否存在
		var group TabUserGroups
		if models.DB.First(&group, params.GroupID).Error != nil {
			ReturnJson(ctx, "groupNotFound", nil)
			return
		}

		groupID := uint(params.GroupID)
		page := int(params.Page)
		pageSize := int(params.PageSize)
		if page < 1 {
			page = 1
		}
		if pageSize < 1 || pageSize > 100 {
			pageSize = 20
		}
		offset := (page - 1) * pageSize

		var binds []TabUserGroupBinds
		var total int64
		models.DB.Model(&TabUserGroupBinds{}).Where("group_id = ?", groupID).Count(&total)
		models.DB.Where("group_id = ?", groupID).Order("id ASC").Offset(offset).Limit(pageSize).Find(&binds)

		// 获取成员用户信息
		var members []map[string]interface{}
		for _, b := range binds {
			var u TabUser
			if models.DB.First(&u, b.UserID).Error == nil {
				userInfo := GetUserInfoFromUserID(u.ID)
				member := map[string]interface{}{
					"id":         u.ID,
					"name":       u.Name,
					"email":      u.Email,
					"type":       u.Type,
					"avatarPath": "",
					"username":   "",
				}
				if userInfo != nil {
					member["username"] = userInfo.Username
					member["avatarPath"] = userInfo.AvatarPath
				}
				members = append(members, member)
			}
		}

		var redata map[string]interface{} = make(map[string]interface{})
		redata["group_id"] = groupID
		redata["group_name"] = group.Name
		redata["members"] = members
		redata["total"] = total
		redata["page"] = page
		redata["page_size"] = pageSize
		ReturnJson(ctx, "apiOK", redata)
	})

	// 获取用户详细信息（仅系统管理员可访问）
	r.POST("/user_detail", func(ctx *gin.Context) {
		isAuth, authUser, data := AuthenticationAuthority(ctx)
		if !isAuth {
			ReturnJson(ctx, "userNoLogin", nil)
			return
		}

		// 检查是否为系统管理员
		if !SysAdminCheck(authUser.ID) {
			ReturnJson(ctx, "permission_denied", nil)
			return
		}

		var params struct {
			UserID uint `json:"user_id"`
		}
		if err := mapstructure.Decode(data, &params); err != nil || params.UserID == 0 {
			ReturnJson(ctx, "parameErr", nil)
			return
		}

		// 获取用户基本信息
		var user TabUser
		if models.DB.First(&user, params.UserID).Error != nil {
			ReturnJson(ctx, "userNotFound", nil)
			return
		}

		// 获取用户扩展信息
		userInfo := GetUserInfoFromUserID(user.ID)

		// 构建返回数据
		redata := map[string]interface{}{
			"user": map[string]interface{}{
				"id":    user.ID,
				"name":  user.Name,
				"email": user.Email,
				"type":  user.Type,
				"date":  user.Date,
			},
			"userinfo": userInfo,
		}

		ReturnJson(ctx, "apiOK", redata)
	})

	// 重置用户密码（仅系统管理员可访问）
	r.POST("/reset_user_password", func(ctx *gin.Context) {
		isAuth, adminUser, data := AuthenticationAuthority(ctx)
		if !isAuth {
			ReturnJson(ctx, "userNoLogin", nil)
			return
		}

		// 检查是否为系统管理员
		if !SysAdminCheck(adminUser.ID) {
			ReturnJson(ctx, "permission_denied", nil)
			return
		}

		var params struct {
			UserID   float64 `json:"user_id" mapstructure:"user_id"`
			Password string  `json:"password" mapstructure:"password"`
		}
		if err := mapstructure.Decode(data, &params); err != nil || params.UserID == 0 || params.Password == "" {
			ReturnJson(ctx, "parameErr", map[string]interface{}{"decode_err": err != nil, "user_id": params.UserID, "pass_empty": params.Password == ""})
			return
		}

		// 查找目标用户
		var targetUser TabUser
		if models.DB.First(&targetUser, uint(params.UserID)).Error != nil {
			ReturnJson(ctx, "userNotFound", nil)
			return
		}

		// 生成新盐值并哈希密码
		newSalt := models.RandStr32()
		tempUser := TabUser{
			Pass: params.Password,
			Salt: newSalt,
		}
		HashUserPass(&tempUser)

		// 更新密码和盐值
		updates := TabUser{
			Pass: tempUser.Pass,
			Salt: newSalt,
		}
		if err := models.DB.Model(&targetUser).Updates(&updates).Error; err != nil {
			ReturnJson(ctx, "dbErr", nil)
			return
		}

		// 注销该用户的所有 cookie（强制重新登录）
		if err := models.DB.Where("user_id = ?", targetUser.ID).Delete(&TabUserCookie{}).Error; err != nil {
			// 删除 cookie 失败不影响密码修改结果，仅记录
			//fmt.Println("删除用户 cookie 失败:", err)
		}

		ReturnJson(ctx, "apiOK", nil)
	})

	// 添加用户组成员（仅系统管理员可访问）
	r.POST("/add_group_member", func(ctx *gin.Context) {
		isAuth, adminUser, data := AuthenticationAuthority(ctx)
		if !isAuth {
			ReturnJson(ctx, "userNoLogin", nil)
			return
		}

		// 检查是否为系统管理员
		if !SysAdminCheck(adminUser.ID) {
			ReturnJson(ctx, "permission_denied", nil)
			return
		}

		var params struct {
			GroupID float64 `json:"group_id" mapstructure:"group_id"`
			UserID  float64 `json:"user_id" mapstructure:"user_id"`
		}
		if err := mapstructure.Decode(data, &params); err != nil || params.GroupID == 0 || params.UserID == 0 {
			ReturnJson(ctx, "parameErr", nil)
			return
		}

		// 验证用户组是否存在
		var group TabUserGroups
		if models.DB.First(&group, uint(params.GroupID)).Error != nil {
			ReturnJson(ctx, "groupNotFound", nil)
			return
		}

		// 验证用户是否存在
		var user TabUser
		if models.DB.First(&user, uint(params.UserID)).Error != nil {
			ReturnJson(ctx, "userNotFound", nil)
			return
		}

		// 检查绑定是否已存在
		var existingBind TabUserGroupBinds
		if models.DB.Where("group_id = ? AND user_id = ?", uint(params.GroupID), uint(params.UserID)).First(&existingBind).Error == nil {
			ReturnJson(ctx, "userAlreadyInGroup", nil)
			return
		}

		// 创建绑定
		newBind := TabUserGroupBinds{
			UserID:  uint(params.UserID),
			GroupID: uint(params.GroupID),
		}
		if err := models.DB.Create(&newBind).Error; err != nil {
			ReturnJson(ctx, "dbErr", nil)
			return
		}

		// 根据组名刷新对应的权限缓存
		switch group.Name {
		case "admins":
			updateSysAdminsCash()
		case "schedule_admin":
			ScheduleUpdateAdminsCash()
		case "purchase_admin":
			PurchaseUpdateAdminsCash()
		case "work_order_admin":
			WorkOrderUpdateAdminsCash()
		case "warehouse_admin":
			WarehouseUpdateAdminsCash()
		case "customer_admin":
			CustomerUpdateAdminsCash()
		case "calendar_admin":
			CalendarUpdateAdminsCash()
		}

		ReturnJson(ctx, "apiOK", nil)
	})

	// 移除用户组成员（仅系统管理员可访问）
	r.POST("/remove_group_member", func(ctx *gin.Context) {
		isAuth, adminUser, data := AuthenticationAuthority(ctx)
		if !isAuth {
			ReturnJson(ctx, "userNoLogin", nil)
			return
		}

		// 检查是否为系统管理员
		if !SysAdminCheck(adminUser.ID) {
			ReturnJson(ctx, "permission_denied", nil)
			return
		}

		var params struct {
			GroupID float64 `json:"group_id" mapstructure:"group_id"`
			UserID  float64 `json:"user_id" mapstructure:"user_id"`
		}
		if err := mapstructure.Decode(data, &params); err != nil || params.GroupID == 0 || params.UserID == 0 {
			ReturnJson(ctx, "parameErr", nil)
			return
		}

		// 验证用户组是否存在
		var group TabUserGroups
		if models.DB.First(&group, uint(params.GroupID)).Error != nil {
			ReturnJson(ctx, "groupNotFound", nil)
			return
		}

		// 删除绑定
		if err := models.DB.Where("group_id = ? AND user_id = ?", uint(params.GroupID), uint(params.UserID)).Delete(&TabUserGroupBinds{}).Error; err != nil {
			ReturnJson(ctx, "dbErr", nil)
			return
		}

		// 根据组名刷新对应的权限缓存
		switch group.Name {
		case "admins":
			updateSysAdminsCash()
		case "schedule_admin":
			ScheduleUpdateAdminsCash()
		case "purchase_admin":
			PurchaseUpdateAdminsCash()
		case "work_order_admin":
			WorkOrderUpdateAdminsCash()
		case "warehouse_admin":
			WarehouseUpdateAdminsCash()
		case "customer_admin":
			CustomerUpdateAdminsCash()
		case "calendar_admin":
			CalendarUpdateAdminsCash()
		}

		ReturnJson(ctx, "apiOK", nil)
	})

	// 获取操作日志（仅系统管理员可访问）
	r.POST("/operation_logs", func(ctx *gin.Context) {
		isAuth, user, data := AuthenticationAuthority(ctx)
		if !isAuth {
			ReturnJson(ctx, "userNoLogin", nil)
			return
		}

		// 检查是否为系统管理员
		if !SysAdminCheck(user.ID) {
			ReturnJson(ctx, "permission_denied", nil)
			return
		}

		// 解析参数
		var params struct {
			Page     int    `json:"page"`
			PageSize int    `json:"page_size"`
			Module   string `json:"module"` // 模块: all/customer/purchase/schedule/warehouse/work_order
		}
		if err := mapstructure.Decode(data, &params); err != nil {
			params.Page = 1
			params.PageSize = 20
			params.Module = "all"
		}
		if params.Page < 1 {
			params.Page = 1
		}
		if params.PageSize < 1 || params.PageSize > 100 {
			params.PageSize = 20
		}

		type LogEntry struct {
			ID         uint       `json:"id"`
			Module     string     `json:"module"`      // 模块名称
			EntityID   uint       `json:"entity_id"`   // 关联实体ID
			UserID     uint       `json:"user_id"`     // 操作人ID
			ActionType string     `json:"action_type"` // 操作类型
			IP         string     `json:"ip"`
			Remark     string     `json:"remark"`
			CreatedAt  *time.Time `json:"created_at"`
		}

		var allLogs []LogEntry

		// 根据模块筛选查询
		if params.Module == "all" || params.Module == "customer" {
			var logs []TabCustomerLog
			query := models.DB.Model(&TabCustomerLog{})
			if params.Module == "customer" {
				query.Order("created_at DESC").Find(&logs)
			} else {
				query.Order("created_at DESC").Limit(1000).Find(&logs)
			}
			for _, log := range logs {
				allLogs = append(allLogs, LogEntry{
					ID:         log.ID,
					Module:     "customer",
					EntityID:   log.CustomerID,
					UserID:     log.UserID,
					ActionType: log.ActionType,
					IP:         log.IP,
					Remark:     log.Remark,
					CreatedAt:  log.CreatedAt,
				})
			}
		}

		if params.Module == "all" || params.Module == "purchase" {
			var logs []TabPurchaseLog
			query := models.DB.Model(&TabPurchaseLog{})
			if params.Module == "purchase" {
				query.Order("created_at DESC").Find(&logs)
			} else {
				query.Order("created_at DESC").Limit(1000).Find(&logs)
			}
			for _, log := range logs {
				allLogs = append(allLogs, LogEntry{
					ID:         log.ID,
					Module:     "purchase",
					EntityID:   log.OrderID,
					UserID:     log.UserID,
					ActionType: log.ActionType,
					IP:         log.IP,
					Remark:     log.Remark,
					CreatedAt:  log.CreatedAt,
				})
			}
		}

		if params.Module == "all" || params.Module == "schedule" {
			var logs []TabScheduleLog
			query := models.DB.Model(&TabScheduleLog{})
			if params.Module == "schedule" {
				query.Order("created_at DESC").Find(&logs)
			} else {
				query.Order("created_at DESC").Limit(1000).Find(&logs)
			}
			for _, log := range logs {
				allLogs = append(allLogs, LogEntry{
					ID:         log.ID,
					Module:     "schedule",
					EntityID:   log.ScheduleID,
					UserID:     log.UserID,
					ActionType: log.ActionType,
					IP:         log.IP,
					Remark:     log.Remark,
					CreatedAt:  log.CreatedAt,
				})
			}
		}

		if params.Module == "all" || params.Module == "calendar" {
			var logs []TabCalendarLog
			query := models.DB.Model(&TabCalendarLog{})
			if params.Module == "calendar" {
				query.Order("created_at DESC").Find(&logs)
			} else {
				query.Order("created_at DESC").Limit(1000).Find(&logs)
			}
			for _, log := range logs {
				allLogs = append(allLogs, LogEntry{
					ID:         log.ID,
					Module:     "calendar",
					EntityID:   log.CalendarID,
					UserID:     log.UserID,
					ActionType: log.ActionType,
					IP:         log.IP,
					Remark:     log.Remark,
					CreatedAt:  log.CreatedAt,
				})
			}
		}

		if params.Module == "all" || params.Module == "warehouse" {
			var logs []TabWarehouseLog
			query := models.DB.Model(&TabWarehouseLog{})
			if params.Module == "warehouse" {
				query.Order("created_at DESC").Find(&logs)
			} else {
				query.Order("created_at DESC").Limit(1000).Find(&logs)
			}
			for _, log := range logs {
				allLogs = append(allLogs, LogEntry{
					ID:         log.ID,
					Module:     "warehouse",
					EntityID:   log.EntityID,
					UserID:     log.UserID,
					ActionType: log.ActionType,
					IP:         log.IP,
					Remark:     log.Remark,
					CreatedAt:  &log.CreatedAt,
				})
			}
		}

		if params.Module == "all" || params.Module == "work_order" {
			var logs []TabWorkOrderLog
			query := models.DB.Model(&TabWorkOrderLog{})
			if params.Module == "work_order" {
				query.Order("created_at DESC").Find(&logs)
			} else {
				query.Order("created_at DESC").Limit(1000).Find(&logs)
			}
			for _, log := range logs {
				allLogs = append(allLogs, LogEntry{
					ID:         log.ID,
					Module:     "work_order",
					EntityID:   log.WorkOrderID,
					UserID:     log.UserID,
					ActionType: log.ActionType,
					IP:         log.IP,
					Remark:     log.Remark,
					CreatedAt:  log.CreatedAt,
				})
			}
		}

		// 按时间倒序排序
		sort.Slice(allLogs, func(i, j int) bool {
			if allLogs[i].CreatedAt == nil || allLogs[j].CreatedAt == nil {
				return allLogs[i].ID > allLogs[j].ID
			}
			return allLogs[i].CreatedAt.After(*allLogs[j].CreatedAt)
		})

		total := len(allLogs)
		offset := (params.Page - 1) * params.PageSize
		end := offset + params.PageSize
		if offset > total {
			offset = total
		}
		if end > total {
			end = total
		}

		var pagedLogs []LogEntry
		if offset < total {
			pagedLogs = allLogs[offset:end]
		}

		ReturnJson(ctx, "apiOK", gin.H{
			"logs":      pagedLogs,
			"total":     total,
			"page":      params.Page,
			"page_size": params.PageSize,
		})
	})

	// 获取登录失败日志（仅系统管理员可访问）
	r.POST("/login_fail_logs", func(ctx *gin.Context) {
		isAuth, authUser, data := AuthenticationAuthority(ctx)
		if !isAuth {
			ReturnJson(ctx, "userNoLogin", nil)
			return
		}

		// 检查是否为系统管理员
		if !SysAdminCheck(authUser.ID) {
			ReturnJson(ctx, "permission_denied", nil)
			return
		}

		// 解析分页和搜索参数
		var params struct {
			Page     int    `json:"page"`
			PageSize int    `json:"page_size"`
			Search   string `json:"search"`
		}
		if err := mapstructure.Decode(data, &params); err != nil {
			params.Page = 1
			params.PageSize = 20
		}
		if params.Page < 1 {
			params.Page = 1
		}
		if params.PageSize < 1 || params.PageSize > 100 {
			params.PageSize = 20
		}

		offset := (params.Page - 1) * params.PageSize

		// 构建查询
		var logs []TabUserLoginFailLog
		var total int64
		query := models.DB.Model(&TabUserLoginFailLog{})

		// 搜索条件（用户名或IP）
		if params.Search != "" {
			search := "%" + params.Search + "%"
			query = query.Where("username LIKE ? OR ip LIKE ?", search, search)
		}

		// 获取总数
		query.Count(&total)

		// 获取分页数据，按时间倒序
		query.Order("updated_at DESC").Offset(offset).Limit(params.PageSize).Find(&logs)

		// 构建返回数据
		var logList []map[string]interface{}
		for _, log := range logs {
			logData := map[string]interface{}{
				"id":         log.ID,
				"username":   log.Username,
				"user_id":    log.UserID,
				"ip":         log.IP,
				"user_agent": log.UserAgent,
				"reason":     log.Reason,
				"count":      log.Count,
				"created_at": log.CreatedAt,
				"updated_at": log.UpdatedAt,
			}
			logList = append(logList, logData)
		}

		var redata map[string]interface{} = make(map[string]interface{})
		redata["logs"] = logList
		redata["total"] = total
		redata["page"] = params.Page
		redata["page_size"] = params.PageSize

		ReturnJson(ctx, "apiOK", redata)
	})
}

// SysAdminCheck 检查当前用户是否为系统管理员
func SysAdminCheck(userID uint) bool {
	for _, adminID := range sysAdmins {
		if adminID == userID {
			return true
		}
	}
	return false
}

// RefreshSysAdmins 刷新系统管理员缓存（可从数据库重新加载）
func RefreshSysAdmins() {
	updateSysAdminsCash()
}
