package admin

import (
	"fmt"
	"strconv"
	"time"

	"verification-platform-backend/internal/database"
	"verification-platform-backend/internal/model"
	"verification-platform-backend/pkg/response"

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

func SetupOrderRoutes(r *gin.RouterGroup) {
	r.GET("/orders", handleGetOrders)
	r.GET("/orders/:id", handleGetOrder)
	r.POST("/orders/:id/refund", handleRefundOrder)
	r.GET("/orders/stats", handleGetOrderStats)
}

func handleGetOrders(c *gin.Context) {
	userID := c.GetUint("user_id")
	page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
	pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))
	orderType := c.Query("order_type")
	status := c.Query("status")
	applicationID := c.Query("application_id")
	search := c.Query("search")
	startDate := c.Query("start_date")
	endDate := c.Query("end_date")

	var orders []model.Order
	var total int64

	query := database.DB.Model(&model.Order{}).
		Joins("LEFT JOIN applications ON orders.application_id = applications.id").
		Where("applications.user_id = ? OR orders.application_id IS NULL", userID)

	if orderType != "" {
		query = query.Where("orders.order_type = ?", orderType)
	}

	if status != "" {
		query = query.Where("orders.status = ?", status)
	}

	if applicationID != "" && applicationID != "all" {
		query = query.Where("orders.application_id = ?", applicationID)
	}

	if search != "" {
		query = query.Where("orders.order_no LIKE ? OR orders.title LIKE ?", "%"+search+"%", "%"+search+"%")
	}

	if startDate != "" {
		query = query.Where("orders.created_at >= ?", startDate+" 00:00:00")
	}

	if endDate != "" {
		query = query.Where("orders.created_at <= ?", endDate+" 23:59:59")
	}

	query.Count(&total)

	offset := (page - 1) * pageSize
	if err := query.Preload("User").Preload("Application").
		Order("orders.created_at DESC").
		Offset(offset).Limit(pageSize).
		Find(&orders).Error; err != nil {
		response.Error(c, 500, "获取订单列表失败")
		return
	}

	response.Success(c, gin.H{
		"orders":     orders,
		"total":      total,
		"page":       page,
		"page_size":  pageSize,
		"total_page": (total + int64(pageSize) - 1) / int64(pageSize),
	})
}

func handleGetOrder(c *gin.Context) {
	userID := c.GetUint("user_id")
	orderID := c.Param("id")

	var order model.Order
	if err := database.DB.Model(&model.Order{}).
		Joins("LEFT JOIN applications ON orders.application_id = applications.id").
		Where("orders.id = ? AND (applications.user_id = ? OR orders.application_id IS NULL)", orderID, userID).
		Preload("User").Preload("Application").
		First(&order).Error; err != nil {
		response.Error(c, 404, "订单不存在")
		return
	}

	response.Success(c, order)
}

func handleRefundOrder(c *gin.Context) {
	userID := c.GetUint("user_id")
	orderID := c.Param("id")

	var req struct {
		Reason string `json:"reason" binding:"required"`
	}

	if err := c.ShouldBindJSON(&req); err != nil {
		response.Error(c, 400, "参数错误: "+err.Error())
		return
	}

	var order model.Order
	if err := database.DB.Model(&model.Order{}).
		Joins("LEFT JOIN applications ON orders.application_id = applications.id").
		Where("orders.id = ? AND (applications.user_id = ? OR orders.application_id IS NULL)", orderID, userID).
		First(&order).Error; err != nil {
		response.Error(c, 404, "订单不存在")
		return
	}

	if order.Status != "paid" {
		response.Error(c, 400, "只能退款已支付的订单")
		return
	}

	tx := database.DB.Begin()

	now := time.Now()
	order.Status = "refunded"
	order.RefundAt = &now
	order.RefundReason = req.Reason

	if err := tx.Save(&order).Error; err != nil {
		tx.Rollback()
		response.Error(c, 500, "退款失败")
		return
	}

	switch order.OrderType {
	case "card_recharge":
		var rechargeRecord model.RechargeRecord
		if err := tx.Where("order_no = ?", order.OrderNo).First(&rechargeRecord).Error; err == nil {
			rechargeRecord.Status = "refunded"
			tx.Save(&rechargeRecord)
		}
	}

	tx.Commit()

	response.Success(c, gin.H{
		"message": "退款成功",
		"order":   order,
	})
}

func handleGetOrderStats(c *gin.Context) {
	userID := c.GetUint("user_id")
	applicationID := c.Query("application_id")
	startDate := c.Query("start_date")
	endDate := c.Query("end_date")

	query := database.DB.Model(&model.Order{}).
		Joins("LEFT JOIN applications ON orders.application_id = applications.id").
		Where("applications.user_id = ? OR orders.application_id IS NULL", userID)

	if applicationID != "" && applicationID != "all" {
		query = query.Where("orders.application_id = ?", applicationID)
	}

	if startDate != "" {
		query = query.Where("orders.created_at >= ?", startDate+" 00:00:00")
	}

	if endDate != "" {
		query = query.Where("orders.created_at <= ?", endDate+" 23:59:59")
	}

	var totalOrders, pendingOrders, paidOrders, refundedOrders int64
	var totalAmount, paidAmount, refundedAmount float64

	query.Count(&totalOrders)

	database.DB.Model(&model.Order{}).
		Joins("LEFT JOIN applications ON orders.application_id = applications.id").
		Where("applications.user_id = ? OR orders.application_id IS NULL", userID).
		Where("orders.status = ?", "pending").
		Count(&pendingOrders)

	database.DB.Model(&model.Order{}).
		Joins("LEFT JOIN applications ON orders.application_id = applications.id").
		Where("applications.user_id = ? OR orders.application_id IS NULL", userID).
		Where("orders.status = ?", "paid").
		Count(&paidOrders)

	database.DB.Model(&model.Order{}).
		Joins("LEFT JOIN applications ON orders.application_id = applications.id").
		Where("applications.user_id = ? OR orders.application_id IS NULL", userID).
		Where("orders.status = ?", "refunded").
		Count(&refundedOrders)

	database.DB.Model(&model.Order{}).
		Joins("LEFT JOIN applications ON orders.application_id = applications.id").
		Where("applications.user_id = ? OR orders.application_id IS NULL", userID).
		Where("orders.status IN ?", []string{"paid", "refunded"}).
		Select("COALESCE(SUM(amount), 0)").
		Scan(&totalAmount)

	database.DB.Model(&model.Order{}).
		Joins("LEFT JOIN applications ON orders.application_id = applications.id").
		Where("applications.user_id = ? OR orders.application_id IS NULL", userID).
		Where("orders.status = ?", "paid").
		Select("COALESCE(SUM(amount), 0)").
		Scan(&paidAmount)

	database.DB.Model(&model.Order{}).
		Joins("LEFT JOIN applications ON orders.application_id = applications.id").
		Where("applications.user_id = ? OR orders.application_id IS NULL", userID).
		Where("orders.status = ?", "refunded").
		Select("COALESCE(SUM(amount), 0)").
		Scan(&refundedAmount)

	var typeStats []struct {
		OrderType   string
		Count       int64
		TotalAmount float64
	}

	database.DB.Model(&model.Order{}).
		Joins("LEFT JOIN applications ON orders.application_id = applications.id").
		Where("applications.user_id = ? OR orders.application_id IS NULL", userID).
		Select("order_type, COUNT(*) as count, COALESCE(SUM(amount), 0) as total_amount").
		Group("order_type").
		Scan(&typeStats)

	response.Success(c, gin.H{
		"total_orders":    totalOrders,
		"pending_orders":  pendingOrders,
		"paid_orders":     paidOrders,
		"refunded_orders": refundedOrders,
		"total_amount":    totalAmount,
		"paid_amount":     paidAmount,
		"refunded_amount": refundedAmount,
		"type_stats":      typeStats,
	})
}

func CreateOrder(orderType string, userID uint, applicationID *uint, title string, amount float64, paymentType string, description string) (*model.Order, error) {
	orderNo := fmt.Sprintf("ORD%d%d", time.Now().Unix(), userID)

	order := model.Order{
		OrderNo:       orderNo,
		UserID:        userID,
		ApplicationID: applicationID,
		OrderType:     orderType,
		Title:         title,
		Amount:        amount,
		PaymentType:   paymentType,
		Status:        "pending",
		Description:   description,
	}

	if err := database.DB.Create(&order).Error; err != nil {
		return nil, err
	}

	return &order, nil
}

func PayOrder(orderNo string) error {
	var order model.Order
	if err := database.DB.Where("order_no = ?", orderNo).First(&order).Error; err != nil {
		return err
	}

	now := time.Now()
	order.Status = "paid"
	order.PaymentAt = &now

	return database.DB.Save(&order).Error
}
