package handlers

import (
	"fmt"
	"log"
	"net/http"
	"net/url"
	"strings"

	"github.com/gin-gonic/gin"

	"mengyastore-backend/internal/auth"
	"mengyastore-backend/internal/models"
	"mengyastore-backend/internal/storage"
)

const qrSize = "320x320"

type OrderHandler struct {
	productStore *storage.JSONStore
	orderStore   *storage.OrderStore
	authClient   *auth.SproutGateClient
}

type checkoutPayload struct {
	ProductID string `json:"productId"`
	Quantity  int    `json:"quantity"`
}

func NewOrderHandler(productStore *storage.JSONStore, orderStore *storage.OrderStore, authClient *auth.SproutGateClient) *OrderHandler {
	return &OrderHandler{productStore: productStore, orderStore: orderStore, authClient: authClient}
}

func (h *OrderHandler) tryExtractUser(c *gin.Context) (string, string) {
	authHeader := c.GetHeader("Authorization")
	if authHeader == "" || !strings.HasPrefix(authHeader, "Bearer ") {
		log.Println("[Order] 无 Authorization header，匿名下单")
		return "", ""
	}
	userToken := strings.TrimPrefix(authHeader, "Bearer ")
	log.Printf("[Order] 检测到用户 token，正在验证 (长度=%d)", len(userToken))

	result, err := h.authClient.VerifyToken(userToken)
	if err != nil {
		log.Printf("[Order] 验证 token 失败: %v", err)
		return "", ""
	}
	if !result.Valid {
		log.Println("[Order] token 验证返回 valid=false")
		return "", ""
	}
	if result.User == nil {
		log.Println("[Order] token 验证成功但 user 为空")
		return "", ""
	}

	log.Printf("[Order] 用户身份验证成功: account=%s username=%s", result.User.Account, result.User.Username)
	return result.User.Account, result.User.Username
}

func (h *OrderHandler) CreateOrder(c *gin.Context) {
	userAccount, userName := h.tryExtractUser(c)

	var payload checkoutPayload
	if err := c.ShouldBindJSON(&payload); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "invalid payload"})
		return
	}

	payload.ProductID = strings.TrimSpace(payload.ProductID)
	if payload.ProductID == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "missing required fields"})
		return
	}
	if payload.Quantity <= 0 {
		payload.Quantity = 1
	}

	product, err := h.productStore.GetByID(payload.ProductID)
	if err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
		return
	}
	if !product.Active {
		c.JSON(http.StatusBadRequest, gin.H{"error": "product is not available"})
		return
	}
	if product.Quantity < payload.Quantity {
		c.JSON(http.StatusBadRequest, gin.H{"error": "库存不足"})
		return
	}

	deliveredCodes, ok := extractCodes(&product, payload.Quantity)
	if !ok {
		c.JSON(http.StatusBadRequest, gin.H{"error": "卡密不足"})
		return
	}
	product.Quantity = len(product.Codes)
	updatedProduct, err := h.productStore.Update(product.ID, product)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	order := models.Order{
		ProductID:      updatedProduct.ID,
		ProductName:    updatedProduct.Name,
		UserAccount:    userAccount,
		UserName:       userName,
		Quantity:       payload.Quantity,
		DeliveredCodes: deliveredCodes,
		Status:         "pending",
	}
	created, err := h.orderStore.Create(order)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	qrPayload := fmt.Sprintf("order:%s:%s", created.ID, created.ProductID)
	qrURL := fmt.Sprintf("https://api.qrserver.com/v1/create-qr-code/?size=%s&data=%s", qrSize, url.QueryEscape(qrPayload))

	c.JSON(http.StatusOK, gin.H{
		"data": gin.H{
			"orderId":    created.ID,
			"qrCodeUrl":  qrURL,
			"productId":  created.ProductID,
			"productQty": created.Quantity,
			"viewCount":  updatedProduct.ViewCount,
			"status":     created.Status,
		},
	})
}

func (h *OrderHandler) ConfirmOrder(c *gin.Context) {
	orderID := c.Param("id")
	order, err := h.orderStore.Confirm(orderID)
	if err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{
		"data": gin.H{
			"orderId":        order.ID,
			"status":         order.Status,
			"deliveredCodes": order.DeliveredCodes,
		},
	})
}

func (h *OrderHandler) ListMyOrders(c *gin.Context) {
	authHeader := c.GetHeader("Authorization")
	if authHeader == "" || !strings.HasPrefix(authHeader, "Bearer ") {
		c.JSON(http.StatusUnauthorized, gin.H{"error": "请先登录"})
		return
	}
	userToken := strings.TrimPrefix(authHeader, "Bearer ")
	result, err := h.authClient.VerifyToken(userToken)
	if err != nil || !result.Valid || result.User == nil {
		c.JSON(http.StatusUnauthorized, gin.H{"error": "登录已过期，请重新登录"})
		return
	}

	orders, err := h.orderStore.ListByAccount(result.User.Account)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{"data": orders})
}

func extractCodes(product *models.Product, count int) ([]string, bool) {
	if count <= 0 {
		return nil, false
	}
	if len(product.Codes) < count {
		return nil, false
	}
	delivered := make([]string, count)
	copy(delivered, product.Codes[:count])
	product.Codes = product.Codes[count:]
	return delivered, true
}
