package service

import (
	"crypto/md5"
	"encoding/hex"
	"errors"
	"fmt"
	"log"
	"math/rand"
	"time"

	"github.com/gouki/lunar-server/internal/config"
	"github.com/gouki/lunar-server/internal/model"
	"gorm.io/gorm"
)

// OrderService 订单服务
type OrderService struct {
	db *gorm.DB
}

// NewOrderService 创建订单服务
func NewOrderService() *OrderService {
	return &OrderService{
		db: config.GetDB(),
	}
}

// CreateOrder 创建订单
func (s *OrderService) CreateOrder(order *model.Order) error {
	// 生成订单号
	order.OrderNo = s.generateOrderNo()
	order.Status = "pending"

	// 设置过期时间（30分钟）
	expireTime := time.Now().Add(30 * time.Minute)
	order.ExpireTime = &expireTime

	return s.db.Create(order).Error
}

// generateOrderNo 生成订单号
func (s *OrderService) generateOrderNo() string {
	// 格式：L + 年月日时分秒 + 6位随机数
	now := time.Now()
	random := rand.Intn(1000000)
	return fmt.Sprintf("L%s%06d", now.Format("20060102150405"), random)
}

// GetOrderByID 根据ID获取订单
func (s *OrderService) GetOrderByID(id uint) (*model.Order, error) {
	var order model.Order
	if err := s.db.First(&order, id).Error; err != nil {
		return nil, err
	}
	return &order, nil
}

// GetOrderByOrderNo 根据订单号获取订单
func (s *OrderService) GetOrderByOrderNo(orderNo string) (*model.Order, error) {
	var order model.Order
	if err := s.db.Where("order_no = ?", orderNo).First(&order).Error; err != nil {
		return nil, err
	}
	return &order, nil
}

// GetOrderList 获取订单列表
func (s *OrderService) GetOrderList(userID uint, page, pageSize int) ([]*model.Order, int64, error) {
	var orders []*model.Order
	var total int64

	query := s.db.Model(&model.Order{}).Where("user_id = ?", userID)

	if err := query.Count(&total).Error; err != nil {
		return nil, 0, err
	}

	if err := query.Order("created_at DESC").
		Offset((page - 1) * pageSize).
		Limit(pageSize).
		Find(&orders).Error; err != nil {
		return nil, 0, err
	}

	return orders, total, nil
}

// UpdateOrderStatus 更新订单状态
func (s *OrderService) UpdateOrderStatus(orderNo, status string) error {
	updates := map[string]interface{}{
		"status": status,
	}

	if status == "paid" {
		now := time.Now()
		updates["pay_time"] = &now
	}

	return s.db.Model(&model.Order{}).Where("order_no = ?", orderNo).Updates(updates).Error
}

// CancelOrder 取消订单（仅限本人且仅待支付状态可取消）
func (s *OrderService) CancelOrder(userID, id uint) error {
	result := s.db.Model(&model.Order{}).
		Where("id = ? AND user_id = ? AND status = ?", id, userID, "pending").
		Update("status", "cancelled")
	if result.Error != nil {
		return result.Error
	}
	if result.RowsAffected == 0 {
		return errors.New("订单不存在或当前状态不可取消")
	}
	return nil
}

// CheckOrderExpired 检查订单是否过期
func (s *OrderService) CheckOrderExpired(order *model.Order) bool {
	if order.ExpireTime == nil {
		return false
	}
	return time.Now().After(*order.ExpireTime)
}

// CreateWechatPayOrder 创建微信支付订单
func (s *OrderService) CreateWechatPayOrder(order *model.Order, openID string) (map[string]string, error) {
	// TODO: 实现微信支付下单逻辑
	// 这里返回模拟数据
	payParams := map[string]string{
		"timeStamp": fmt.Sprintf("%d", time.Now().Unix()),
		"nonceStr":  s.generateNonceStr(),
		"package":   fmt.Sprintf("prepay_id=wx%s", order.OrderNo),
		"signType":  "MD5",
		"paySign":   s.generatePaySign(order.OrderNo),
	}

	return payParams, nil
}

// generateNonceStr 生成随机字符串
func (s *OrderService) generateNonceStr() string {
	return fmt.Sprintf("%d", time.Now().UnixNano())
}

// generatePaySign 生成支付签名
func (s *OrderService) generatePaySign(orderNo string) string {
	// TODO: 实现真实的微信支付签名
	hash := md5.Sum([]byte(orderNo + "secret"))
	return hex.EncodeToString(hash[:])
}

// HandlePayNotify 处理支付回调（幂等：已支付订单不重复处理）
func (s *OrderService) HandlePayNotify(orderNo, transactionID string) error {
	order, err := s.GetOrderByOrderNo(orderNo)
	if err != nil {
		return fmt.Errorf("order not found: %w", err)
	}

	// 幂等：已支付直接返回成功
	if order.Status == "paid" {
		return nil
	}
	if order.Status != "pending" {
		return fmt.Errorf("order %s in unexpected status %s", orderNo, order.Status)
	}

	// 条件更新防止并发重复入账
	updates := map[string]interface{}{
		"status":   "paid",
		"pay_time": time.Now(),
		"remark":   order.Remark + " [tx:" + transactionID + "]",
	}
	result := s.db.Model(&model.Order{}).
		Where("order_no = ? AND status = ?", orderNo, "pending").
		Updates(updates)
	if result.Error != nil {
		return result.Error
	}
	if result.RowsAffected == 0 {
		// 并发下已被其他回调处理，视为幂等成功
		return nil
	}

	// 支付成功后才创建付费许愿
	if order.Type == "wish" && order.Remark != "" {
		wishService := NewWishService()
		wish := &model.Wish{
			UserID:  order.UserID,
			TreeID:  1, // 默认祈福树
			Content: order.Remark,
			Type:    "paid",
			Status:  1,
		}
		if err := wishService.CreateWish(wish); err != nil {
			// 许愿创建失败不回滚支付状态，由后台补处理
			log.Printf("create paid wish for order %s failed: %v", orderNo, err)
		}
	}

	return nil
}
