<?php

declare(strict_types=1);

namespace App\Http\Controllers\Api\V1;

use App\Events\SubscriptionCancelled;
use App\Http\Controllers\Controller;
use App\Http\Resources\SubscriptionResource;
use App\Services\Billing\BillingServiceFactory;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;

class CustomerSubscriptionController extends Controller
{
    public function __construct(
        private readonly BillingServiceFactory $billingFactory,
    ) {}

    public function index(Request $request): AnonymousResourceCollection
    {
        $subscriptions = $request->user()
            ->subscriptions()
            ->select([
                'subscriptions.*',
                'plans.name as plan_name',
                'plans.price as plan_price',
                'plans.billing_cycle as plan_billing_cycle',
            ])
            ->leftJoin('plans', 'subscriptions.plan_id', '=', 'plans.id')
            ->latest('subscriptions.created_at')
            ->get();

        return SubscriptionResource::collection($subscriptions);
    }

    public function cancel(Request $request, int $subscription): JsonResponse
    {
        $sub = $request->user()
            ->subscriptions()
            ->find($subscription);

        if (! $sub) {
            return response()->json(['message' => 'Subscription not found.'], 404);
        }

        $gateway = $sub->gateway ?? 'stripe';
        $service = $this->billingFactory->make($gateway);

        $gatewayId = $gateway === 'stripe'
            ? $sub->stripe_id
            : $sub->gateway_subscription_id;

        $success = $service->cancelSubscription(
            $request->user(),
            $gatewayId,
            $request->boolean('immediately'),
        );

        if (! $success) {
            return response()->json([
                'message' => 'Failed to cancel subscription. Please try again.',
            ], 500);
        }

        SubscriptionCancelled::dispatch($request->user(), $sub);

        return response()->json([
            'message' => 'Subscription has been cancelled.',
        ]);
    }
}
