package plant

import (
	"errors"
	"sundynix-go/global"
	"sundynix-go/model/plant"
	plantReq "sundynix-go/model/plant/request"
	"time"

	"gorm.io/gorm"
)

type ExchangeService struct{}

// ==================== 管理端 ====================

// CreateItem 创建兑换商品
func (s *ExchangeService) CreateItem(req plantReq.ExchangeItemCreateReq) error {
	item := plant.ExchangeItem{
		Name:         req.Name,
		Description:  req.Description,
		ImageId:      req.ImageId,
		Type:         req.Type,
		CostSunlight: req.CostSunlight,
		Stock:        req.Stock,
		LimitPerUser: req.LimitPerUser,
		Sort:         req.Sort,
		Status:       1, // 默认上架
	}
	if req.StartTime != "" {
		t, _ := time.Parse("2006-01-02 15:04:05", req.StartTime)
		item.StartTime = &t
	}
	if req.EndTime != "" {
		t, _ := time.Parse("2006-01-02 15:04:05", req.EndTime)
		item.EndTime = &t
	}
	return global.DB.Create(&item).Error
}

// UpdateItem 更新兑换商品
func (s *ExchangeService) UpdateItem(req plantReq.ExchangeItemUpdateReq) error {
	updateMap := map[string]interface{}{
		"name":           req.Name,
		"description":    req.Description,
		"image_id":       req.ImageId,
		"type":           req.Type,
		"cost_sunlight":  req.CostSunlight,
		"stock":          req.Stock,
		"limit_per_user": req.LimitPerUser,
		"status":         req.Status,
		"sort":           req.Sort,
	}
	if req.StartTime != "" {
		t, _ := time.Parse("2006-01-02 15:04:05", req.StartTime)
		updateMap["start_time"] = t
	}
	if req.EndTime != "" {
		t, _ := time.Parse("2006-01-02 15:04:05", req.EndTime)
		updateMap["end_time"] = t
	}
	return global.DB.Model(&plant.ExchangeItem{}).Where("id = ?", req.Id).Updates(updateMap).Error
}

// DeleteItem 删除兑换商品
func (s *ExchangeService) DeleteItem(id string) error {
	return global.DB.Where("id = ?", id).Delete(&plant.ExchangeItem{}).Error
}

// AdminItemList 管理端商品列表（含下架）
func (s *ExchangeService) AdminItemList(req plantReq.ExchangeItemListReq) (list []plant.ExchangeItem, total int64, err error) {
	db := global.DB.Model(&plant.ExchangeItem{}).Preload("Image")
	if req.Type != "" {
		db = db.Where("type = ?", req.Type)
	}
	if req.Status != 0 {
		db = db.Where("status = ?", req.Status)
	}
	if req.Keyword != "" {
		db = db.Where("name LIKE ?", "%"+req.Keyword+"%")
	}
	err = db.Count(&total).Error
	if err != nil {
		return
	}
	err = db.Scopes(req.Paginate()).Order("sort asc, created_at desc").Find(&list).Error
	return
}

// AdminOrderList 管理端订单列表
func (s *ExchangeService) AdminOrderList(req plantReq.ExchangeOrderListReq) (list []plant.ExchangeOrder, total int64, err error) {
	db := global.DB.Model(&plant.ExchangeOrder{}).Preload("Item", func(db *gorm.DB) *gorm.DB {
		return db.Preload("Image")
	})
	if req.Status != 0 {
		db = db.Where("status = ?", req.Status)
	}
	if req.UserId != "" {
		db = db.Where("user_id = ?", req.UserId)
	}
	if req.Keyword != "" {
		db = db.Where("item_name LIKE ? OR recipient_name LIKE ?", "%"+req.Keyword+"%", "%"+req.Keyword+"%")
	}
	err = db.Count(&total).Error
	if err != nil {
		return
	}
	err = db.Scopes(req.Paginate()).Order("created_at desc").Find(&list).Error
	return
}

// UpdateOrderStatus 更新订单状态（管理端）
func (s *ExchangeService) UpdateOrderStatus(req plantReq.ExchangeOrderUpdateReq) error {
	updateMap := map[string]interface{}{
		"status": req.Status,
	}
	if req.TrackingNo != "" {
		updateMap["tracking_no"] = req.TrackingNo
	}
	if req.Remark != "" {
		updateMap["remark"] = req.Remark
	}
	if req.Status == plant.OrderStatusCompleted {
		now := time.Now()
		updateMap["completed_at"] = now
	}
	// 如果取消订单，退还阳光值
	if req.Status == plant.OrderStatusCancelled {
		return global.DB.Transaction(func(tx *gorm.DB) error {
			var order plant.ExchangeOrder
			if err := tx.Where("id = ?", req.Id).First(&order).Error; err != nil {
				return err
			}
			if order.Status == plant.OrderStatusCancelled {
				return errors.New("订单已取消")
			}
			// 退还阳光值
			if err := tx.Model(&plant.UserProfile{}).Where("user_id = ?", order.UserId).
				Update("current_sunlight", gorm.Expr("current_sunlight + ?", order.CostSunlight)).Error; err != nil {
				return err
			}
			// 恢复库存
			if err := tx.Model(&plant.ExchangeItem{}).Where("id = ? AND stock >= 0", order.ItemId).
				Update("stock", gorm.Expr("stock + ?", order.Quantity)).Error; err != nil {
				// 库存为-1(无限)时，WHERE条件不匹配，不影响
			}
			return tx.Model(&plant.ExchangeOrder{}).Where("id = ?", req.Id).Updates(updateMap).Error
		})
	}
	return global.DB.Model(&plant.ExchangeOrder{}).Where("id = ?", req.Id).Updates(updateMap).Error
}

// ==================== 用户端 ====================

// UserItemList 用户端商品列表（仅上架）
func (s *ExchangeService) UserItemList(req plantReq.ExchangeItemListReq) (list []plant.ExchangeItem, total int64, err error) {
	db := global.DB.Model(&plant.ExchangeItem{}).Preload("Image").
		Where("status = 1")
	if req.Type != "" {
		db = db.Where("type = ?", req.Type)
	}
	if req.Keyword != "" {
		db = db.Where("name LIKE ?", "%"+req.Keyword+"%")
	}
	err = db.Count(&total).Error
	if err != nil {
		return
	}
	err = db.Scopes(req.Paginate()).Order("sort asc, created_at desc").Find(&list).Error
	return
}

// UserItemDetail 商品详情
func (s *ExchangeService) UserItemDetail(itemId string) (plant.ExchangeItem, error) {
	var item plant.ExchangeItem
	err := global.DB.Preload("Image").Where("id = ? AND status = 1", itemId).First(&item).Error
	return item, err
}

// UserExchange 用户发起兑换
func (s *ExchangeService) UserExchange(req plantReq.ExchangeReq, userId string) error {
	if req.Quantity <= 0 {
		req.Quantity = 1
	}

	return global.DB.Transaction(func(tx *gorm.DB) error {
		// 1. 查询并锁定商品
		var item plant.ExchangeItem
		if err := tx.Set("gorm:query_option", "FOR UPDATE").
			Where("id = ? AND status = 1", req.ItemId).First(&item).Error; err != nil {
			if errors.Is(err, gorm.ErrRecordNotFound) {
				return errors.New("商品不存在或已下架")
			}
			return err
		}

		// 2. 检查有效期
		now := time.Now()
		if item.StartTime != nil && now.Before(*item.StartTime) {
			return errors.New("兑换尚未开始")
		}
		if item.EndTime != nil && now.After(*item.EndTime) {
			return errors.New("兑换已结束")
		}

		// 3. 检查库存
		if item.Stock >= 0 && item.Stock < req.Quantity {
			return errors.New("库存不足")
		}

		// 4. 检查每人限兑
		if item.LimitPerUser > 0 {
			var count int64
			tx.Model(&plant.ExchangeOrder{}).Where("user_id = ? AND item_id = ? AND status != ?",
				userId, req.ItemId, plant.OrderStatusCancelled).Count(&count)
			if int(count)+req.Quantity > item.LimitPerUser {
				return errors.New("已达到兑换上限")
			}
		}

		// 5. 计算总消耗
		totalCost := item.CostSunlight * int64(req.Quantity)

		// 6. 扣减阳光值
		result := tx.Model(&plant.UserProfile{}).
			Where("user_id = ? AND current_sunlight >= ?", userId, totalCost).
			Update("current_sunlight", gorm.Expr("current_sunlight - ?", totalCost))
		if result.Error != nil {
			return result.Error
		}
		if result.RowsAffected == 0 {
			return errors.New("阳光值不足")
		}

		// 7. 扣减库存
		if item.Stock >= 0 {
			if err := tx.Model(&plant.ExchangeItem{}).Where("id = ? AND stock >= ?", item.Id, req.Quantity).
				Update("stock", gorm.Expr("stock - ?", req.Quantity)).Error; err != nil {
				return err
			}
		}

		// 8. 创建订单
		order := plant.ExchangeOrder{
			UserId:        userId,
			ItemId:        item.Id,
			ItemName:      item.Name,
			CostSunlight:  totalCost,
			Quantity:      req.Quantity,
			Status:        plant.OrderStatusPending,
			ItemType:      item.Type,
			RecipientName: req.RecipientName,
			Phone:         req.Phone,
			Address:       req.Address,
		}

		// 虚拟商品自动完成
		if item.Type == "VIRTUAL" {
			order.Status = plant.OrderStatusCompleted
			now := time.Now()
			order.CompletedAt = &now
		}

		return tx.Create(&order).Error
	})
}

// UserOrderList 用户订单列表
func (s *ExchangeService) UserOrderList(req plantReq.ExchangeOrderListReq, userId string) (list []plant.ExchangeOrder, total int64, err error) {
	db := global.DB.Model(&plant.ExchangeOrder{}).Preload("Item", func(db *gorm.DB) *gorm.DB {
		return db.Preload("Image")
	}).Where("user_id = ?", userId)
	if req.Status != 0 {
		db = db.Where("status = ?", req.Status)
	}
	err = db.Count(&total).Error
	if err != nil {
		return
	}
	err = db.Scopes(req.Paginate()).Order("created_at desc").Find(&list).Error
	return
}
