package admin

import (
	"encoding/json"
	"net/http"
	"strconv"

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

// ======== 抖店商品奖励规则 CRUD ========

type douyinProductRewardListRequest struct {
	Page     int `form:"page"`
	PageSize int `form:"page_size"`
}

type douyinProductRewardListResponse struct {
	List  []douyinProductRewardItem `json:"list"`
	Total int64                     `json:"total"`
	Page  int                       `json:"page"`
}

type douyinProductRewardItem struct {
	ID            int64           `json:"id"`
	ProductID     string          `json:"product_id"`
	ProductName   string          `json:"product_name"`
	ActivityID    int64           `json:"activity_id"`
	ActivityName  string          `json:"activity_name"`
	RewardType    string          `json:"reward_type"`
	RewardPayload json.RawMessage `json:"reward_payload"`
	Quantity      int32           `json:"quantity"`
	Status        int32           `json:"status"`
	CreatedAt     string          `json:"created_at"`
}

// ListDouyinProductRewards 获取抖店商品奖励规则列表
func (h *handler) ListDouyinProductRewards() core.HandlerFunc {
	return func(ctx core.Context) {
		req := new(douyinProductRewardListRequest)
		if err := ctx.ShouldBindForm(req); err != nil {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, 10001, validation.Error(err)))
			return
		}
		if req.Page <= 0 {
			req.Page = 1
		}
		if req.PageSize <= 0 {
			req.PageSize = 20
		}

		db := h.repo.GetDbR().Model(&model.DouyinProductRewards{})

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

		var list []model.DouyinProductRewards
		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, 10003, err.Error()))
			return
		}

		// 收集所有需要查询的 activity_id
		activityIDs := make([]int64, 0)
		for _, r := range list {
			if r.ActivityID > 0 {
				activityIDs = append(activityIDs, r.ActivityID)
			}
		}

		// 批量查询活动名称
		activityNameMap := make(map[int64]string)
		if len(activityIDs) > 0 {
			var activities []model.LivestreamActivities
			if err := h.repo.GetDbR().Model(&model.LivestreamActivities{}).
				Select("id, name").
				Where("id IN ?", activityIDs).
				Find(&activities).Error; err == nil {
				for _, a := range activities {
					activityNameMap[a.ID] = a.Name
				}
			}
		}

		res := douyinProductRewardListResponse{
			List:  make([]douyinProductRewardItem, len(list)),
			Total: total,
			Page:  req.Page,
		}
		for i, r := range list {
			res.List[i] = douyinProductRewardItem{
				ID:            r.ID,
				ProductID:     r.ProductID,
				ProductName:   r.ProductName,
				ActivityID:    r.ActivityID,
				ActivityName:  activityNameMap[r.ActivityID],
				RewardType:    r.RewardType,
				RewardPayload: json.RawMessage(r.RewardPayload),
				Quantity:      r.Quantity,
				Status:        r.Status,
				CreatedAt:     r.CreatedAt.Format("2006-01-02 15:04:05"),
			}
		}
		ctx.Payload(res)
	}
}

type createDouyinProductRewardRequest struct {
	ProductID     string          `json:"product_id" binding:"required"`
	ProductName   string          `json:"product_name"`
	ActivityID    int64           `json:"activity_id"`
	RewardType    string          `json:"reward_type" binding:"required"`
	RewardPayload json.RawMessage `json:"reward_payload"`
	Quantity      int32           `json:"quantity"`
	Status        int32           `json:"status"`
}

// CreateDouyinProductReward 创建抖店商品奖励规则
func (h *handler) CreateDouyinProductReward() core.HandlerFunc {
	return func(ctx core.Context) {
		req := new(createDouyinProductRewardRequest)
		if err := ctx.ShouldBindJSON(req); err != nil {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, 10001, validation.Error(err)))
			return
		}
		if req.Quantity <= 0 {
			req.Quantity = 1
		}
		if req.Status == 0 {
			req.Status = 1
		}

		row := &model.DouyinProductRewards{
			ProductID:     req.ProductID,
			ProductName:   req.ProductName,
			ActivityID:    req.ActivityID,
			RewardType:    req.RewardType,
			RewardPayload: string(req.RewardPayload),
			Quantity:      req.Quantity,
			Status:        req.Status,
		}
		if err := h.repo.GetDbW().Create(row).Error; err != nil {
			ctx.AbortWithError(core.Error(http.StatusInternalServerError, 10002, err.Error()))
			return
		}
		ctx.Payload(map[string]any{"id": row.ID, "message": "创建成功"})
	}
}

type updateDouyinProductRewardRequest struct {
	ProductName   string          `json:"product_name"`
	ActivityID    *int64          `json:"activity_id"`
	RewardType    string          `json:"reward_type"`
	RewardPayload json.RawMessage `json:"reward_payload"`
	Quantity      int32           `json:"quantity"`
	Status        int32           `json:"status"`
}

// UpdateDouyinProductReward 更新抖店商品奖励规则
func (h *handler) UpdateDouyinProductReward() core.HandlerFunc {
	return func(ctx core.Context) {
		idStr := ctx.Param("id")
		id, _ := strconv.ParseInt(idStr, 10, 64)
		if id <= 0 {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, 10001, "无效的ID"))
			return
		}

		req := new(updateDouyinProductRewardRequest)
		if err := ctx.ShouldBindJSON(req); err != nil {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, 10002, validation.Error(err)))
			return
		}

		updates := map[string]any{
			"product_name":   req.ProductName,
			"reward_type":    req.RewardType,
			"reward_payload": string(req.RewardPayload),
			"quantity":       req.Quantity,
			"status":         req.Status,
		}
		if req.ActivityID != nil {
			updates["activity_id"] = *req.ActivityID
		}
		if err := h.repo.GetDbW().Model(&model.DouyinProductRewards{}).Where("id = ?", id).Updates(updates).Error; err != nil {
			ctx.AbortWithError(core.Error(http.StatusInternalServerError, 10003, err.Error()))
			return
		}
		ctx.Payload(map[string]string{"message": "更新成功"})
	}
}

// DeleteDouyinProductReward 删除抖店商品奖励规则
func (h *handler) DeleteDouyinProductReward() core.HandlerFunc {
	return func(ctx core.Context) {
		idStr := ctx.Param("id")
		id, _ := strconv.ParseInt(idStr, 10, 64)
		if id <= 0 {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, 10001, "无效的ID"))
			return
		}

		if err := h.repo.GetDbW().Delete(&model.DouyinProductRewards{}, id).Error; err != nil {
			ctx.AbortWithError(core.Error(http.StatusInternalServerError, 10002, err.Error()))
			return
		}
		ctx.Payload(map[string]string{"message": "删除成功"})
	}
}
