package payment

import "errors"

var (
	ErrDependencyUnavailable  = errors.New("dependency unavailable")
	ErrPaymentUnavailable     = errors.New("payment unavailable")
	ErrPaymentCannotStart     = errors.New("payment cannot start")
	ErrPaymentVerifyFailed    = errors.New("payment verify failed")
	ErrPaymentNotFound        = errors.New("payment not found")
	ErrRefundCannotStart      = errors.New("refund cannot start")
	ErrWalletRechargeDisabled = errors.New("wallet recharge disabled")
)

const MinWalletRechargeAmount = 0.01

type Service struct {
	repo *Repository
}

func NewService(repo *Repository) *Service {
	return &Service{repo: repo}
}

func (s *Service) Start(userID uint64, orderID uint64, req StartPaymentRequest, clientIP string) (*PaymentDTO, error) {
	if s.repo == nil {
		return nil, ErrDependencyUnavailable
	}
	if userID == 0 || orderID == 0 {
		return nil, ErrPaymentCannotStart
	}
	return s.repo.Start(userID, orderID, req, clientIP)
}

func (s *Service) Query(userID uint64, orderID uint64) (*PaymentDTO, error) {
	if s.repo == nil {
		return nil, ErrDependencyUnavailable
	}
	if userID == 0 || orderID == 0 {
		return nil, ErrPaymentNotFound
	}
	return s.repo.Query(userID, orderID)
}

func (s *Service) StartWalletRecharge(userID uint64, req WalletRechargePaymentRequest, clientIP string) (*PaymentDTO, error) {
	if s.repo == nil {
		return nil, ErrDependencyUnavailable
	}
	return nil, ErrWalletRechargeDisabled
}

func (s *Service) QueryWalletRecharge(userID uint64, paymentID uint64) (*PaymentDTO, error) {
	if s.repo == nil {
		return nil, ErrDependencyUnavailable
	}
	if userID == 0 || paymentID == 0 {
		return nil, ErrPaymentNotFound
	}
	return s.repo.QueryWalletRecharge(userID, paymentID)
}

func (s *Service) HandleLeshuaNotify(params map[string]string, rawPayload string, contentType string) (*NotifyResult, error) {
	if s.repo == nil {
		return nil, ErrDependencyUnavailable
	}
	return s.repo.HandleLeshuaNotify(params, rawPayload, contentType)
}

func (s *Service) StartRefund(orderID uint64, refundAmountCent int64, bizType string, remark string) (*RefundDTO, error) {
	if s.repo == nil {
		return nil, ErrDependencyUnavailable
	}
	if orderID == 0 || refundAmountCent <= 0 {
		return nil, ErrRefundCannotStart
	}
	return s.repo.StartRefund(orderID, refundAmountCent, bizType, remark)
}

func (s *Service) QueryRefundStatus(orderID uint64) (*RefundDTO, error) {
	if s.repo == nil {
		return nil, ErrDependencyUnavailable
	}
	if orderID == 0 {
		return nil, ErrPaymentNotFound
	}
	return s.repo.QueryRefundStatus(orderID)
}
