package admin

import (
	"net/http"
	"strconv"

	"metazone.cc/metalab/internal/common"
	"metazone.cc/metalab/internal/model"

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

// AuditController 审核管理控制器
type AuditController struct {
	auditService auditUseCase
	userRepo     auditStatusProvider
}

// NewAuditController 构造函数
func NewAuditController(auditService auditUseCase, userRepo auditStatusProvider) *AuditController {
	return &AuditController{auditService: auditService, userRepo: userRepo}
}

// AuditPage 审核管理页面
func (ac *AuditController) AuditPage(c *gin.Context) {
	c.HTML(http.StatusOK, "admin/audit/index.html", common.BuildAdminPageData(c, gin.H{
		"Title":       "审核管理",
		"ExtraCSS":    "/admin/static/css/audit.css",
		"ExtraJS":     "/admin/static/js/audit.js",
		"AuditTypes":  model.AuditTypeNames,
		"AuditStatus": model.AuditStatusNames,
	}))
}

// ListAudits 审核列表 API（分页 + 类型筛选）
func (ac *AuditController) ListAudits(c *gin.Context) {
	page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
	pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))
	auditType := c.Query("type")
	status := c.Query("status")

	// 默认查 pending
	if status == "" {
		status = model.AuditStatusPending
	}

	result, err := ac.auditService.List(auditType, status, page, pageSize)
	if err != nil {
		common.Error(c, http.StatusInternalServerError, "查询失败")
		return
	}

	// 为每个审核记录附加提交者的用户名
	type auditItem struct {
		model.AuditSubmission
		SubmitterUsername string `json:"submitter_username"`
	}

	items := make([]auditItem, 0, len(result.Items))
	for _, a := range result.Items {
		item := auditItem{AuditSubmission: a}
		if user, err := ac.userRepo.FindByID(a.UserID); err == nil {
			item.SubmitterUsername = user.Username
		}
		items = append(items, item)
	}

	common.Ok(c, gin.H{
		"items": items,
		"total": result.Total,
		"page":  result.Page,
	})
}

// Approve 通过审核
func (ac *AuditController) Approve(c *gin.Context) {
	submissionID, err := parseIDParam(c.Param("id"))
	if err != nil {
		common.Error(c, http.StatusBadRequest, "无效的审核 ID")
		return
	}

	reviewerID := c.GetUint("uid")
	if err := ac.auditService.Approve(reviewerID, submissionID); err != nil {
		handleAuditError(c, err)
		return
	}

	common.OkMessage(c, "审核通过")
}

// Reject 拒绝审核
func (ac *AuditController) Reject(c *gin.Context) {
	submissionID, err := parseIDParam(c.Param("id"))
	if err != nil {
		common.Error(c, http.StatusBadRequest, "无效的审核 ID")
		return
	}

	var req struct {
		Reason string `json:"reason"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		common.Error(c, http.StatusBadRequest, "参数错误")
		return
	}

	reviewerID := c.GetUint("uid")
	if err := ac.auditService.Reject(reviewerID, submissionID, req.Reason); err != nil {
		handleAuditError(c, err)
		return
	}

	common.OkMessage(c, "已拒绝")
}

// parseIDParam 从 URL 路径参数解析 uint ID
func parseIDParam(s string) (uint, error) {
	id, err := strconv.ParseUint(s, 10, 64)
	if err != nil {
		return 0, err
	}
	return uint(id), nil
}

// handleAuditError 统一处理审核接口的 service 层错误
func handleAuditError(c *gin.Context, err error) {
	switch err {
	case common.ErrAuditNotFound:
		common.Error(c, http.StatusNotFound, "审核记录不存在")
	case common.ErrAuditNotPending:
		common.Error(c, http.StatusBadRequest, "该审核记录已处理")
	case common.ErrUserNotFound:
		common.Error(c, http.StatusNotFound, "用户不存在")
	case common.ErrUsernameTaken:
		common.Error(c, http.StatusConflict, "该用户名已被其他用户占用，审批失败")
	default:
		common.Error(c, http.StatusInternalServerError, "操作失败")
	}
}
