package admin

import (
	"net/http"
	"strconv"

	"bindbox-game/internal/code"
	"bindbox-game/internal/pkg/core"
	"bindbox-game/internal/pkg/validation"
	"bindbox-game/internal/repository/mysql/model"
)

// ========== 黑名单管理 ==========

type addBlacklistRequest struct {
	DouyinUserID string `json:"douyin_user_id" binding:"required"`
	Reason       string `json:"reason"`
}

type blacklistResponse struct {
	ID           int64  `json:"id"`
	DouyinUserID string `json:"douyin_user_id"`
	Reason       string `json:"reason"`
	OperatorID   int64  `json:"operator_id"`
	Status       int32  `json:"status"`
	CreatedAt    string `json:"created_at"`
}

type listBlacklistRequest struct {
	Page     int    `form:"page"`
	PageSize int    `form:"page_size"`
	Keyword  string `form:"keyword"`
}

type listBlacklistResponse struct {
	List     []blacklistResponse `json:"list"`
	Total    int64               `json:"total"`
	Page     int                 `json:"page"`
	PageSize int                 `json:"page_size"`
}

// ListBlacklist 获取黑名单列表
// @Summary 获取黑名单列表
// @Description 获取抖音用户黑名单列表，支持分页和关键词搜索
// @Tags 管理端.黑名单
// @Accept json
// @Produce json
// @Param page query int false "页码" default(1)
// @Param page_size query int false "每页数量" default(20)
// @Param keyword query string false "搜索关键词(抖音ID)"
// @Success 200 {object} listBlacklistResponse
// @Failure 400 {object} code.Failure
// @Router /api/admin/blacklist [get]
// @Security LoginVerifyToken
func (h *handler) ListBlacklist() core.HandlerFunc {
	return func(ctx core.Context) {
		req := new(listBlacklistRequest)
		if err := ctx.ShouldBindQuery(req); err != nil {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err)))
			return
		}

		if req.Page <= 0 {
			req.Page = 1
		}
		if req.PageSize <= 0 {
			req.PageSize = 20
		}

		db := h.repo.GetDbR().WithContext(ctx.RequestContext()).
			Table("douyin_blacklist").
			Where("status = 1")

		if req.Keyword != "" {
			db = db.Where("douyin_user_id LIKE ?", "%"+req.Keyword+"%")
		}

		var total int64
		if err := db.Count(&total).Error; err != nil {
			ctx.AbortWithError(core.Error(http.StatusInternalServerError, code.ServerError, err.Error()))
			return
		}

		var list []model.DouyinBlacklist
		if err := db.Order("id DESC").
			Offset((req.Page - 1) * req.PageSize).
			Limit(req.PageSize).
			Find(&list).Error; err != nil {
			ctx.AbortWithError(core.Error(http.StatusInternalServerError, code.ServerError, err.Error()))
			return
		}

		rsp := &listBlacklistResponse{
			List:     make([]blacklistResponse, len(list)),
			Total:    total,
			Page:     req.Page,
			PageSize: req.PageSize,
		}

		for i, item := range list {
			rsp.List[i] = blacklistResponse{
				ID:           item.ID,
				DouyinUserID: item.DouyinUserID,
				Reason:       item.Reason,
				OperatorID:   item.OperatorID,
				Status:       item.Status,
				CreatedAt:    item.CreatedAt.Format("2006-01-02 15:04:05"),
			}
		}

		ctx.Payload(rsp)
	}
}

// AddBlacklist 添加黑名单
// @Summary 添加黑名单
// @Description 将抖音用户添加到黑名单
// @Tags 管理端.黑名单
// @Accept json
// @Produce json
// @Param body body addBlacklistRequest true "请求参数"
// @Success 200 {object} blacklistResponse
// @Failure 400 {object} code.Failure
// @Router /api/admin/blacklist [post]
// @Security LoginVerifyToken
func (h *handler) AddBlacklist() core.HandlerFunc {
	return func(ctx core.Context) {
		req := new(addBlacklistRequest)
		if err := ctx.ShouldBindJSON(req); err != nil {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err)))
			return
		}

		// 检查是否已在黑名单
		var existCount int64
		h.repo.GetDbR().WithContext(ctx.RequestContext()).
			Table("douyin_blacklist").
			Where("douyin_user_id = ? AND status = 1", req.DouyinUserID).
			Count(&existCount)

		if existCount > 0 {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "该用户已在黑名单中"))
			return
		}

		operatorID := int64(0)
		if ctx.SessionUserInfo().Id > 0 {
			operatorID = int64(ctx.SessionUserInfo().Id)
		}

		blacklist := &model.DouyinBlacklist{
			DouyinUserID: req.DouyinUserID,
			Reason:       req.Reason,
			OperatorID:   operatorID,
			Status:       1,
		}

		if err := h.repo.GetDbW().WithContext(ctx.RequestContext()).Create(blacklist).Error; err != nil {
			ctx.AbortWithError(core.Error(http.StatusInternalServerError, code.ServerError, err.Error()))
			return
		}

		ctx.Payload(&blacklistResponse{
			ID:           blacklist.ID,
			DouyinUserID: blacklist.DouyinUserID,
			Reason:       blacklist.Reason,
			OperatorID:   blacklist.OperatorID,
			Status:       blacklist.Status,
			CreatedAt:    blacklist.CreatedAt.Format("2006-01-02 15:04:05"),
		})
	}
}

// RemoveBlacklist 移除黑名单
// @Summary 移除黑名单
// @Description 将用户从黑名单中移除（软删除，status设为0）
// @Tags 管理端.黑名单
// @Accept json
// @Produce json
// @Param id path integer true "黑名单ID"
// @Success 200 {object} simpleMessageResponse
// @Failure 400 {object} code.Failure
// @Router /api/admin/blacklist/{id} [delete]
// @Security LoginVerifyToken
func (h *handler) RemoveBlacklist() core.HandlerFunc {
	return func(ctx core.Context) {
		idStr := ctx.Param("id")
		id, err := strconv.ParseInt(idStr, 10, 64)
		if err != nil {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "无效的ID"))
			return
		}

		result := h.repo.GetDbW().WithContext(ctx.RequestContext()).
			Table("douyin_blacklist").
			Where("id = ?", id).
			Update("status", 0)

		if result.Error != nil {
			ctx.AbortWithError(core.Error(http.StatusInternalServerError, code.ServerError, result.Error.Error()))
			return
		}

		if result.RowsAffected == 0 {
			ctx.AbortWithError(core.Error(http.StatusNotFound, code.ParamBindError, "黑名单记录不存在"))
			return
		}

		ctx.Payload(&simpleMessageResponse{Message: "移除成功"})
	}
}

// CheckBlacklist 检查用户是否在黑名单
// @Summary 检查黑名单状态
// @Description 检查指定抖音用户是否在黑名单中
// @Tags 管理端.黑名单
// @Accept json
// @Produce json
// @Param douyin_user_id query string true "抖音用户ID"
// @Success 200 {object} map[string]bool
// @Failure 400 {object} code.Failure
// @Router /api/admin/blacklist/check [get]
// @Security LoginVerifyToken
func (h *handler) CheckBlacklist() core.HandlerFunc {
	return func(ctx core.Context) {
		douyinUserID := ctx.RequestInputParams().Get("douyin_user_id")
		if douyinUserID == "" {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "抖音用户ID不能为空"))
			return
		}

		var count int64
		h.repo.GetDbR().WithContext(ctx.RequestContext()).
			Table("douyin_blacklist").
			Where("douyin_user_id = ? AND status = 1", douyinUserID).
			Count(&count)

		ctx.Payload(map[string]any{
			"douyin_user_id": douyinUserID,
			"is_blacklisted": count > 0,
		})
	}
}

// BatchAddBlacklist 批量添加黑名单
// @Summary 批量添加黑名单
// @Description 批量将抖音用户添加到黑名单
// @Tags 管理端.黑名单
// @Accept json
// @Produce json
// @Param body body batchAddBlacklistRequest true "请求参数"
// @Success 200 {object} batchAddBlacklistResponse
// @Failure 400 {object} code.Failure
// @Router /api/admin/blacklist/batch [post]
// @Security LoginVerifyToken
func (h *handler) BatchAddBlacklist() core.HandlerFunc {
	return func(ctx core.Context) {
		var req struct {
			DouyinUserIDs []string `json:"douyin_user_ids" binding:"required"`
			Reason        string   `json:"reason"`
		}

		if err := ctx.ShouldBindJSON(&req); err != nil {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err)))
			return
		}

		if len(req.DouyinUserIDs) == 0 {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "抖音用户ID列表不能为空"))
			return
		}

		// 获取操作人ID
		operatorID := int64(0)
		if ctx.SessionUserInfo().Id > 0 {
			operatorID = int64(ctx.SessionUserInfo().Id)
		}

		// 查询已存在的黑名单
		var existingIDs []string
		h.repo.GetDbR().WithContext(ctx.RequestContext()).
			Table("douyin_blacklist").
			Where("douyin_user_id IN ? AND status = 1", req.DouyinUserIDs).
			Pluck("douyin_user_id", &existingIDs)

		existMap := make(map[string]bool)
		for _, id := range existingIDs {
			existMap[id] = true
		}

		// 过滤出需要新增的
		var toAdd []model.DouyinBlacklist
		for _, uid := range req.DouyinUserIDs {
			if !existMap[uid] {
				toAdd = append(toAdd, model.DouyinBlacklist{
					DouyinUserID: uid,
					Reason:       req.Reason,
					OperatorID:   operatorID,
					Status:       1,
				})
			}
		}

		addedCount := 0
		if len(toAdd) > 0 {
			if err := h.repo.GetDbW().WithContext(ctx.RequestContext()).Create(&toAdd).Error; err != nil {
				ctx.AbortWithError(core.Error(http.StatusInternalServerError, code.ServerError, err.Error()))
				return
			}
			addedCount = len(toAdd)
		}

		ctx.Payload(map[string]any{
			"total_requested": len(req.DouyinUserIDs),
			"added":           addedCount,
			"skipped":         len(req.DouyinUserIDs) - addedCount,
		})
	}
}
