package admin

import (
    "net/http"
    "time"
    "errors"
    "bindbox-game/internal/pkg/core"
    "bindbox-game/internal/pkg/validation"
    "bindbox-game/internal/code"
    activitysvc "bindbox-game/internal/service/activity"
)

type setScheduledConfigRequest struct {
    PlayType            string  `json:"play_type"`
    DrawMode            string  `json:"draw_mode"`
    MinParticipants     int64   `json:"min_participants"`
    ScheduledTime       string  `json:"scheduled_time"`
    ScheduledDelayMinutes int64 `json:"scheduled_delay_minutes"`
    IntervalMinutes     int64   `json:"interval_minutes"`
    RefundCouponType    string  `json:"refund_coupon_type"`
    RefundCouponAmount  float64 `json:"refund_coupon_amount"`
    RefundCouponID      int64   `json:"refund_coupon_id"`
}

type scheduledConfigResponse struct {
    ActivityID          int64   `json:"activity_id"`
    PlayType            string  `json:"play_type"`
    DrawMode            string  `json:"draw_mode"`
    MinParticipants     int64   `json:"min_participants"`
    ScheduledTime       string  `json:"scheduled_time"`
    ScheduledDelayMinutes int64 `json:"scheduled_delay_minutes"`
    IntervalMinutes     int64   `json:"interval_minutes"`
    RefundCouponType    string  `json:"refund_coupon_type"`
    RefundCouponAmount  float64 `json:"refund_coupon_amount"`
    RefundCouponID      int64   `json:"refund_coupon_id"`
}

func (h *handler) SetScheduledConfig() core.HandlerFunc {
    return func(ctx core.Context) {
        if ctx.SessionUserInfo().IsSuper != 1 {
            ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "禁止操作"))
            return
        }
        activityID, err := parsePathID(ctx, "activity_id")
        if err != nil {
            ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "未传递活动ID"))
            return
        }
        req := new(setScheduledConfigRequest)
        if err := ctx.ShouldBindJSON(req); err != nil {
            ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err)))
            return
        }
        if req.DrawMode != "scheduled" && req.DrawMode != "instant" {
            ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "draw_mode错误"))
            return
        }
        if req.DrawMode == "scheduled" {
            if req.MinParticipants <= 0 {
                ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "min_participants必须>0"))
                return
            }
            var st time.Time
            if req.ScheduledDelayMinutes > 0 {
                st = time.Now().Add(time.Duration(req.ScheduledDelayMinutes) * time.Minute)
            } else if req.IntervalMinutes > 0 {
                st = time.Now().Add(time.Duration(req.IntervalMinutes) * time.Minute)
            } else {
                if req.ScheduledTime == "" {
                    ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "scheduled_time或scheduled_delay_minutes必填"))
                    return
                }
                var ok bool
                if t, e := time.Parse(time.RFC3339, req.ScheduledTime); e == nil { st = t; ok = true }
                if !ok {
                    if t2, e2 := time.ParseInLocation("2006-01-02 15:04:05", req.ScheduledTime, time.Local); e2 == nil { st = t2; ok = true }
                }
                if !ok {
                    ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "scheduled_time格式错误"))
                    return
                }
            }
            if st.Before(time.Now().Add(1 * time.Minute)) {
                ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "scheduled_time需晚于当前时间1分钟"))
                return
            }
            req.ScheduledTime = st.UTC().Format(time.RFC3339)
        }
        var stPtr *time.Time
        if req.ScheduledTime != "" { t := parseTimeFlexible(req.ScheduledTime); if !t.IsZero() { stPtr = &t } }
        if req.ScheduledDelayMinutes > 0 && stPtr == nil { t := time.Now().Add(time.Duration(req.ScheduledDelayMinutes)*time.Minute); stPtr = &t }
        if req.IntervalMinutes > 0 && stPtr == nil { t := time.Now().Add(time.Duration(req.IntervalMinutes)*time.Minute); stPtr = &t }
        if err := h.activity.SaveActivityDrawConfig(ctx.RequestContext(), activityID, activitysvc.DrawConfig{ PlayType: req.PlayType, DrawMode: req.DrawMode, MinParticipants: req.MinParticipants, IntervalMinutes: req.IntervalMinutes, ScheduledTime: stPtr, RefundCouponID: req.RefundCouponID }); err != nil {
            ctx.AbortWithError(core.Error(http.StatusInternalServerError, 160010, err.Error()))
            return
        }
        resp := &scheduledConfigResponse{
            ActivityID: activityID,
            PlayType: req.PlayType,
            DrawMode: req.DrawMode,
            MinParticipants: req.MinParticipants,
            ScheduledTime: req.ScheduledTime,
            ScheduledDelayMinutes: req.ScheduledDelayMinutes,
            IntervalMinutes: req.IntervalMinutes,
            RefundCouponType: req.RefundCouponType,
            RefundCouponAmount: req.RefundCouponAmount,
            RefundCouponID: req.RefundCouponID,
        }
        ctx.Payload(resp)
    }
}

func (h *handler) GetScheduledConfig() core.HandlerFunc {
    return func(ctx core.Context) {
        if ctx.SessionUserInfo().IsSuper != 1 {
            ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "禁止操作"))
            return
        }
        activityID, err := parsePathID(ctx, "activity_id")
        if err != nil {
            ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "未传递活动ID"))
            return
        }
        dc, err := h.activity.GetActivityDrawConfig(ctx.RequestContext(), activityID)
        if err != nil || dc == nil {
            ctx.AbortWithError(core.Error(http.StatusBadRequest, 160011, "配置不存在"))
            return
        }
        resp := &scheduledConfigResponse{ ActivityID: activityID, PlayType: dc.PlayType, DrawMode: dc.DrawMode, MinParticipants: dc.MinParticipants, ScheduledTime: func() string { if dc.ScheduledTime!=nil { return dc.ScheduledTime.UTC().Format(time.RFC3339) }; return "" }(), ScheduledDelayMinutes: 0, IntervalMinutes: dc.IntervalMinutes, RefundCouponType: "", RefundCouponAmount: 0, RefundCouponID: dc.RefundCouponID }
        ctx.Payload(resp)
    }
}

func parsePathID(ctx core.Context, name string) (int64, error) {
    v := ctx.Param(name)
    if v == "" { return 0, errors.New("missing id") }
    id, err := strconvParseInt(v)
    if err != nil { return 0, err }
    return id, nil
}

func parseTimeFlexible(s string) time.Time {
    if s == "" { return time.Time{} }
    if t, err := time.Parse(time.RFC3339, s); err == nil { return t }
    if t2, err2 := time.ParseInLocation("2006-01-02 15:04:05", s, time.Local); err2 == nil { return t2 }
    return time.Time{}
}

func strconvParseInt(s string) (int64, error) {
    var n int64
    for i := 0; i < len(s); i++ {
        c := s[i]
        if c < '0' || c > '9' { return 0, errors.New("invalid id") }
        n = n*10 + int64(c-'0')
    }
    return n, nil
}
