package admin

import (
  "net/http"

  "bindbox-game/internal/code"
  "bindbox-game/internal/pkg/core"
  "bindbox-game/internal/pkg/validation"
  usersvc "bindbox-game/internal/service/user"
)

type batchPointsRequest struct {
  Users []int64 `json:"users" binding:"required"`
  Amount int64 `json:"amount" binding:"min=1"`
  Reason string `json:"reason"`
  IdempotencyKey string `json:"idempotency_key"`
}

type batchCouponsRequest struct {
  Users []int64 `json:"users" binding:"required"`
  CouponID int64 `json:"coupon_id" binding:"required"`
  QuantityPerUser int `json:"quantity_per_user"`
  IdempotencyKey string `json:"idempotency_key"`
}

type batchRewardsRequest struct {
  Users []int64 `json:"users" binding:"required"`
  ProductID int64 `json:"product_id" binding:"required"`
  Quantity int `json:"quantity" binding:"min=1"`
  ActivityID *int64 `json:"activity_id"`
  RewardID *int64 `json:"reward_id"`
  AddressID *int64 `json:"address_id"`
  Remark string `json:"remark"`
  IdempotencyKey string `json:"idempotency_key"`
}

type batchItemResult struct {
  UserID int64 `json:"user_id"`
  Status string `json:"status"`
  Message string `json:"message"`
}

type batchResponse struct {
  Success int `json:"success"`
  Failed int `json:"failed"`
  Details []batchItemResult `json:"details"`
}

func (h *handler) BatchAddUserPoints() core.HandlerFunc {
  return func(ctx core.Context) {
    if ctx.SessionUserInfo().IsSuper != 1 {
      ctx.AbortWithError(core.Error(http.StatusBadRequest, code.CreateAdminError, "禁止操作"))
      return
    }
    req := new(batchPointsRequest)
    if err := ctx.ShouldBindJSON(req); err != nil {
      ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err)))
      return
    }
    if len(req.Users) != 1 {
      ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "当前仅支持单用户操作，请仅选择1位用户"))
      return
    }
    res := &batchResponse{Details: make([]batchItemResult, 0, len(req.Users))}
    for _, uid := range req.Users {
      if err := h.userSvc.AddPoints(ctx.RequestContext(), uid, req.Amount, "manual", req.Reason, nil, nil); err != nil {
        res.Failed++
        res.Details = append(res.Details, batchItemResult{UserID: uid, Status: "failed", Message: err.Error()})
      } else {
        res.Success++
        res.Details = append(res.Details, batchItemResult{UserID: uid, Status: "success"})
      }
    }
    ctx.Payload(res)
  }
}

func (h *handler) BatchAddUserCoupons() core.HandlerFunc {
  return func(ctx core.Context) {
    if ctx.SessionUserInfo().IsSuper != 1 {
      ctx.AbortWithError(core.Error(http.StatusBadRequest, code.CreateAdminError, "禁止操作"))
      return
    }
    req := new(batchCouponsRequest)
    if err := ctx.ShouldBindJSON(req); err != nil {
      ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err)))
      return
    }
    if len(req.Users) != 1 {
      ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "当前仅支持单用户操作，请仅选择1位用户"))
      return
    }
    if req.QuantityPerUser <= 0 { req.QuantityPerUser = 1 }
    if req.QuantityPerUser > 5 { req.QuantityPerUser = 5 }
    res := &batchResponse{Details: make([]batchItemResult, 0, len(req.Users))}
    for _, uid := range req.Users {
      ok := true
      for i := 0; i < req.QuantityPerUser; i++ {
        if err := h.userSvc.AddCoupon(ctx.RequestContext(), uid, req.CouponID); err != nil { ok = false }
      }
      if ok {
        res.Success++
        res.Details = append(res.Details, batchItemResult{UserID: uid, Status: "success"})
      } else {
        res.Failed++
        res.Details = append(res.Details, batchItemResult{UserID: uid, Status: "failed"})
      }
    }
    ctx.Payload(res)
  }
}

func (h *handler) BatchGrantUserRewards() core.HandlerFunc {
  return func(ctx core.Context) {
    if ctx.SessionUserInfo().IsSuper != 1 {
      ctx.AbortWithError(core.Error(http.StatusBadRequest, code.CreateAdminError, "禁止操作"))
      return
    }
    req := new(batchRewardsRequest)
    if err := ctx.ShouldBindJSON(req); err != nil {
      ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err)))
      return
    }
    if len(req.Users) != 1 {
      ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "当前仅支持单用户操作，请仅选择1位用户"))
      return
    }
    if req.Quantity <= 0 { req.Quantity = 1 }
    if req.Quantity > 10 { req.Quantity = 10 }
    res := &batchResponse{Details: make([]batchItemResult, 0, len(req.Users))}
    r := usersvc.GrantRewardRequest{ProductID: req.ProductID, Quantity: req.Quantity, ActivityID: req.ActivityID, RewardID: req.RewardID, AddressID: req.AddressID, Remark: req.Remark}
    for _, uid := range req.Users {
      _, err := h.userSvc.GrantReward(ctx.RequestContext(), uid, r)
      if err != nil {
        res.Failed++
        res.Details = append(res.Details, batchItemResult{UserID: uid, Status: "failed", Message: err.Error()})
      } else {
        res.Success++
        res.Details = append(res.Details, batchItemResult{UserID: uid, Status: "success"})
      }
    }
    ctx.Payload(res)
  }
}