package booking

import (
	"context"
	"errors"
	"log/slog"
	"testing"

	"github.com/stripe/stripe-go/v83"

	"github.com/rjNemo/rentease/internal/config"
)

func TestHandleChargeRefundedUpdatesAmount(t *testing.T) {
	store := &mockStore{}
	stripeID := "pi_123"
	status := "succeeded"
	_, _ = store.UpsertStripePayment(&Payment{
		BookingID:       42,
		Amount:          100,
		PaymentMethod:   config.PaymentMethod("Card"),
		StripePaymentID: &stripeID,
		StripeStatus:    &status,
	})

	svc, err := NewService(slog.New(slog.DiscardHandler), store, nil, nil, nil)
	if err != nil {
		t.Fatalf("NewService returned error: %v", err)
	}

	charge := &stripe.Charge{
		ID:             "ch_123",
		Amount:         10000,
		AmountRefunded: 2500,
		PaymentIntent:  &stripe.PaymentIntent{ID: stripeID},
	}

	if err := svc.HandleChargeRefunded(context.Background(), charge); err != nil {
		t.Fatalf("HandleChargeRefunded returned error: %v", err)
	}

	updated, err := store.FindStripePayment(stripeID)
	if err != nil {
		t.Fatalf("expected payment to be present: %v", err)
	}

	if updated.Amount != 75 {
		t.Fatalf("expected amount 75, got %v", updated.Amount)
	}
	if updated.StripeStatus == nil || *updated.StripeStatus != "refunded" {
		t.Fatalf("expected status refunded, got %v", updated.StripeStatus)
	}
}

func TestHandleChargeRefundedUnknownPayment(t *testing.T) {
	store := &mockStore{}
	svc, _ := NewService(slog.New(slog.DiscardHandler), store, nil, nil, nil)

	charge := &stripe.Charge{PaymentIntent: &stripe.PaymentIntent{ID: "pi_missing"}}

	if err := svc.HandleChargeRefunded(context.Background(), charge); err != nil {
		t.Fatalf("expected no error, got %v", err)
	}
}

func TestHandleChargeRefundedStoreError(t *testing.T) {
	store := &mockStore{}
	stripeID := "pi_321"
	status := "succeeded"
	_, _ = store.UpsertStripePayment(&Payment{
		BookingID:       1,
		Amount:          10,
		PaymentMethod:   config.PaymentMethod("Card"),
		StripePaymentID: &stripeID,
		StripeStatus:    &status,
	})
	store.err = errors.New("db error")

	svc, _ := NewService(slog.New(slog.DiscardHandler), store, nil, nil, nil)
	charge := &stripe.Charge{PaymentIntent: &stripe.PaymentIntent{ID: stripeID}}

	if err := svc.HandleChargeRefunded(context.Background(), charge); err == nil {
		t.Fatalf("expected error when store fails")
	}
}
