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"
)

type listShippingStatsRequest struct {
    Page            int     `form:"page"`
    PageSize        int     `form:"page_size"`
    ProductID       *int64  `form:"product_id"`
    ProductName     string  `form:"product_name"`
    UserID          *int64  `form:"user_id"`
    UserName        string  `form:"user_name"`
    ExpressCode     string  `form:"express_code"`
    ExpressNo       string  `form:"express_no"`
    OrderID         *int64  `form:"order_id"`
    OrderNo         string  `form:"order_no"`
    OrderSourceType *int32  `form:"order_source_type"`
    Payer           string  `form:"payer"`
    Keyword         string  `form:"keyword"`
}

type listShippingStatsResponse struct {
    Page     int                        `json:"page"`
    PageSize int                        `json:"page_size"`
    Total    int64                      `json:"total"`
    List     []*model.OpsShippingStats  `json:"list"`
}

// ListShippingStats 发货统计列表
func (h *handler) ListShippingStats() core.HandlerFunc {
    return func(ctx core.Context) {
        req := new(listShippingStatsRequest)
        rsp := new(listShippingStatsResponse)
        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 }
        if req.PageSize > 100 { req.PageSize = 100 }

        q := h.readDB.OpsShippingStats.WithContext(ctx.RequestContext()).ReadDB()

        // 精确匹配
        if req.ProductID != nil { q = q.Where(h.readDB.OpsShippingStats.ProductID.Eq(*req.ProductID)) }
        if req.UserID != nil { q = q.Where(h.readDB.OpsShippingStats.UserID.Eq(*req.UserID)) }
        if req.OrderID != nil { q = q.Where(h.readDB.OpsShippingStats.OrderID.Eq(*req.OrderID)) }
        if req.OrderSourceType != nil { q = q.Where(h.readDB.OpsShippingStats.OrderSourceType.Eq(*req.OrderSourceType)) }
        if req.Payer != "" { q = q.Where(h.readDB.OpsShippingStats.Payer.Eq(req.Payer)) }
        // 字符串匹配
        if req.ProductName != "" { q = q.Where(h.readDB.OpsShippingStats.ProductName.Like("%" + req.ProductName + "%")) }
        if req.UserName != "" { q = q.Where(h.readDB.OpsShippingStats.UserName.Like("%" + req.UserName + "%")) }
        if req.ExpressCode != "" { q = q.Where(h.readDB.OpsShippingStats.ExpressCode.Eq(req.ExpressCode)) }
        if req.ExpressNo != "" { q = q.Where(h.readDB.OpsShippingStats.ExpressNo.Like("%" + req.ExpressNo + "%")) }
        if req.OrderNo != "" { q = q.Where(h.readDB.OpsShippingStats.OrderNo.Like("%" + req.OrderNo + "%")) }
        if req.Keyword != "" {
            like := "%" + req.Keyword + "%"
            q = q.Where(h.readDB.OpsShippingStats.ProductName.Like(like)).
                Or(h.readDB.OpsShippingStats.UserName.Like(like)).
                Or(h.readDB.OpsShippingStats.OrderNo.Like(like)).
                Or(h.readDB.OpsShippingStats.ExpressNo.Like(like))
        }

        total, err := q.Count()
        if err != nil {
            ctx.AbortWithError(core.Error(http.StatusBadRequest, 40101, err.Error()))
            return
        }
        rows, err := q.Order(h.readDB.OpsShippingStats.CreatedAt.Desc(), h.readDB.OpsShippingStats.ID.Desc()).
            Offset((req.Page-1)*req.PageSize).Limit(req.PageSize).Find()
        if err != nil {
            ctx.AbortWithError(core.Error(http.StatusBadRequest, 40102, err.Error()))
            return
        }
        rsp.Page = req.Page
        rsp.PageSize = req.PageSize
        rsp.Total = total
        rsp.List = rows
        ctx.Payload(rsp)
    }
}

type createShippingStatRequest struct {
    ProductID          int64  `json:"product_id" binding:"required"`
    ProductName        string `json:"product_name" binding:"required"`
    ProductPriceCents  int64  `json:"product_price_cents"`
    ShippedQty         int64  `json:"shipped_qty" binding:"required"`
    UserID             int64  `json:"user_id" binding:"required"`
    UserName           string `json:"user_name" binding:"required"`
    UserAddressText    string `json:"user_address_text"`
    ExpressCode        string `json:"express_code"`
    ExpressNo          string `json:"express_no"`
    OrderID            int64  `json:"order_id"`
    OrderNo            string `json:"order_no"`
    OrderQty           int64  `json:"order_qty"`
    OrderAmountCents   int64  `json:"order_amount_cents"`
    OrderSourceType    int32  `json:"order_source_type"`
    Payer              string `json:"payer"`
}

type simpleMessageResponseShipping struct {
    Message string `json:"message"`
}

// CreateShippingStat 新增发货统计记录
func (h *handler) CreateShippingStat() core.HandlerFunc {
    return func(ctx core.Context) {
        var req createShippingStatRequest
        if err := ctx.ShouldBindJSON(&req); err != nil {
            ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err)))
            return
        }
        shippedAt := time.Now()
        // 若传入了订单ID但未给金额/数量，尝试回填
        var orderAmount int64 = req.OrderAmountCents
        var orderQty int64 = req.OrderQty
        var orderNo string = req.OrderNo
        if req.OrderID > 0 && (orderAmount == 0 || orderQty == 0 || orderNo == "") {
            if ord, e := h.readDB.Orders.WithContext(ctx.RequestContext()).Where(h.readDB.Orders.ID.Eq(req.OrderID)).First(); e == nil && ord != nil {
                if orderAmount == 0 { orderAmount = ord.ActualAmount }
                if orderNo == "" { orderNo = ord.OrderNo }
            }
            if orderQty == 0 {
                _ = h.readDB.OrderItems.WithContext(ctx.RequestContext()).Where(h.readDB.OrderItems.OrderID.Eq(req.OrderID)).Select(h.readDB.OrderItems.Quantity.Sum()).Scan(&orderQty)
            }
        }

        // 自动计算盈亏：行价×发货数量 − （订单实付金额/下单总量）×发货数量（订单可空）
        var perUnitPaid int64
        if orderQty > 0 {
            perUnitPaid = orderAmount / orderQty
        }
        autoProfit := req.ProductPriceCents*req.ShippedQty - perUnitPaid*req.ShippedQty

        it := &model.OpsShippingStats{
            ShippedAt:         shippedAt,
            ProductID:         req.ProductID,
            ProductName:       req.ProductName,
            ProductPriceCents: req.ProductPriceCents,
            ShippedQty:        req.ShippedQty,
            UserID:            req.UserID,
            UserName:          req.UserName,
            UserAddressText:   req.UserAddressText,
            ExpressCode:       req.ExpressCode,
            ExpressNo:         req.ExpressNo,
            OrderID:           req.OrderID,
            OrderNo:           orderNo,
            OrderQty:          orderQty,
            OrderAmountCents:  orderAmount,
            ProfitLossCents:   autoProfit,
            OrderSourceType:   req.OrderSourceType,
            OrderSourceText:   sourceTextFromType(req.OrderSourceType),
            Payer:             req.Payer,
        }
        if err := h.writeDB.OpsShippingStats.WithContext(ctx.RequestContext()).Create(it); err != nil {
            ctx.AbortWithError(core.Error(http.StatusInternalServerError, 40106, "创建发货统计失败"))
            return
        }
        ctx.Payload(&simpleMessageResponseShipping{Message: "创建成功"})
    }
}

type modifyShippingStatRequest struct {
    ProductID          *int64  `json:"product_id"`
    ProductName        string  `json:"product_name"`
    ProductPriceCents  *int64  `json:"product_price_cents"`
    ShippedQty         *int64  `json:"shipped_qty"`
    UserID             *int64  `json:"user_id"`
    UserName           string  `json:"user_name"`
    UserAddressText    string  `json:"user_address_text"`
    ExpressCode        string  `json:"express_code"`
    ExpressNo          string  `json:"express_no"`
    OrderID            *int64  `json:"order_id"`
    OrderNo            string  `json:"order_no"`
    OrderQty           *int64  `json:"order_qty"`
    OrderAmountCents   *int64  `json:"order_amount_cents"`
    OrderSourceType    *int32  `json:"order_source_type"`
    Payer              string  `json:"payer"`
}

// ModifyShippingStat 修改发货统计记录
func (h *handler) ModifyShippingStat() core.HandlerFunc {
    return func(ctx core.Context) {
        id, err := strconv.ParseInt(ctx.Param("id"), 10, 64)
        if err != nil || id <= 0 {
            ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "未传递ID"))
            return
        }
        var req modifyShippingStatRequest
        if err := ctx.ShouldBindJSON(&req); err != nil {
            ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err)))
            return
        }
        row, err := h.readDB.OpsShippingStats.WithContext(ctx.RequestContext()).Where(h.readDB.OpsShippingStats.ID.Eq(id)).First()
        if err != nil || row == nil {
            ctx.AbortWithError(core.Error(http.StatusBadRequest, 40107, "记录不存在"))
            return
        }
        // shipped_at 字段从统计维度中移除，不再更新
        if req.ProductID != nil { row.ProductID = *req.ProductID }
        if req.ProductName != "" { row.ProductName = req.ProductName }
        if req.ProductPriceCents != nil { row.ProductPriceCents = *req.ProductPriceCents }
        if req.ShippedQty != nil { row.ShippedQty = *req.ShippedQty }
        if req.UserID != nil { row.UserID = *req.UserID }
        if req.UserName != "" { row.UserName = req.UserName }
        if req.UserAddressText != "" { row.UserAddressText = req.UserAddressText }
        if req.ExpressCode != "" { row.ExpressCode = req.ExpressCode }
        if req.ExpressNo != "" { row.ExpressNo = req.ExpressNo }
        if req.OrderID != nil {
            row.OrderID = *req.OrderID
            // 回填订单相关字段（若空）
            if row.OrderID > 0 {
                if ord, e := h.readDB.Orders.WithContext(ctx.RequestContext()).Where(h.readDB.Orders.ID.Eq(row.OrderID)).First(); e == nil && ord != nil {
                    if row.OrderNo == "" { row.OrderNo = ord.OrderNo }
                    if row.OrderAmountCents == 0 { row.OrderAmountCents = ord.ActualAmount }
                }
                if row.OrderQty == 0 {
                    var totalQty int64
                    if err := h.readDB.OrderItems.WithContext(ctx.RequestContext()).Where(h.readDB.OrderItems.OrderID.Eq(row.OrderID)).Select(h.readDB.OrderItems.Quantity.Sum()).Scan(&totalQty); err == nil {
                        row.OrderQty = totalQty
                    }
                }
            }
        }
        if req.OrderNo != "" { row.OrderNo = req.OrderNo }
        if req.OrderQty != nil { row.OrderQty = *req.OrderQty }
        if req.OrderAmountCents != nil { row.OrderAmountCents = *req.OrderAmountCents }
        if req.OrderSourceType != nil {
            row.OrderSourceType = *req.OrderSourceType
            row.OrderSourceText = sourceTextFromType(*req.OrderSourceType)
        }
        if req.Payer != "" { row.Payer = req.Payer }
        // 自动计算盈亏（订单金额按单位分摊）
        var perUnitPaidUpd int64
        if row.OrderQty > 0 {
            perUnitPaidUpd = row.OrderAmountCents / row.OrderQty
        }
        row.ProfitLossCents = row.ProductPriceCents*row.ShippedQty - perUnitPaidUpd*row.ShippedQty
        if err := h.writeDB.OpsShippingStats.Save(row); err != nil {
            ctx.AbortWithError(core.Error(http.StatusInternalServerError, 40108, "修改失败"))
            return
        }
        ctx.Payload(&simpleMessageResponseShipping{Message: "修改成功"})
    }
}

// DeleteShippingStat 删除发货统计记录
func (h *handler) DeleteShippingStat() core.HandlerFunc {
    return func(ctx core.Context) {
        id, err := strconv.ParseInt(ctx.Param("id"), 10, 64)
        if err != nil || id <= 0 {
            ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "未传递ID"))
            return
        }
        del := &model.OpsShippingStats{ID: id}
        if _, err := h.writeDB.OpsShippingStats.Delete(del); err != nil {
            ctx.AbortWithError(core.Error(http.StatusInternalServerError, 40109, "删除失败"))
            return
        }
        ctx.Payload(&simpleMessageResponseShipping{Message: "删除成功"})
    }
}

// GetShippingStat 获取单条发货统计详情
func (h *handler) GetShippingStat() core.HandlerFunc {
    return func(ctx core.Context) {
        id, err := strconv.ParseInt(ctx.Param("id"), 10, 64)
        if err != nil || id <= 0 {
            ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "未传递ID"))
            return
        }
        row, err := h.readDB.OpsShippingStats.WithContext(ctx.RequestContext()).Where(h.readDB.OpsShippingStats.ID.Eq(id)).First()
        if err != nil || row == nil {
            ctx.AbortWithError(core.Error(http.StatusBadRequest, 40103, "记录不存在"))
            return
        }
        ctx.Payload(row)
    }
}

func sourceTextFromType(t int32) string {
    switch t {
    case 1:
        return "淘宝"
    case 2:
        return "拼多多"
    case 3:
        return "京东"
    case 4:
        return "线下"
    default:
        return "未知"
    }
}