<?php

namespace App\Domains\Billing\Actions;

use App\Domains\Billing\Models\Subscription;
use App\Domains\Billing\Models\TenantBillingInvoice;
use App\Support\PlatformSettings;
use Illuminate\Support\Facades\DB;

class ActivateTenantPlanFromInvoiceAction
{
    public function __construct(
        protected SyncTenantLifecycleAction $syncTenantLifecycle,
    ) {
    }

    public function execute(TenantBillingInvoice $invoice): Subscription
    {
        if ($invoice->status === 'paid') {
            /** @var Subscription|null $existing */
            $existing = Subscription::query()
                ->where('tenant_id', $invoice->tenant_id)
                ->where('plan_id', $invoice->plan_id)
                ->where('status', 'active')
                ->latest('created_at')
                ->first();

            if ($existing) {
                return $existing;
            }
        }

        return DB::transaction(function () use ($invoice) {
            $tenant = $invoice->tenant()->firstOrFail();

            Subscription::query()
                ->where('tenant_id', $tenant->getKey())
                ->whereIn('status', ['trial', 'active', 'paid', 'succeeded'])
                ->update([
                    'status' => 'cancelled',
                    'cancelled_at' => now(),
                    'ends_at' => now(),
                ]);

            $subscription = Subscription::query()->create([
                'tenant_id' => $tenant->getKey(),
                'plan_id' => $invoice->plan_id,
                'provider' => $invoice->provider?->provider_key ?? PlatformSettings::get('PAYMENT_DEFAULT_PROVIDER', config('payments.default_provider', 'manual')),
                'external_subscription_id' => $invoice->external_reference,
                'status' => 'active',
                'starts_at' => now(),
                'ends_at' => $invoice->billing_cycle === 'yearly' ? now()->addYear() : now()->addMonth(),
                'trial_ends_at' => null,
                'cancelled_at' => null,
            ]);

            $tenant->update([
                'plan_id' => $invoice->plan_id,
                'status' => 'active',
                'trial_ends_at' => null,
            ]);

            $invoice->update([
                'status' => 'paid',
                'paid_at' => now(),
            ]);

            $this->syncTenantLifecycle->execute($tenant->fresh());

            return $subscription;
        });
    }
}
