package admin

import (
	"bindbox-game/internal/code"
	"bindbox-game/internal/pkg/core"
	"bindbox-game/internal/pkg/validation"
	"bindbox-game/internal/repository/mysql/model"
	"net/http"
	"time"
)

// ========== 对对碰卡牌类型管理 ==========

type matchingCardTypeRequest struct {
	Code     string `json:"code" binding:"required"`
	Name     string `json:"name" binding:"required"`
	ImageURL string `json:"image_url"`
	Quantity int32  `json:"quantity"`
	Sort     int32  `json:"sort"`
	Status   int32  `json:"status"`
}

type matchingCardTypeResponse struct {
	ID        int64  `json:"id"`
	Code      string `json:"code"`
	Name      string `json:"name"`
	ImageURL  string `json:"image_url"`
	Quantity  int32  `json:"quantity"`
	Sort      int32  `json:"sort"`
	Status    int32  `json:"status"`
	CreatedAt string `json:"created_at"`
}

type listMatchingCardTypesResponse struct {
	List  []matchingCardTypeResponse `json:"list"`
	Total int64                      `json:"total"`
}

// ListMatchingCardTypes 列出对对碰卡牌类型
// @Summary 列出对对碰卡牌类型
// @Description 获取所有卡牌类型配置
// @Tags 管理端.对对碰
// @Accept json
// @Produce json
// @Security AdminAuth
// @Success 200 {object} listMatchingCardTypesResponse
// @Failure 400 {object} code.Failure
// @Router /api/admin/matching_card_types [get]
func (h *handler) ListMatchingCardTypes() core.HandlerFunc {
	return func(ctx core.Context) {
		items, err := h.readDB.MatchingCardTypes.WithContext(ctx.RequestContext()).Order(h.readDB.MatchingCardTypes.Sort.Asc(), h.readDB.MatchingCardTypes.ID.Asc()).Find()
		if err != nil {
			ctx.AbortWithError(core.Error(http.StatusInternalServerError, code.ParamBindError, err.Error()))
			return
		}
		list := make([]matchingCardTypeResponse, len(items))
		for i, item := range items {
			list[i] = matchingCardTypeResponse{
				ID:        item.ID,
				Code:      item.Code,
				Name:      item.Name,
				ImageURL:  item.ImageURL,
				Quantity:  item.Quantity,
				Sort:      item.Sort,
				Status:    item.Status,
				CreatedAt: item.CreatedAt.Format("2006-01-02 15:04:05"),
			}
		}
		ctx.Payload(&listMatchingCardTypesResponse{List: list, Total: int64(len(list))})
	}
}

// CreateMatchingCardType 创建卡牌类型
// @Summary 创建卡牌类型
// @Description 创建新的卡牌类型
// @Tags 管理端.对对碰
// @Accept json
// @Produce json
// @Security AdminAuth
// @Param RequestBody body matchingCardTypeRequest true "请求参数"
// @Success 200 {object} matchingCardTypeResponse
// @Failure 400 {object} code.Failure
// @Router /api/admin/matching_card_types [post]
func (h *handler) CreateMatchingCardType() core.HandlerFunc {
	return func(ctx core.Context) {
		req := new(matchingCardTypeRequest)
		if err := ctx.ShouldBindJSON(req); err != nil {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err)))
			return
		}
		if req.Quantity <= 0 {
			req.Quantity = 9
		}
		if req.Status == 0 {
			req.Status = 1
		}
		item := &model.MatchingCardTypes{
			Code:      req.Code,
			Name:      req.Name,
			ImageURL:  req.ImageURL,
			Quantity:  req.Quantity,
			Sort:      req.Sort,
			Status:    req.Status,
			CreatedAt: time.Now(),
			UpdatedAt: time.Now(),
		}
		if err := h.writeDB.MatchingCardTypes.WithContext(ctx.RequestContext()).Create(item); err != nil {
			ctx.AbortWithError(core.Error(http.StatusInternalServerError, code.ParamBindError, err.Error()))
			return
		}
		ctx.Payload(&matchingCardTypeResponse{
			ID:       item.ID,
			Code:     item.Code,
			Name:     item.Name,
			ImageURL: item.ImageURL,
			Quantity: item.Quantity,
			Sort:     item.Sort,
			Status:   item.Status,
		})
	}
}

// ModifyMatchingCardType 修改卡牌类型
// @Summary 修改卡牌类型
// @Description 修改已有的卡牌类型
// @Tags 管理端.对对碰
// @Accept json
// @Produce json
// @Security AdminAuth
// @Param id path int true "卡牌类型ID"
// @Param RequestBody body matchingCardTypeRequest true "请求参数"
// @Success 200 {object} matchingCardTypeResponse
// @Failure 400 {object} code.Failure
// @Router /api/admin/matching_card_types/{id} [put]
func (h *handler) ModifyMatchingCardType() core.HandlerFunc {
	return func(ctx core.Context) {
		idStr := ctx.Param("id")
		var id int64
		for i := 0; i < len(idStr); i++ {
			c := idStr[i]
			if c < '0' || c > '9' {
				break
			}
			id = id*10 + int64(c-'0')
		}
		if id <= 0 {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "invalid id"))
			return
		}
		req := new(matchingCardTypeRequest)
		if err := ctx.ShouldBindJSON(req); err != nil {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err)))
			return
		}
		updates := map[string]any{
			"code":       req.Code,
			"name":       req.Name,
			"image_url":  req.ImageURL,
			"quantity":   req.Quantity,
			"sort":       req.Sort,
			"status":     req.Status,
			"updated_at": time.Now(),
		}
		_, err := h.writeDB.MatchingCardTypes.WithContext(ctx.RequestContext()).Where(h.writeDB.MatchingCardTypes.ID.Eq(id)).Updates(updates)
		if err != nil {
			ctx.AbortWithError(core.Error(http.StatusInternalServerError, code.ParamBindError, err.Error()))
			return
		}
		item, _ := h.readDB.MatchingCardTypes.WithContext(ctx.RequestContext()).Where(h.readDB.MatchingCardTypes.ID.Eq(id)).First()
		if item == nil {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "not found"))
			return
		}
		ctx.Payload(&matchingCardTypeResponse{
			ID:       item.ID,
			Code:     item.Code,
			Name:     item.Name,
			ImageURL: item.ImageURL,
			Quantity: item.Quantity,
			Sort:     item.Sort,
			Status:   item.Status,
		})
	}
}

// DeleteMatchingCardType 删除卡牌类型
// @Summary 删除卡牌类型
// @Description 删除指定的卡牌类型
// @Tags 管理端.对对碰
// @Accept json
// @Produce json
// @Security AdminAuth
// @Param id path int true "卡牌类型ID"
// @Success 200 {object} map[string]any
// @Failure 400 {object} code.Failure
// @Router /api/admin/matching_card_types/{id} [delete]
func (h *handler) DeleteMatchingCardType() core.HandlerFunc {
	return func(ctx core.Context) {
		idStr := ctx.Param("id")
		var id int64
		for i := 0; i < len(idStr); i++ {
			c := idStr[i]
			if c < '0' || c > '9' {
				break
			}
			id = id*10 + int64(c-'0')
		}
		if id <= 0 {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "invalid id"))
			return
		}
		_, err := h.writeDB.MatchingCardTypes.WithContext(ctx.RequestContext()).Where(h.writeDB.MatchingCardTypes.ID.Eq(id)).Delete()
		if err != nil {
			ctx.AbortWithError(core.Error(http.StatusInternalServerError, code.ParamBindError, err.Error()))
			return
		}
		ctx.Payload(map[string]any{"deleted": true})
	}
}
