// 员工认证模块：提交认证申请、查询申请状态、撤回申请
package certification

import (
	"time"

	"com.sclktx/m/v2/internal/common/model"
	"com.sclktx/m/v2/internal/common/response"
	"com.sclktx/m/v2/internal/common/utils"

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

// Handler 角色认证处理器
type Handler struct {
	db *gorm.DB
}

// NewHandler 创建角色认证处理器
func NewHandler(db *gorm.DB) *Handler {
	return &Handler{db: db}
}

// SubmitCertificationReq 提交认证申请请求
type SubmitCertificationReq struct {
	RealName     string   `json:"real_name" binding:"required"`
	Phone        string   `json:"phone" binding:"required"`
	Role         string   `json:"role" binding:"required"`
	Snapshot     []string `json:"snapshot" binding:"required"`
	DepartmentID *uint    `json:"department_id"`
	Position     string   `json:"position"`
}

// SubmitCertification 提交角色认证申请
// @Summary      提交角色认证申请
// @Description  提交员工角色认证申请，需上传钉钉截图
// @Tags         员工认证
// @Accept       json
// @Produce      json
// @Security     BearerAuth
// @Param        body body SubmitCertificationReq true "认证申请请求"
// @Success      200  {object}  response.Response  "success"
// @Router       /api/v1/certification/submit [post]
func (h *Handler) SubmitCertification(c *gin.Context) {
	var req SubmitCertificationReq
	if err := c.ShouldBindJSON(&req); err != nil {
		response.BadRequest(c, "参数错误: "+err.Error())
		return
	}

	userID := utils.GetUserID(c)

	// 检查是否已有待审核或已通过的申请
	var existing model.EmployeeCertification
	if err := h.db.Where("user_id = ? AND status IN (0, 1)", userID).First(&existing).Error; err == nil {
		if existing.Status == 1 {
			response.BadRequest(c, "您已通过认证，无需重复申请")
			return
		}
		response.BadRequest(c, "您已提交申请，请等待审核")
		return
	}

	cert := model.EmployeeCertification{
		UserID:       userID,
		RealName:     req.RealName,
		Phone:        req.Phone,
		Role:         req.Role,
		Snapshot:     req.Snapshot,
		Position:     req.Position,
		DepartmentID: req.DepartmentID,
		Status:       0,
	}

	if err := h.db.Create(&cert).Error; err != nil {
		response.InternalError(c, "提交失败: "+err.Error())
		return
	}

	response.SuccessWithMessage(c, "提交成功，请等待管理员审核", cert)
}

// GetMyCertification 获取我的认证申请
// @Summary      获取我的认证申请
// @Description  获取当前用户的角色认证申请状态
// @Tags         员工认证
// @Accept       json
// @Produce      json
// @Security     BearerAuth
// @Success      200  {object}  response.Response  "success"
// @Router       /api/v1/certification/my [get]
func (h *Handler) GetMyCertification(c *gin.Context) {
	userID := utils.GetUserID(c)

	var cert model.EmployeeCertification
	if err := h.db.Preload("Department").Preload("Approver").Where("user_id = ?", userID).Order("created_at DESC").First(&cert).Error; err != nil {
		response.Success(c, nil)
		return
	}

	response.Success(c, cert)
}

// WithdrawCertification 撤回认证申请
// @Summary      撤回认证申请
// @Description  撤回已提交但尚未处理的认证申请
// @Tags         员工认证
// @Accept       json
// @Produce      json
// @Security     BearerAuth
// @Param        id path uint true "认证申请ID"
// @Success      200  {object}  response.Response  "success"
// @Router       /api/v1/certification/{id}/withdraw [put]
func (h *Handler) WithdrawCertification(c *gin.Context) {
	userID := utils.GetUserID(c)
	certID := c.Param("id")

	var cert model.EmployeeCertification
	if err := h.db.First(&cert, certID).Error; err != nil {
		response.NotFound(c, "申请不存在")
		return
	}

	if cert.UserID != userID {
		response.Forbidden(c, "无权操作")
		return
	}

	if cert.Status != 0 {
		response.BadRequest(c, "该申请已处理，无法撤回")
		return
	}

	if err := h.db.Delete(&cert).Error; err != nil {
		response.InternalError(c, "撤回失败")
		return
	}

	response.SuccessWithMessage(c, "已撤回", nil)
}

// AutoVerifyReq 自动认证请求
type AutoVerifyReq struct {
	RealName string `json:"real_name" binding:"required"`
	Phone    string `json:"phone" binding:"required"`
}

// AutoVerify 自动认证：姓名+手机号 → 匹配 pending_employees → 直接认证为员工
// @Summary      自动认证为员工
// @Description  输入姓名和手机号，系统自动匹配通讯录导入数据，匹配成功直接认证为员工
// @Tags         员工认证
// @Accept       json
// @Produce      json
// @Security     BearerAuth
// @Param        body body AutoVerifyReq true "认证请求"
// @Success      200  {object}  response.Response  "success"
// @Router       /api/v1/certification/auto-verify [post]
func (h *Handler) AutoVerify(c *gin.Context) {
	var req AutoVerifyReq
	if err := c.ShouldBindJSON(&req); err != nil {
		response.BadRequest(c, "请输入姓名和手机号")
		return
	}

	userID := utils.GetUserID(c)

	// 查当前用户角色
	var user model.User
	if err := h.db.First(&user, userID).Error; err != nil {
		response.InternalError(c, "用户不存在")
		return
	}
	if user.Role == "employee" {
		response.BadRequest(c, "您已经是认证员工，无需重复申请")
		return
	}

	// 查找 pending_employees
	var pending model.PendingEmployee
	if err := h.db.Where("phone = ?", req.Phone).First(&pending).Error; err != nil {
		response.BadRequest(c, "未找到您的认证信息，请联系管理员导入通讯录")
		return
	}

	// 检查是否已被其他用户匹配
	if pending.IsMatched {
		if pending.MatchedUserID != nil && *pending.MatchedUserID == userID {
			// 已匹配当前用户但角色尚未升级 → 修复
			if user.Role != "employee" {
				goto doMatch
			}
			response.BadRequest(c, "您已认证成为员工，如有问题请联系管理员")
		} else {
			response.BadRequest(c, "该手机号已被其他用户认证，如有问题请联系管理员")
		}
		return
	}

doMatch:
	// 执行认证
	now := time.Now()
	ud := model.UserDepartment{
		UserID:         userID,
		DepartmentID:   pending.DepartmentID,
		DepartmentName: pending.DepartmentName,
		Position:       pending.Position,
		EmployeeType:   pending.EmployeeType,
		EmployeeStatus: 1,
	}
	h.db.Where("user_id = ?", userID).Assign(ud).FirstOrCreate(&model.UserDepartment{UserID: userID})
	h.db.Model(&user).Update("role", "employee")
	h.db.Model(&pending).Updates(map[string]interface{}{
		"is_matched":      true,
		"matched_user_id": &userID,
		"matched_at":      &now,
	})

	// 如果用户还没有真实姓名，同步填入
	if user.RealName == "" {
		h.db.Model(&user).Update("real_name", req.RealName)
	}

	response.SuccessWithMessage(c, "认证成功", gin.H{
		"department_name": pending.DepartmentName,
		"position":        pending.Position,
	})
}

// RegisterRoutes 注册认证路由（需要 JWT 认证）
func (h *Handler) RegisterRoutes(r *gin.RouterGroup) {
	r.POST("/certification/submit", h.SubmitCertification)
	r.GET("/certification/my", h.GetMyCertification)
	r.PUT("/certification/:id/withdraw", h.WithdrawCertification)
	r.POST("/certification/auto-verify", h.AutoVerify)
}
