package dto

import (
	"encoding/json"
	"time"
)

type PaymentOrderListRequest struct {
	Page          int    `form:"page"`
	PageSize      int    `form:"pageSize"`
	Provider      string `form:"provider"`
	TradeNo       string `form:"tradeNo"`
	BusinessType  string `form:"businessType"`
	BusinessID    string `form:"businessId"`
	PaymentStatus string `form:"paymentStatus"`
	RefundStatus  string `form:"refundStatus"`
}

type PaymentRequest struct {
	Provider       string         `json:"provider"`
	TradeNo        string         `json:"tradeNo"`
	Subject        string         `json:"subject"`
	Amount         int64          `json:"amount"`
	OriginalAmount int64          `json:"originalAmount"`
	Currency       string         `json:"currency"`
	NotifyURL      string         `json:"notifyUrl"`
	ReturnURL      string         `json:"returnUrl"`
	Extra          map[string]any `json:"extra"`
	ClientIP       string         `json:"-"`
	BusinessType   string         `json:"businessType"`
	BusinessID     string         `json:"businessId"`
	PaymentMode    string         `json:"paymentMode"`
}
type PaymentQueryRequest struct {
	Provider string `json:"provider"`
	TradeNo  string `json:"tradeNo"`
}
type PaymentRefundRequest struct {
	Provider string `json:"provider"`
	TradeNo  string `json:"tradeNo"`
	Amount   int64  `json:"amount"`
}

type PaymentFulfillRequest struct {
	Provider string `json:"provider"`
	TradeNo  string `json:"tradeNo"`
}

// PaymentCallbackRequest is populated by the HTTP transport and converted to
// the biz callback object inside service.
type PaymentCallbackRequest struct {
	Provider string
	Headers  map[string]string
	Body     []byte
	Query    map[string]string
}

type PaymentCallbackAck struct {
	StatusCode  int
	ContentType string
	Body        []byte
}

type PaymentResultResponse struct {
	Provider               string          `json:"provider"`
	Status                 string          `json:"status"`
	TradeNo                string          `json:"tradeNo"`
	ProviderTradeNo        string          `json:"providerTradeNo"`
	Amount                 int64           `json:"amount"`
	PayerPaidAmount        int64           `json:"payerPaidAmount,omitempty"`
	CashPaidAmount         int64           `json:"cashPaidAmount,omitempty"`
	PointPaidAmount        int64           `json:"pointPaidAmount,omitempty"`
	DiscountAmount         int64           `json:"discountAmount,omitempty"`
	ProviderDiscountAmount int64           `json:"providerDiscountAmount,omitempty"`
	MerchantDiscountAmount int64           `json:"merchantDiscountAmount,omitempty"`
	SettlementAmount       int64           `json:"settlementAmount,omitempty"`
	Currency               string          `json:"currency"`
	PayerCurrency          string          `json:"payerCurrency,omitempty"`
	AmountBreakdownKnown   bool            `json:"amountBreakdownKnown"`
	Duplicate              bool            `json:"duplicate"`
	Payload                json.RawMessage `json:"payload"`
	OrderStatus            string          `json:"orderStatus,omitempty"`
	FulfillmentStatus      string          `json:"fulfillmentStatus,omitempty"`
	RefundStatus           string          `json:"refundStatus,omitempty"`
}

type PaymentTestStage struct {
	Name     string `json:"name"`
	Status   string `json:"status"`
	Message  string `json:"message,omitempty"`
	TradeNo  string `json:"tradeNo,omitempty"`
	Duration int64  `json:"durationMs,omitempty"`
}

type PaymentTestResult struct {
	Provider string                 `json:"provider"`
	TradeNo  string                 `json:"tradeNo"`
	Passed   bool                   `json:"passed"`
	FullFlow bool                   `json:"fullFlow"`
	Mode     string                 `json:"mode,omitempty"`
	Stages   []*PaymentTestStage    `json:"stages"`
	Result   *PaymentResultResponse `json:"result,omitempty"`
}

type PaymentOrderResponse struct {
	ID                     uint64     `json:"ID"`
	Provider               string     `json:"provider"`
	TradeNo                string     `json:"tradeNo"`
	ProviderTradeNo        string     `json:"providerTradeNo"`
	BusinessType           string     `json:"businessType"`
	BusinessID             string     `json:"businessId"`
	Subject                string     `json:"subject"`
	PaymentMode            string     `json:"paymentMode"`
	OriginalAmount         int64      `json:"originalAmount"`
	Amount                 int64      `json:"amount"`
	PaidAmount             int64      `json:"paidAmount"`
	PayerPaidAmount        int64      `json:"payerPaidAmount"`
	CashPaidAmount         int64      `json:"cashPaidAmount"`
	PointPaidAmount        int64      `json:"pointPaidAmount"`
	DiscountAmount         int64      `json:"discountAmount"`
	ProviderDiscountAmount int64      `json:"providerDiscountAmount"`
	MerchantDiscountAmount int64      `json:"merchantDiscountAmount"`
	SettlementAmount       int64      `json:"settlementAmount"`
	Currency               string     `json:"currency"`
	PayerCurrency          string     `json:"payerCurrency,omitempty"`
	AmountBreakdownKnown   bool       `json:"amountBreakdownKnown"`
	PaymentStatus          string     `json:"paymentStatus"`
	ProviderStatus         string     `json:"providerStatus"`
	FulfillmentStatus      string     `json:"fulfillmentStatus"`
	RefundStatus           string     `json:"refundStatus"`
	RefundedAmount         int64      `json:"refundedAmount"`
	RefundRequestedAmount  int64      `json:"refundRequestedAmount"`
	RefundNo               string     `json:"refundNo,omitempty"`
	LastError              string     `json:"lastError,omitempty"`
	CreatedAt              time.Time  `json:"createdAt"`
	UpdatedAt              time.Time  `json:"updatedAt"`
	PaidAt                 *time.Time `json:"paidAt,omitempty"`
	FulfilledAt            *time.Time `json:"fulfilledAt,omitempty"`
	RefundedAt             *time.Time `json:"refundedAt,omitempty"`
}
