package walletapi

import (
	"context"
	"io"
	"net/http"

	"hyapp/pkg/tencentim"
	"hyapp/services/gateway-service/internal/client"
	"hyapp/services/gateway-service/internal/financewithdrawal"
	"hyapp/services/gateway-service/internal/transport/http/httproutes"
)

// Handler owns wallet-facing HTTP endpoints.
// It keeps wallet semantics behind wallet-service and only handles HTTP protocol conversion.
type Handler struct {
	walletClient       client.WalletClient
	roomGuardClient    client.RoomGuardClient
	roomQueryClient    client.RoomQueryClient
	userIdentityClient client.UserIdentityClient
	userProfileClient  client.UserProfileClient
	userHostClient     client.UserHostClient
	broadcastClient    client.BroadcastClient
	imAccountImporter  TencentIMAccountImporter
	imPublisher        TencentIMUserMessagePublisher
	imGroupIDPrefix    string
	objectUploader     ObjectUploader
	withdrawalWriter   financewithdrawal.Writer
	withdrawalNotifier financewithdrawal.Notifier
}

// TencentIMAccountImporter 只负责把 app 内部 user_id 补偿导入腾讯 IM 账号体系。
type TencentIMAccountImporter interface {
	ImportAccount(ctx context.Context, userID int64, nickname string, faceURL string) error
}

// TencentIMUserMessagePublisher 只暴露服务端 C2C custom message 投递能力。
type TencentIMUserMessagePublisher interface {
	PublishUserCustomMessage(ctx context.Context, message tencentim.CustomUserMessage) error
}

// ObjectUploader 是临时支付链接包装 app scheme 时依赖的对象存储能力。
type ObjectUploader interface {
	PutObject(ctx context.Context, key string, reader io.Reader, sizeBytes int64, contentType string) (string, error)
}

type Config struct {
	WalletClient       client.WalletClient
	RoomGuardClient    client.RoomGuardClient
	RoomQueryClient    client.RoomQueryClient
	UserIdentityClient client.UserIdentityClient
	UserProfileClient  client.UserProfileClient
	UserHostClient     client.UserHostClient
	BroadcastClient    client.BroadcastClient
	IMAccountImporter  TencentIMAccountImporter
	IMPublisher        TencentIMUserMessagePublisher
	IMGroupIDPrefix    string
	ObjectUploader     ObjectUploader
	WithdrawalWriter   financewithdrawal.Writer
	WithdrawalNotifier financewithdrawal.Notifier
}

func New(config Config) *Handler {
	return &Handler{
		walletClient:       config.WalletClient,
		roomGuardClient:    config.RoomGuardClient,
		roomQueryClient:    config.RoomQueryClient,
		userIdentityClient: config.UserIdentityClient,
		userProfileClient:  config.UserProfileClient,
		userHostClient:     config.UserHostClient,
		broadcastClient:    config.BroadcastClient,
		imAccountImporter:  config.IMAccountImporter,
		imPublisher:        config.IMPublisher,
		imGroupIDPrefix:    config.IMGroupIDPrefix,
		objectUploader:     config.ObjectUploader,
		withdrawalWriter:   config.WithdrawalWriter,
		withdrawalNotifier: config.WithdrawalNotifier,
	}
}

func (h *Handler) WalletHandlers() httproutes.WalletHandlers {
	return httproutes.WalletHandlers{
		GetWalletOverview:                 h.getWalletOverview,
		GetMyBalances:                     h.getMyBalances,
		ListRechargeProducts:              h.listRechargeProducts,
		GetH5RechargeContext:              h.getH5RechargeContext,
		ListH5RechargeOptions:             h.listH5RechargeOptions,
		CreateH5RechargeOrder:             h.createH5RechargeOrder,
		ListTemporaryPayMethods:           h.listTemporaryPayMethods,
		CreateTemporaryPayLink:            h.createTemporaryPayLink,
		GetTemporaryPayLink:               h.getTemporaryPayLink,
		ListTemporaryPayLinks:             h.listTemporaryPayLinks,
		SubmitH5RechargeTx:                h.submitH5RechargeTx,
		GetH5RechargeOrder:                h.getH5RechargeOrder,
		HandleMifapayNotify:               h.handleMifapayNotify,
		HandleV5PayNotify:                 h.handleV5PayNotify,
		ConfirmGooglePayment:              h.confirmGooglePayment,
		GetDiamondExchangeConfig:          h.getDiamondExchangeConfig,
		ListCoinTransactions:              h.listCoinTransactions,
		ListWalletTransactions:            h.listWalletTransactions,
		ListDiamondTransactions:           h.listDiamondTransactions,
		ListCoinSellers:                   h.listCoinSellers,
		TransferCoinFromSeller:            h.transferCoinFromSeller,
		GetCoinSellerSubSellerPermission:  h.getCoinSellerSubSellerPermission,
		InviteCoinSellerSubSeller:         h.inviteCoinSellerSubSeller,
		ListCoinSellerSubSellers:          h.listCoinSellerSubSellers,
		TransferCoinSellerToSubSeller:     h.transferCoinSellerToSubSeller,
		GetCoinSellerOverview:             h.getCoinSellerOverview,
		CreateSubCoinSeller:               h.createSubCoinSeller,
		ListSubCoinSellers:                h.listSubCoinSellers,
		TransferCoinSellerStockToChild:    h.transferCoinSellerStockToChild,
		SendDirectGift:                    h.sendDirectGift,
		GetSalaryWalletOverview:           h.getSalaryWalletOverview,
		GetSalaryWalletHistory:            h.getSalaryWalletHistory,
		SearchSalaryWalletSeller:          h.searchSalaryWalletSeller,
		ExchangeSalaryToCoin:              h.exchangeSalaryToCoin,
		TransferSalaryToSeller:            h.transferSalaryToCoinSeller,
		HandleSalaryWalletWithdrawAddress: h.handleSalaryWalletWithdrawAddress,
		WithdrawSalaryWallet:              h.withdrawSalaryWallet,
		GetPointWalletOverview:            h.getPointWalletOverview,
		GetPointWalletExchangeConfig:      h.getPointWalletExchangeConfig,
		WithdrawPointWallet:               h.withdrawPointWallet,
		TransferPointWalletToCoinSeller:   h.transferPointWalletToCoinSeller,
		ExchangePointWalletToCoins:        h.exchangePointWalletToCoins,
		GetPointDiamondWalletOverview:     h.getPointDiamondWalletOverview,
		GetPointDiamondWalletHistory:      h.getPointDiamondWalletHistory,
		ExchangePointDiamondWalletToCoins: h.exchangePointDiamondWalletToCoins,
		WithdrawPointDiamondWallet:        h.withdrawPointDiamondWallet,
		TransferPointDiamondToCoinSeller:  h.transferPointDiamondWalletToCoinSeller,
		HandlePointDiamondWithdrawAddress: h.handleSalaryWalletWithdrawAddress,
		GetRedPacketConfig:                h.getRedPacketConfig,
		ListRoomRedPackets:                h.listRoomRedPackets,
		CreateRoomRedPacket:               h.createRoomRedPacket,
		GetRedPacket:                      h.getRedPacket,
		ClaimRedPacket:                    h.claimRedPacket,
		GetCurrentRegionIMGroup:           h.getCurrentRegionIMGroup,
		GetRedPacketIMGroup:               h.getCurrentRegionIMGroup,
		SendVoiceRoomRedPacket:            h.sendVoiceRoomRedPacket,
		ListActiveRedPackets:              h.listActiveRedPackets,
		ClaimVoiceRoomRedPacket:           h.claimVoiceRoomRedPacket,
		GetVoiceRoomRedPacket:             h.getVoiceRoomRedPacket,
		ListRedPacketClaims:               h.listRedPacketClaims,
		ListSentRedPackets:                h.listSentRedPackets,
	}
}

func (h *Handler) VIPHandlers() httproutes.VIPHandlers {
	return httproutes.VIPHandlers{
		GetMyVIP:               h.getMyVIP,
		ListVIPPackages:        h.listVIPPackages,
		PurchaseVIP:            h.purchaseVIP,
		EquipVIPTrialCard:      h.equipVIPTrialCard,
		UnequipVIPTrialCard:    h.unequipVIPTrialCard,
		TriggerOnlineNotice:    h.triggerVIPOnlineNotice,
		HandleVIPSettings:      h.handleVIPSettings,
		GetCurrentCoinRebate:   h.getCurrentVIPCoinRebate,
		ListCoinRebateStatuses: h.listVIPCoinRebateStatuses,
		ClaimCoinRebate:        h.claimVIPCoinRebate,
	}
}

func (h *Handler) GetMyGiftWall(writer http.ResponseWriter, request *http.Request) {
	h.getMyGiftWall(writer, request)
}

func (h *Handler) GetUserGiftWall(writer http.ResponseWriter, request *http.Request) {
	h.getUserGiftWall(writer, request)
}
