package pickup

import (
	"errors"
	"net/http"
	"strings"

	"hfb_sys/backend/internal/auditlog"
	"hfb_sys/backend/internal/middleware"
	"hfb_sys/backend/pkg/response"

	"github.com/gin-gonic/gin"
)

type Handler struct {
	service *Service
}

func NewHandler(service *Service) *Handler {
	return &Handler{service: service}
}

// Create 创建提号订单（管理员）
func (h *Handler) Create(c *gin.Context) {
	adminID, ok := currentAdminID(c)
	if !ok {
		response.Unauthorized(c, "缺少管理员上下文")
		return
	}
	var req CreateRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		response.BadRequest(c, "参数格式错误")
		return
	}
	item, err := h.service.Create(c.Request.Context(), req, adminID, auditMeta(c))
	if err != nil {
		writePickupError(c, err)
		return
	}
	response.OK(c, item)
}

// Complete 完成提号结算（管理员）
func (h *Handler) Complete(c *gin.Context) {
	adminID, ok := currentAdminID(c)
	if !ok {
		response.Unauthorized(c, "缺少管理员上下文")
		return
	}
	id, ok := parseID(c)
	if !ok {
		return
	}
	var req CompleteRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		response.BadRequest(c, "结算金额不正确")
		return
	}
	item, err := h.service.Complete(c.Request.Context(), id, req, adminID, auditMeta(c))
	if err != nil {
		writePickupError(c, err)
		return
	}
	response.OK(c, item)
}

// Cancel 取消提号（管理员）
func (h *Handler) Cancel(c *gin.Context) {
	adminID, ok := currentAdminID(c)
	if !ok {
		response.Unauthorized(c, "缺少管理员上下文")
		return
	}
	id, ok := parseID(c)
	if !ok {
		return
	}
	var req CancelRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		response.BadRequest(c, "取消原因不能为空")
		return
	}
	if err := h.service.Cancel(c.Request.Context(), id, req.Reason, adminID, auditMeta(c)); err != nil {
		writePickupError(c, err)
		return
	}
	response.OK(c, gin.H{"cancelled": true})
}

// List 提号订单列表（管理员）
func (h *Handler) List(c *gin.Context) {
	query := parseAdminQuery(c)
	result, err := h.service.ListAdmin(c.Request.Context(), query)
	if err != nil {
		writePickupError(c, err)
		return
	}
	response.OK(c, result)
}

// Detail 提号订单详情（管理员）
func (h *Handler) Detail(c *gin.Context) {
	id, ok := parseID(c)
	if !ok {
		return
	}
	item, err := h.service.FindByID(c.Request.Context(), id)
	if err != nil {
		writePickupError(c, err)
		return
	}
	response.OK(c, item)
}

// AvailableListings 可提号的 listing 搜索（管理员）
func (h *Handler) AvailableListings(c *gin.Context) {
	keyword := strings.TrimSpace(c.Query("keyword"))
	page, pageSize := parsePagination(c)
	result, err := h.service.ListAvailableListings(c.Request.Context(), keyword, page, pageSize)
	if err != nil {
		writePickupError(c, err)
		return
	}
	response.OK(c, result)
}

// ListForSeller 卖家自己的提号记录
func (h *Handler) ListForSeller(c *gin.Context) {
	userID, ok := currentUserID(c)
	if !ok {
		response.Unauthorized(c, "缺少用户上下文")
		return
	}
	query := parseSellerQuery(c)
	result, err := h.service.ListForSeller(c.Request.Context(), userID, query)
	if err != nil {
		writePickupError(c, err)
		return
	}
	response.OK(c, result)
}

func writePickupError(c *gin.Context, err error) {
	switch {
	case errors.Is(err, ErrDependencyUnavailable):
		response.ServiceUnavailable(c, "数据库未连接")
	case errors.Is(err, ErrListingUnavailable):
		response.BadRequest(c, "账号不可用或已在交易中")
	case errors.Is(err, ErrDuplicatePickup):
		response.BadRequest(c, "该账号已有进行中的提号订单")
	case errors.Is(err, ErrPickupNotFound):
		response.Error(c, http.StatusNotFound, "pickup_not_found", "提号订单不存在")
	case errors.Is(err, ErrPickupNotPickingUp):
		response.BadRequest(c, "提号订单状态不允许该操作")
	case errors.Is(err, ErrInvalidAmount):
		response.BadRequest(c, "结算金额不正确")
	case errors.Is(err, ErrInvalidProfit):
		response.BadRequest(c, "利润金额不正确")
	default:
		response.Error(c, http.StatusInternalServerError, "pickup_error", err.Error())
	}
}

func auditMeta(c *gin.Context) auditlog.Meta {
	return auditlog.Meta{
		IP:        c.ClientIP(),
		UserAgent: c.GetHeader("User-Agent"),
		RequestID: middleware.GetRequestID(c),
	}
}
