package wallet

import (
	"context"
	"hyapp/pkg/appcode"
	"hyapp/pkg/xerr"
	"hyapp/services/wallet-service/internal/domain/ledger"
	"strings"
)

// HandleMifapayNotify 只在验签、订单号、币种和金额全部匹配后更新订单；正式订单入账，临时订单只标记 paid。
func (s *Service) HandleMifapayNotify(ctx context.Context, appCode string, notification ledger.MifaPayNotification) (ledger.ExternalRechargeOrder, bool, error) {
	if s.mifaPay == nil {
		return ledger.ExternalRechargeOrder{}, false, xerr.New(xerr.Unavailable, "mifapay client is not configured")
	}
	if s.repository == nil {
		return ledger.ExternalRechargeOrder{}, false, xerr.New(xerr.Unavailable, "wallet repository is not configured")
	}
	ctx = appcode.WithContext(ctx, appcode.Normalize(appCode))
	data, err := s.mifaPay.ParseNotification(notification)
	if err != nil {
		return ledger.ExternalRechargeOrder{}, false, err
	}
	order, err := s.repository.GetExternalRechargeOrder(ctx, appcode.FromContext(ctx), data.OrderID)
	if err != nil {
		return ledger.ExternalRechargeOrder{}, false, err
	}
	if !strings.EqualFold(data.OrderStatus, "SUCCESS") {
		order, err = s.repository.MarkExternalRechargeOrderFailed(ctx, order.AppCode, order.OrderID, "mifapay order status "+data.OrderStatus, data.RawJSON)
		return order, true, err
	}
	if !mifaPayNotifyMatchesOrder(data, order) {
		order, err = s.repository.MarkExternalRechargeOrderFailed(ctx, order.AppCode, order.OrderID, "mifapay callback amount or currency mismatch", data.RawJSON)
		return order, false, err
	}
	if isTemporaryExternalRechargeOrder(order) {
		paid, err := s.repository.MarkExternalRechargeOrderPaid(ctx, order.AppCode, order.OrderID, data.ProviderOrderID, data.RawJSON)
		return paid, err == nil, err
	}
	credited, err := s.repository.CreditExternalRechargeOrder(ctx, order.AppCode, order.OrderID, data.ProviderOrderID, "", data.RawJSON)
	return credited, err == nil, err
}

// HandleV5PayNotify 只在验签、订单号、币种、金额和 productType 全部匹配后更新订单；正式订单入账，临时订单只标记 paid。
func (s *Service) HandleV5PayNotify(ctx context.Context, appCode string, notification ledger.V5PayNotification) (ledger.ExternalRechargeOrder, bool, error) {
	if s.v5Pay == nil {
		return ledger.ExternalRechargeOrder{}, false, xerr.New(xerr.Unavailable, "v5pay client is not configured")
	}
	if s.repository == nil {
		return ledger.ExternalRechargeOrder{}, false, xerr.New(xerr.Unavailable, "wallet repository is not configured")
	}
	ctx = appcode.WithContext(ctx, appcode.Normalize(appCode))
	data, err := s.v5Pay.ParseNotification(notification)
	if err != nil {
		return ledger.ExternalRechargeOrder{}, false, err
	}
	order, err := s.repository.GetExternalRechargeOrder(ctx, appcode.FromContext(ctx), data.OrderID)
	if err != nil {
		return ledger.ExternalRechargeOrder{}, false, err
	}
	switch strings.TrimSpace(data.OrderStatus) {
	case "2":
		if !v5PayOrderDataMatchesOrder(data, order) {
			order, err = s.repository.MarkExternalRechargeOrderFailed(ctx, order.AppCode, order.OrderID, "v5pay callback amount currency or product mismatch", data.RawJSON)
			return order, false, err
		}
		if isTemporaryExternalRechargeOrder(order) {
			paid, err := s.repository.MarkExternalRechargeOrderPaid(ctx, order.AppCode, order.OrderID, data.ProviderOrderID, data.RawJSON)
			return paid, err == nil, err
		}
		credited, err := s.repository.CreditExternalRechargeOrder(ctx, order.AppCode, order.OrderID, data.ProviderOrderID, "", data.RawJSON)
		return credited, err == nil, err
	case "3", "5", "6":
		order, err = s.repository.MarkExternalRechargeOrderFailed(ctx, order.AppCode, order.OrderID, "v5pay order status "+data.OrderStatus, data.RawJSON)
		return order, true, err
	default:
		return order, true, nil
	}
}
