package asset_wallet

import (
	"context"

	"github.com/break/junhong_cmp_fiber/internal/model/dto"
	"github.com/break/junhong_cmp_fiber/internal/store/postgres"
	"github.com/break/junhong_cmp_fiber/pkg/constants"
	"github.com/break/junhong_cmp_fiber/pkg/errors"
	"gorm.io/gorm"
)

// Service 资产钱包业务服务
// 负责管理端资产（卡/设备）钱包概况查询和流水列表查询
type Service struct {
	assetWalletStore            *postgres.AssetWalletStore
	assetWalletTransactionStore *postgres.AssetWalletTransactionStore
}

// New 创建资产钱包服务实例
func New(assetWalletStore *postgres.AssetWalletStore, assetWalletTransactionStore *postgres.AssetWalletTransactionStore) *Service {
	return &Service{
		assetWalletStore:            assetWalletStore,
		assetWalletTransactionStore: assetWalletTransactionStore,
	}
}

// GetWallet 查询资产钱包概况
// assetType 为 card 或 device，映射到 resourceType = iot_card 或 device
func (s *Service) GetWallet(ctx context.Context, assetType string, assetID uint) (*dto.AssetWalletResponse, error) {
	resourceType, err := mapAssetTypeToResourceType(assetType)
	if err != nil {
		return nil, err
	}

	wallet, err := s.assetWalletStore.GetByResourceTypeAndID(ctx, resourceType, assetID)
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			// 暂无钱包记录属于正常业务状态（企业卡/未充值资产），返回 nil 而非错误
			return nil, nil
		}
		return nil, errors.Wrap(errors.CodeDatabaseError, err, "查询钱包失败")
	}

	statusText := walletStatusText(wallet.Status)

	return &dto.AssetWalletResponse{
		WalletID:         wallet.ID,
		ResourceType:     wallet.ResourceType,
		ResourceID:       wallet.ResourceID,
		Balance:          wallet.Balance,
		FrozenBalance:    wallet.FrozenBalance,
		AvailableBalance: wallet.Balance - wallet.FrozenBalance,
		Currency:         wallet.Currency,
		Status:           wallet.Status,
		StatusText:       statusText,
		CreatedAt:        wallet.CreatedAt,
		UpdatedAt:        wallet.UpdatedAt,
	}, nil
}

// ListTransactions 查询资产钱包流水列表（分页）
func (s *Service) ListTransactions(ctx context.Context, assetType string, assetID uint, req *dto.AssetWalletTransactionListRequest) (*dto.AssetWalletTransactionListResponse, error) {
	resourceType, err := mapAssetTypeToResourceType(assetType)
	if err != nil {
		return nil, err
	}

	page := req.Page
	if page < 1 {
		page = 1
	}
	pageSize := req.PageSize
	if pageSize < 1 {
		pageSize = 20
	}
	if pageSize > 100 {
		pageSize = 100
	}
	offset := (page - 1) * pageSize

	transactions, err := s.assetWalletTransactionStore.ListByResourceIDWithFilter(
		ctx, resourceType, assetID, req.TransactionType, req.StartTime, req.EndTime, offset, pageSize,
	)
	if err != nil {
		return nil, errors.Wrap(errors.CodeDatabaseError, err, "查询流水列表失败")
	}

	total, err := s.assetWalletTransactionStore.CountByResourceIDWithFilter(
		ctx, resourceType, assetID, req.TransactionType, req.StartTime, req.EndTime,
	)
	if err != nil {
		return nil, errors.Wrap(errors.CodeDatabaseError, err, "统计流水数量失败")
	}

	list := make([]*dto.AssetWalletTransactionItem, 0, len(transactions))
	for _, tx := range transactions {
		list = append(list, &dto.AssetWalletTransactionItem{
			ID:                  tx.ID,
			TransactionType:     tx.TransactionType,
			TransactionTypeText: transactionTypeText(tx.TransactionType),
			Amount:              tx.Amount,
			BalanceBefore:       tx.BalanceBefore,
			BalanceAfter:        tx.BalanceAfter,
			ReferenceType:       tx.ReferenceType,
			ReferenceNo:         tx.ReferenceNo,
			Remark:              tx.Remark,
			CreatedAt:           tx.CreatedAt,
		})
	}

	return &dto.AssetWalletTransactionListResponse{
		List:     list,
		Total:    total,
		Page:     page,
		PageSize: pageSize,
	}, nil
}

// mapAssetTypeToResourceType 将路由参数 assetType（card/device）映射到数据库资源类型
func mapAssetTypeToResourceType(assetType string) (string, error) {
	switch assetType {
	case "card":
		return "iot_card", nil
	case "device":
		return "device", nil
	default:
		return "", errors.New(errors.CodeInvalidParam, "无效的资产类型，仅支持 card 或 device")
	}
}

// walletStatusText 翻译钱包状态文本
func walletStatusText(status int) string {
	switch status {
	case 1:
		return "正常"
	case 2:
		return "冻结"
	case 3:
		return "关闭"
	default:
		return "未知"
	}
}

// transactionTypeText 翻译交易类型文本
func transactionTypeText(transactionType string) string {
	switch transactionType {
	case constants.AssetTransactionTypeRecharge:
		return "充值"
	case constants.AssetTransactionTypeDeduct:
		return "扣款"
	case constants.AssetTransactionTypeRefund:
		return "退款"
	case constants.AssetTransactionTypeExchange:
		return "换货迁移"
	default:
		return transactionType
	}
}
