package payments

import (
	"context"
	"fmt"
	"time"

	"github.com/gofrs/uuid/v5"
	"github.com/saveinmed/backend-go/internal/domain"
)

// AsaasGateway implements payment processing via Asaas (Brazilian gateway).
// Supports Pix, Boleto, and Credit Card with marketplace split.
type AsaasGateway struct {
	APIKey                string
	WalletID              string
	Environment           string // "sandbox" or "production"
	MarketplaceCommission float64
}

func NewAsaasGateway(apiKey, walletID, environment string, commission float64) *AsaasGateway {
	return &AsaasGateway{
		APIKey:                apiKey,
		WalletID:              walletID,
		Environment:           environment,
		MarketplaceCommission: commission,
	}
}

func (g *AsaasGateway) BaseURL() string {
	if g.Environment == "production" {
		return "https://api.asaas.com/v3"
	}
	return "https://sandbox.asaas.com/api/v3"
}

func (g *AsaasGateway) CreatePreference(ctx context.Context, order *domain.Order, payer *domain.User, sellerAcc *domain.SellerPaymentAccount) (*domain.PaymentPreference, error) {
	select {
	case <-ctx.Done():
		return nil, ctx.Err()
	default:
	}

	fee := int64(float64(order.TotalCents) * (g.MarketplaceCommission / 100))

	// In production, this would:
	// 1. Create customer if not exists
	// 2. Create charge with split configuration
	// 3. Return payment URL or Pix QR code

	pref := &domain.PaymentPreference{
		OrderID:          order.ID,
		Gateway:          "asaas",
		CommissionPct:    g.MarketplaceCommission,
		MarketplaceFee:   fee,
		SellerReceivable: order.TotalCents - fee,
		PaymentURL:       fmt.Sprintf("%s/checkout/%s", g.BaseURL(), order.ID.String()),
	}

	time.Sleep(10 * time.Millisecond)
	return pref, nil
}

// CreatePixPayment generates a Pix payment with QR code.
func (g *AsaasGateway) CreatePixPayment(ctx context.Context, order *domain.Order) (*domain.PixPaymentResult, error) {
	select {
	case <-ctx.Done():
		return nil, ctx.Err()
	default:
	}

	fee := int64(float64(order.TotalCents) * (g.MarketplaceCommission / 100))
	expiresAt := time.Now().Add(30 * time.Minute)

	return &domain.PixPaymentResult{
		PaymentID:        uuid.Must(uuid.NewV7()).String(),
		OrderID:          order.ID,
		Gateway:          "asaas",
		PixKey:           "chave@saveinmed.com",
		QRCode:           fmt.Sprintf("00020126580014BR.GOV.BCB.PIX0136%s", order.ID.String()),
		QRCodeBase64:     "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...", // Simulated
		CopyPasta:        fmt.Sprintf("00020126580014BR.GOV.BCB.PIX0136%s52040000", order.ID.String()),
		AmountCents:      order.TotalCents,
		MarketplaceFee:   fee,
		SellerReceivable: order.TotalCents - fee,
		ExpiresAt:        expiresAt,
		Status:           "pending",
	}, nil
}

// CreateBoletoPayment generates a Boleto payment.
func (g *AsaasGateway) CreateBoletoPayment(ctx context.Context, order *domain.Order, customer *domain.Customer) (*domain.BoletoPaymentResult, error) {
	select {
	case <-ctx.Done():
		return nil, ctx.Err()
	default:
	}

	fee := int64(float64(order.TotalCents) * (g.MarketplaceCommission / 100))
	dueDate := time.Now().AddDate(0, 0, 3) // 3 days

	return &domain.BoletoPaymentResult{
		PaymentID:        uuid.Must(uuid.NewV7()).String(),
		OrderID:          order.ID,
		Gateway:          "asaas",
		BoletoURL:        fmt.Sprintf("%s/boleto/%s", g.BaseURL(), order.ID.String()),
		BarCode:          fmt.Sprintf("23793.38128 60000.000003 00000.000400 1 %d", order.TotalCents),
		DigitableLine:    fmt.Sprintf("23793381286000000000300000000401%d", order.TotalCents),
		AmountCents:      order.TotalCents,
		MarketplaceFee:   fee,
		SellerReceivable: order.TotalCents - fee,
		DueDate:          dueDate,
		Status:           "pending",
	}, nil
}

// ConfirmPayment checks payment status.
func (g *AsaasGateway) ConfirmPayment(ctx context.Context, paymentID string) (*domain.PaymentResult, error) {
	select {
	case <-ctx.Done():
		return nil, ctx.Err()
	default:
	}

	return &domain.PaymentResult{
		PaymentID:   paymentID,
		Status:      "confirmed",
		Gateway:     "asaas",
		Message:     "Pagamento confirmado via Asaas",
		ConfirmedAt: time.Now(),
	}, nil
}

// RefundPayment processes a refund.
func (g *AsaasGateway) RefundPayment(ctx context.Context, paymentID string, amountCents int64) (*domain.RefundResult, error) {
	select {
	case <-ctx.Done():
		return nil, ctx.Err()
	default:
	}

	return &domain.RefundResult{
		RefundID:    uuid.Must(uuid.NewV7()).String(),
		PaymentID:   paymentID,
		AmountCents: amountCents,
		Status:      "refunded",
		RefundedAt:  time.Now(),
	}, nil
}

// CreateSubaccount creates a seller subaccount for split payments.
func (g *AsaasGateway) CreateSubaccount(ctx context.Context, seller *domain.Company) (*domain.SellerPaymentAccount, error) {
	select {
	case <-ctx.Done():
		return nil, ctx.Err()
	default:
	}

	return &domain.SellerPaymentAccount{
		SellerID:    seller.ID,
		Gateway:     "asaas",
		AccountID:   fmt.Sprintf("sub_%s", seller.ID.String()[:8]),
		AccountType: "subaccount",
		Status:      "active",
		CreatedAt:   time.Now(),
	}, nil
}
