package cron

import (
	"context"
	"fmt"
	"log/slog"
	"time"

	"github.com/rjNemo/rentease/internal/config"
	"github.com/rjNemo/rentease/internal/driver/database"
	stripeclient "github.com/rjNemo/rentease/internal/driver/stripe"
	"github.com/rjNemo/rentease/internal/repository/booking"
	bookingservice "github.com/rjNemo/rentease/internal/service/booking"
)

// JobStripePaymentSync synchronises Stripe payments for the last 24 hours. It is
// safe to run multiple times thanks to the repository upsert semantics.
func JobStripePaymentSync() error {
	ctx := context.Background()

	cfg, err := config.New(ctx)
	if err != nil {
		return fmt.Errorf("error loading config: %w", err)
	}

	if cfg.StripeSecretKey == "" {
		slog.Default().Warn("stripe secret key missing; skipping stripe sync job")
		return nil
	}

	db, err := database.New(cfg.DatabaseURL)
	if err != nil {
		return fmt.Errorf("error connecting to database: %w", err)
	}

	// Auto-migrate payment schema if necessary.
	if err := database.Migrate(db, &bookingservice.Booking{}, &bookingservice.Item{}, &bookingservice.Payment{}); err != nil {
		return fmt.Errorf("error migrating database: %w", err)
	}

	store := booking.NewPgStore(db)

	opts := []stripeclient.Option{}

	client, err := stripeclient.New(cfg.StripeSecretKey, opts...)
	if err != nil {
		return fmt.Errorf("error creating stripe client: %w", err)
	}

	logger := slog.Default()
	service, err := bookingservice.NewService(logger, store, nil, nil, client)
	if err != nil {
		return fmt.Errorf("error creating booking service: %w", err)
	}

	to := time.Now().UTC()
	from := to.Add(-24 * time.Hour)

	if err := service.SyncStripePayments(ctx, from, to); err != nil {
		return fmt.Errorf("error syncing stripe payments: %w", err)
	}

	slog.Default().Info("stripe payment sync job completed", slog.Time("from", from), slog.Time("to", to))
	return nil
}
