package app

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

	"bindbox-game/internal/code"
	"bindbox-game/internal/pkg/core"
	"bindbox-game/internal/pkg/validation"
)

type listActivitiesRequest struct {
	Name       string `form:"name"`
	CategoryID int64  `form:"category_id"`
	IsBoss     int32  `form:"is_boss"`
	Status     int32  `form:"status"`
	Page       int    `form:"page"`
	PageSize   int    `form:"page_size"`
}

type activityItem struct {
	ID                 int64  `json:"id"`
	Name               string `json:"name"`
	Banner             string `json:"banner"`
	Image              string `json:"image"`
	ActivityCategoryID int64  `json:"activity_category_id"`
	CategoryName       string `json:"category_name"`
	Status             int32  `json:"status"`
	PriceDraw          int64  `json:"price_draw"`
	IsBoss             int32  `json:"is_boss"`
}

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

type activityDetailResponse struct {
	ID                 int64     `json:"id"`
	CreatedAt          time.Time `json:"created_at"`
	UpdatedAt          time.Time `json:"updated_at"`
	Name               string    `json:"name"`
	Banner             string    `json:"banner"`
	ActivityCategoryID int64     `json:"activity_category_id"`
	Status             int32     `json:"status"`
	PriceDraw          int64     `json:"price_draw"`
	IsBoss             int32     `json:"is_boss"`
	StartTime          time.Time `json:"start_time"`
	EndTime            time.Time `json:"end_time"`
	DrawMode           string    `json:"draw_mode"`
	PlayType           string    `json:"play_type"`
	MinParticipants    int64     `json:"min_participants"`
	IntervalMinutes    int64     `json:"interval_minutes"`
	ScheduledTime      time.Time `json:"scheduled_time"`
	LastSettledAt      time.Time `json:"last_settled_at"`
	RefundCouponID     int64     `json:"refund_coupon_id"`
	Image              string    `json:"image"`
	GameplayIntro      string    `json:"gameplay_intro"`
	AllowItemCards     bool      `json:"allow_item_cards"`
	AllowCoupons       bool      `json:"allow_coupons"`
}

// ListActivities 活动列表
// @Summary 活动列表
// @Description 获取活动列表，支持分类、Boss、状态过滤与分页
// @Tags APP端.活动
// @Accept json
// @Produce json
// @Param name query string false "活动名称(模糊)"
// @Param category_id query int false "活动分类ID"
// @Param is_boss query int false "是否Boss(0/1)"
// @Param status query int false "状态(1进行中 2下线)"
// @Param page query int true "页码" default(1)
// @Param page_size query int true "每页数量，最多100" default(20)
// @Success 200 {object} listActivitiesResponse
// @Failure 400 {object} code.Failure
// @Router /api/app/activities [get]
func (h *handler) ListActivities() core.HandlerFunc {
	return func(ctx core.Context) {
		req := new(listActivitiesRequest)
		res := new(listActivitiesResponse)
		if err := ctx.ShouldBindForm(req); err != nil {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err)))
			return
		}
		var isBossPtr *int32
		if req.IsBoss == 0 || req.IsBoss == 1 {
			isBossPtr = &req.IsBoss
		}
		var statusPtr *int32
		onlineStatus := int32(1)
		statusPtr = &onlineStatus
		items, total, err := h.activity.ListActivities(ctx.RequestContext(), struct {
			Name       string
			CategoryID int64
			IsBoss     *int32
			Status     *int32
			Page       int
			PageSize   int
		}{Name: req.Name, CategoryID: req.CategoryID, IsBoss: isBossPtr, Status: statusPtr, Page: req.Page, PageSize: req.PageSize})
		if err != nil {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ListActivitiesError, err.Error()))
			return
		}
		res.Page = req.Page
		res.PageSize = req.PageSize
		res.Total = total
		res.List = make([]activityItem, len(items))
		// collect category ids
		var catIDs []int64
		catSet := make(map[int64]struct{})
		for _, v := range items {
			if v.ActivityCategoryID != 0 {
				if _, ok := catSet[v.ActivityCategoryID]; !ok {
					catSet[v.ActivityCategoryID] = struct{}{}
					catIDs = append(catIDs, v.ActivityCategoryID)
				}
			}
		}
		nameMap, _ := h.activity.GetCategoryNames(ctx.RequestContext(), catIDs)
		for i, v := range items {
			res.List[i] = activityItem{
				ID:                 v.ID,
				Name:               v.Name,
				Banner:             v.Banner,
				Image:              v.Image,
				ActivityCategoryID: v.ActivityCategoryID,
				CategoryName:       nameMap[v.ActivityCategoryID],
				Status:             v.Status,
				PriceDraw:          v.PriceDraw,
				IsBoss:             v.IsBoss,
			}
		}
		ctx.Payload(res)
	}
}

// GetActivityDetail 活动详情
// @Summary 活动详情
// @Description 获取指定活动的详细信息
// @Tags APP端.活动
// @Accept json
// @Produce json
// @Param activity_id path integer true "活动ID"
// @Success 200 {object} activityDetailResponse
// @Failure 400 {object} code.Failure
// @Router /api/app/activities/{activity_id} [get]
func (h *handler) GetActivityDetail() core.HandlerFunc {
	return func(ctx core.Context) {
		id, err := strconv.ParseInt(ctx.Param("activity_id"), 10, 64)
		if err != nil {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "未传递活动ID"))
			return
		}
		item, err := h.activity.GetActivity(ctx.RequestContext(), id)
		if err != nil {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, code.GetActivityError, err.Error()))
			return
		}
		if item.Status != 1 {
			ctx.AbortWithError(core.Error(http.StatusNotFound, code.GetActivityError, "该活动已下线"))
			return
		}
		rsp := &activityDetailResponse{
			ID:                 item.ID,
			CreatedAt:          item.CreatedAt,
			UpdatedAt:          item.UpdatedAt,
			Name:               item.Name,
			Banner:             item.Banner,
			ActivityCategoryID: item.ActivityCategoryID,
			Status:             item.Status,
			PriceDraw:          item.PriceDraw,
			IsBoss:             item.IsBoss,
			StartTime:          item.StartTime,
			EndTime:            item.EndTime,
			DrawMode:           item.DrawMode,
			PlayType:           item.PlayType,
			MinParticipants:    item.MinParticipants,
			IntervalMinutes:    item.IntervalMinutes,
			ScheduledTime:      item.ScheduledTime,
			LastSettledAt:      item.LastSettledAt,
			RefundCouponID:     item.RefundCouponID,
			Image:              item.Image,
			GameplayIntro:      item.GameplayIntro,
			AllowItemCards:     item.AllowItemCards,
			AllowCoupons:       item.AllowCoupons,
		}
		ctx.Payload(rsp)
	}
}
