<?php

declare(strict_types=1);

namespace App\Listeners;

use App\Events\SubscriptionCancelled;
use App\Notifications\SubscriptionCancelledNotification;
use App\Services\Provisioning\ProvisioningFactory;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Support\Facades\Log;

class HandleSubscriptionCancelled implements ShouldQueue
{
    public $tries = 3;

    public $backoff = [60, 120, 300];

    public function __construct(
        private ProvisioningFactory $provisioningFactory,
    ) {}

    public function handle(SubscriptionCancelled $event): void
    {
        Log::info("Subscription cancelled for user #{$event->user->id}", [
            'subscription_id' => $event->subscription->id,
            'type' => $event->subscription->type,
        ]);

        // Terminate associated services (VirtFusion handles delay)
        $services = $event->user->services()
            ->where('subscription_id', $event->subscription->id)
            ->whereIn('status', ['active', 'suspended'])
            ->get();

        foreach ($services as $service) {
            try {
                $planId = $event->subscription->plan_id;
                if ($planId) {
                    $plan = \App\Models\Plan::find($planId);

                    if ($plan) {
                        $provisioner = $this->provisioningFactory->make($plan->service_type);
                        $provisioner->terminate($service);

                        Log::info('Service terminated successfully', [
                            'service_id' => $service->id,
                            'subscription_id' => $event->subscription->id,
                        ]);
                    }
                }
            } catch (\Exception $e) {
                Log::error('Service termination exception', [
                    'service_id' => $service->id,
                    'subscription_id' => $event->subscription->id,
                    'error' => $e->getMessage(),
                ]);
            }
        }

        $event->user->notify(new SubscriptionCancelledNotification($event->subscription));
    }
}
