package sms

import (
	"context"
	"fmt"
	"strings"

	"bookra/apps/backend/internal/config"
	"bookra/apps/backend/internal/db"

	"github.com/stripe/stripe-go/v81"
	"github.com/stripe/stripe-go/v81/invoiceitem"
)

type BillingService struct {
	cfg         config.Config
	repo        db.Repository
	smsPriceIDs map[string]string // currency -> price ID
}

func NewBillingService(cfg config.Config, repo db.Repository) *BillingService {
	return &BillingService{
		cfg:         cfg,
		repo:        repo,
		smsPriceIDs: cfg.StripeSMSPriceMatrix,
	}
}

// PriceIDForCurrency returns the Stripe price ID for SMS in the given currency
func (b *BillingService) PriceIDForCurrency(currency string) string {
	c := strings.ToLower(strings.TrimSpace(currency))
	if c == "" {
		c = "czk"
	}
	if id := b.smsPriceIDs[c]; id != "" {
		return id
	}
	// Fallback to CZK
	return b.smsPriceIDs["czk"]
}

// CreateMonthlyInvoiceItem creates a Stripe InvoiceItem for the total SMS usage of a month.
// This adds a line item to the customer's next invoice — charging all messages together.
func (b *BillingService) CreateMonthlyInvoiceItem(ctx context.Context, customerID string, currency string, yearMonth string, messageCount int, totalCents int) (string, error) {
	if customerID == "" {
		return "", fmt.Errorf("customer id is empty")
	}

	priceID := b.PriceIDForCurrency(currency)
	c := strings.ToLower(strings.TrimSpace(currency))
	if c == "" {
		c = "czk"
	}

	// If a Stripe price is configured, use Price + Quantity for a clean invoice line
	if priceID != "" {
		item, err := invoiceitem.New(&stripe.InvoiceItemParams{
			Customer:    stripe.String(customerID),
			Price:       stripe.String(priceID),
			Quantity:    stripe.Int64(int64(messageCount)),
			Description: stripe.String(fmt.Sprintf("SMS Messages (%s) — %d messages", yearMonth, messageCount)),
		})
		if err != nil {
			return "", fmt.Errorf("failed to create invoice item: %w", err)
		}
		return item.ID, nil
	}

	// Fallback: explicit amount (for dev/testing when no price configured yet)
	item, err := invoiceitem.New(&stripe.InvoiceItemParams{
		Customer:    stripe.String(customerID),
		Amount:      stripe.Int64(int64(totalCents)),
		Currency:    stripe.String(c),
		Description: stripe.String(fmt.Sprintf("SMS Messages (%s) — %d messages", yearMonth, messageCount)),
	})
	if err != nil {
		return "", fmt.Errorf("failed to create invoice item: %w", err)
	}
	return item.ID, nil
}
