package user

import (
	"bindbox-game/internal/repository/mysql/dao"
	"context"
	"fmt"
)

// CancelShipping 取消发货申请
// 支持按单个资产ID取消，或按批次号批量取消
// 返回成功取消的记录数
func (s *service) CancelShipping(ctx context.Context, userID int64, inventoryID int64, batchNo string) (int64, error) {
	var cancelledCount int64

	err := s.writeDB.Transaction(func(tx *dao.Query) error {
		var records []*struct {
			ID          int64
			InventoryID int64
		}

		// 根据参数查询待取消的发货记录
		if batchNo != "" {
			// 按批次号查询
			rows, err := tx.ShippingRecords.WithContext(ctx).
				Select(tx.ShippingRecords.ID, tx.ShippingRecords.InventoryID).
				Where(tx.ShippingRecords.BatchNo.Eq(batchNo)).
				Where(tx.ShippingRecords.UserID.Eq(userID)).
				Where(tx.ShippingRecords.Status.Eq(1)). // 待发货状态
				Find()
			if err != nil {
				return fmt.Errorf("query shipping records failed: %w", err)
			}
			for _, r := range rows {
				records = append(records, &struct {
					ID          int64
					InventoryID int64
				}{ID: r.ID, InventoryID: r.InventoryID})
			}
		} else if inventoryID > 0 {
			// 按单个资产ID查询
			sr, err := tx.ShippingRecords.WithContext(ctx).
				Where(tx.ShippingRecords.InventoryID.Eq(inventoryID)).
				Where(tx.ShippingRecords.UserID.Eq(userID)).
				Where(tx.ShippingRecords.Status.Eq(1)).
				First()
			if err != nil {
				return fmt.Errorf("shipping record not found or already processed")
			}
			records = append(records, &struct {
				ID          int64
				InventoryID int64
			}{ID: sr.ID, InventoryID: sr.InventoryID})
		}

		if len(records) == 0 {
			return fmt.Errorf("no pending shipping records found")
		}

		// 批量处理每条记录
		for _, rec := range records {
			// 更新发货记录状态为已取消 (status=5)
			if _, err := tx.ShippingRecords.WithContext(ctx).
				Where(tx.ShippingRecords.ID.Eq(rec.ID)).
				Update(tx.ShippingRecords.Status, 5); err != nil {
				return err
			}

			// 恢复库存状态为可用 (status=1) 并清空 shipping_no
			remark := fmt.Sprintf("|shipping_cancelled_by_user:%d", userID)
			if err := tx.UserInventory.WithContext(ctx).UnderlyingDB().Exec(
				"UPDATE user_inventory SET status=1, shipping_no='', remark=CONCAT(IFNULL(remark,''), ?) WHERE id=? AND user_id=?",
				remark,
				rec.InventoryID,
				userID,
			).Error; err != nil {
				return err
			}

			cancelledCount++
		}

		return nil
	})

	if err != nil {
		return 0, err
	}

	return cancelledCount, nil
}
