<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Http\Requests\StoreServicePlanRequest;
use App\Http\Requests\UpdateServicePlanRequest;
use App\Models\Service;
use App\Models\SharedSubscription;
use App\Models\ServicePlan;
use Illuminate\Support\Facades\DB;

class ServicePlanController extends Controller
{
    public function __construct()
    {
        $this->middleware('permission:view plans', ['only' => ['index', 'show']]);
        $this->middleware('permission:create plans', ['only' => ['create', 'store']]);
        $this->middleware('permission:update plans', ['only' => ['edit', 'update']]);
        $this->middleware('permission:delete plans', ['only' => ['destroy']]);
    }


    public function index()
    {
        $user = auth()->user();
        $isAdminOrSuper = $user->hasAnyRole(['admin', 'super admin']);

        $servicePlans = ServicePlan::query()
            ->with('service')
            ->when(! $isAdminOrSuper, fn ($q) => $q->where('created_by', $user->id))
            ->latest()
            ->paginate(15);

        return view('admin.service-plans.index', compact('servicePlans'));
    }

    public function create()
    {
        $user = auth()->user();
        $isAdminOrSuper = $user->hasAnyRole(['admin', 'super admin']);

        $services = Service::query()
            ->where('is_active', true)
            ->when(! $isAdminOrSuper, fn ($q) => $q->where('created_by', $user->id))
            ->orderBy('name')
            ->get();

        return view('admin.service-plans.create', compact('services'));
    }

    public function store(StoreServicePlanRequest $request)
    {
        $user = $request->user();
        $isAdminOrSuper = $user->hasAnyRole(['admin', 'super admin']);

        $data = $request->validated();
        $this->ensureServiceAccess((int) $data['service_id'], (int) $user->id, $isAdminOrSuper);

        $data['created_by'] = $user->id;
        $data['currency'] = $data['currency'] ?? 'USD';
        // New plans require super admin approval before becoming active.
        $data['is_active'] = false;

        ServicePlan::create($data);

        return redirect()->route('admin.service-plans.index')->with('status', 'Service plan created in pending status.');
    }

    public function show(ServicePlan $servicePlan)
    {
        $this->authorizePlanAccess($servicePlan);

        return redirect()->route('admin.service-plans.edit', $servicePlan);
    }

    public function edit(ServicePlan $servicePlan)
    {
        $this->authorizePlanAccess($servicePlan);

        $user = auth()->user();
        $isAdminOrSuper = $user->hasAnyRole(['admin', 'super admin']);

        $services = Service::query()
            ->when(! $isAdminOrSuper, fn ($q) => $q->where('created_by', $user->id))
            ->orderBy('name')
            ->get();

        return view('admin.service-plans.edit', compact('servicePlan', 'services'));
    }

    public function update(UpdateServicePlanRequest $request, ServicePlan $servicePlan)
    {
        $this->authorizePlanAccess($servicePlan);

        $user = $request->user();
        $isAdminOrSuper = $user->hasAnyRole(['admin', 'super admin']);

        $data = $request->validated();
        $this->ensureServiceAccess((int) $data['service_id'], (int) $user->id, $isAdminOrSuper);

        $data['currency'] = $data['currency'] ?? 'USD';
        $data['is_active'] = (bool) ($data['is_active'] ?? false);

        $servicePlan->update($data);

        return redirect()->route('admin.service-plans.index')->with('status', 'Service plan updated successfully.');
    }

    public function destroy(ServicePlan $servicePlan)
    {
        $this->authorizePlanAccess($servicePlan);

        DB::transaction(function () use ($servicePlan) {
            SharedSubscription::query()
                ->where('service_plan_id', $servicePlan->id)
                ->delete();

            $servicePlan->delete();
        });

        return redirect()->route('admin.service-plans.index')->with('status', 'Service plan deleted successfully.');
    }

    private function authorizePlanAccess(ServicePlan $servicePlan): void
    {
        $user = auth()->user();

        if ($user->hasAnyRole(['admin', 'super admin'])) {
            return;
        }

        abort_if((int) $servicePlan->created_by !== (int) $user->id, 403);
    }

    private function ensureServiceAccess(int $serviceId, int $userId, bool $isAdminOrSuper): void
    {
        if ($isAdminOrSuper) {
            return;
        }

        $hasAccess = Service::query()
            ->whereKey($serviceId)
            ->where('created_by', $userId)
            ->exists();

        abort_if(! $hasAccess, 403);
    }
}
