package admin

import (
	"net/http"
	"strconv"
	"time"

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

// ==================== 套餐管理 API ====================

type createGamePassPackageRequest struct {
	Name          string `json:"name" binding:"required"`
	PassCount     int32  `json:"pass_count" binding:"required,min=1"`
	Price         int64  `json:"price" binding:"required,min=0"`
	OriginalPrice *int64 `json:"original_price"`
	ActivityID    *int64 `json:"activity_id"`
	ValidDays     *int32 `json:"valid_days"`
	SortOrder     *int32 `json:"sort_order"`
	Status        *int32 `json:"status"` // 1=上架 2=下架
}

type createGamePassPackageResponse struct {
	ID      int64  `json:"id"`
	Message string `json:"message"`
}

// CreateGamePassPackage 创建次数卡套餐
// @Summary 创建次数卡套餐
// @Description 创建可购买的次数卡套餐
// @Tags 管理端.次数卡套餐
// @Accept json
// @Produce json
// @Param RequestBody body createGamePassPackageRequest true "请求参数"
// @Success 200 {object} createGamePassPackageResponse
// @Failure 400 {object} code.Failure
// @Router /api/admin/game-pass-packages [post]
// @Security LoginVerifyToken
func (h *handler) CreateGamePassPackage() core.HandlerFunc {
	return func(ctx core.Context) {
		req := new(createGamePassPackageRequest)
		res := new(createGamePassPackageResponse)
		if err := ctx.ShouldBindJSON(req); err != nil {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err)))
			return
		}

		now := time.Now()
		m := &model.GamePassPackages{
			Name:      req.Name,
			PassCount: req.PassCount,
			Price:     req.Price,
			Status:    1, // 默认上架
			CreatedAt: now,
			UpdatedAt: now,
		}

		if req.OriginalPrice != nil {
			m.OriginalPrice = *req.OriginalPrice
		}
		if req.ActivityID != nil && *req.ActivityID > 0 {
			m.ActivityID = *req.ActivityID
		}
		if req.ValidDays != nil {
			m.ValidDays = *req.ValidDays
		}
		if req.SortOrder != nil {
			m.SortOrder = *req.SortOrder
		}
		if req.Status != nil {
			m.Status = *req.Status
		}

		if err := h.writeDB.GamePassPackages.WithContext(ctx.RequestContext()).Create(m); err != nil {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ServerError, err.Error()))
			return
		}

		res.ID = m.ID
		res.Message = "创建成功"
		ctx.Payload(res)
	}
}

type modifyGamePassPackageRequest struct {
	Name          *string `json:"name"`
	PassCount     *int32  `json:"pass_count"`
	Price         *int64  `json:"price"`
	OriginalPrice *int64  `json:"original_price"`
	ActivityID    *int64  `json:"activity_id"`
	ValidDays     *int32  `json:"valid_days"`
	SortOrder     *int32  `json:"sort_order"`
	Status        *int32  `json:"status"`
}

// ModifyGamePassPackage 修改次数卡套餐
// @Summary 修改次数卡套餐
// @Description 修改次数卡套餐配置
// @Tags 管理端.次数卡套餐
// @Accept json
// @Produce json
// @Param package_id path integer true "套餐ID"
// @Param RequestBody body modifyGamePassPackageRequest true "请求参数"
// @Success 200 {object} simpleMessageResponse
// @Failure 400 {object} code.Failure
// @Router /api/admin/game-pass-packages/{package_id} [put]
// @Security LoginVerifyToken
func (h *handler) ModifyGamePassPackage() core.HandlerFunc {
	return func(ctx core.Context) {
		req := new(modifyGamePassPackageRequest)
		if err := ctx.ShouldBindJSON(req); err != nil {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err)))
			return
		}
		idStr := ctx.Param("package_id")
		id, _ := strconv.ParseInt(idStr, 10, 64)
		if id <= 0 {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "套餐ID无效"))
			return
		}

		set := map[string]any{}
		if req.Name != nil {
			set["name"] = *req.Name
		}
		if req.PassCount != nil {
			set["pass_count"] = *req.PassCount
		}
		if req.Price != nil {
			set["price"] = *req.Price
		}
		if req.OriginalPrice != nil {
			set["original_price"] = *req.OriginalPrice
		}
		if req.ActivityID != nil {
			set["activity_id"] = *req.ActivityID
		}
		if req.ValidDays != nil {
			set["valid_days"] = *req.ValidDays
		}
		if req.SortOrder != nil {
			set["sort_order"] = *req.SortOrder
		}
		if req.Status != nil {
			set["status"] = *req.Status
		}
		if len(set) == 0 {
			ctx.Payload(simpleMessageResponse{Message: "无修改"})
			return
		}

		if _, err := h.writeDB.GamePassPackages.WithContext(ctx.RequestContext()).
			Where(h.writeDB.GamePassPackages.ID.Eq(id)).Updates(set); err != nil {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ServerError, err.Error()))
			return
		}
		ctx.Payload(simpleMessageResponse{Message: "修改成功"})
	}
}

// DeleteGamePassPackage 删除次数卡套餐
// @Summary 删除次数卡套餐
// @Description 软删除次数卡套餐
// @Tags 管理端.次数卡套餐
// @Accept json
// @Produce json
// @Param package_id path integer true "套餐ID"
// @Success 200 {object} simpleMessageResponse
// @Failure 400 {object} code.Failure
// @Router /api/admin/game-pass-packages/{package_id} [delete]
// @Security LoginVerifyToken
func (h *handler) DeleteGamePassPackage() core.HandlerFunc {
	return func(ctx core.Context) {
		idStr := ctx.Param("package_id")
		id, _ := strconv.ParseInt(idStr, 10, 64)
		if id <= 0 {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "套餐ID无效"))
			return
		}

		if _, err := h.writeDB.GamePassPackages.WithContext(ctx.RequestContext()).
			Where(h.writeDB.GamePassPackages.ID.Eq(id)).Delete(); err != nil {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ServerError, err.Error()))
			return
		}
		ctx.Payload(simpleMessageResponse{Message: "删除成功"})
	}
}

// ==================== 套餐列表 ====================

type listGamePassPackagesRequest struct {
	ActivityID *int64 `form:"activity_id"`
	Status     *int32 `form:"status"`
	Page       int    `form:"page"`
	PageSize   int    `form:"page_size"`
}

type gamePassPackageItem struct {
	ID            int64  `json:"id"`
	Name          string `json:"name"`
	PassCount     int32  `json:"pass_count"`
	Price         int64  `json:"price"`
	OriginalPrice int64  `json:"original_price"`
	ActivityID    int64  `json:"activity_id"`
	ActivityName  string `json:"activity_name"`
	ValidDays     int32  `json:"valid_days"`
	SortOrder     int32  `json:"sort_order"`
	Status        int32  `json:"status"`
	CreatedAt     string `json:"created_at"`
}

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

// ListGamePassPackages 次数卡套餐列表
// @Summary 次数卡套餐列表
// @Description 查询次数卡套餐列表
// @Tags 管理端.次数卡套餐
// @Accept json
// @Produce json
// @Param activity_id query integer false "活动ID"
// @Param status query integer false "状态: 1=上架 2=下架"
// @Param page query integer false "页码"
// @Param page_size query integer false "每页条数"
// @Success 200 {object} listGamePassPackagesResponse
// @Failure 400 {object} code.Failure
// @Router /api/admin/game-pass-packages [get]
// @Security LoginVerifyToken
func (h *handler) ListGamePassPackages() core.HandlerFunc {
	return func(ctx core.Context) {
		req := new(listGamePassPackagesRequest)
		res := new(listGamePassPackagesResponse)
		if err := ctx.ShouldBindForm(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
		}

		q := h.readDB.GamePassPackages.WithContext(ctx.RequestContext()).ReadDB()
		if req.ActivityID != nil && *req.ActivityID > 0 {
			q = q.Where(h.readDB.GamePassPackages.ActivityID.Eq(*req.ActivityID))
		}
		if req.Status != nil {
			q = q.Where(h.readDB.GamePassPackages.Status.Eq(*req.Status))
		}

		total, err := q.Count()
		if err != nil {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ServerError, err.Error()))
			return
		}

		packages, err := q.Order(h.readDB.GamePassPackages.SortOrder.Desc(), h.readDB.GamePassPackages.ID.Desc()).
			Limit(req.PageSize).
			Offset((req.Page - 1) * req.PageSize).
			Find()
		if err != nil {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ServerError, err.Error()))
			return
		}

		// 获取活动名称
		activityIDs := make([]int64, 0)
		for _, p := range packages {
			if p.ActivityID > 0 {
				activityIDs = append(activityIDs, p.ActivityID)
			}
		}
		activityMap := make(map[int64]string)
		if len(activityIDs) > 0 {
			activities, _ := h.readDB.Activities.WithContext(ctx.RequestContext()).Where(h.readDB.Activities.ID.In(activityIDs...)).Find()
			for _, a := range activities {
				activityMap[a.ID] = a.Name
			}
		}

		res.Page = req.Page
		res.PageSize = req.PageSize
		res.Total = total
		res.List = make([]gamePassPackageItem, len(packages))
		for i, p := range packages {
			res.List[i] = gamePassPackageItem{
				ID:            p.ID,
				Name:          p.Name,
				PassCount:     p.PassCount,
				Price:         p.Price,
				OriginalPrice: p.OriginalPrice,
				ActivityID:    p.ActivityID,
				ActivityName:  activityMap[p.ActivityID],
				ValidDays:     p.ValidDays,
				SortOrder:     p.SortOrder,
				Status:        p.Status,
				CreatedAt:     p.CreatedAt.Format("2006-01-02 15:04:05"),
			}
		}
		ctx.Payload(res)
	}
}
