<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Http\Requests\StoreServiceRequest;
use App\Http\Requests\UpdateServiceRequest;
use App\Models\Category;
use App\Models\Service;
use Illuminate\Support\Str;

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

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

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

        return view('admin.services.index', compact('services', 'isAdminOrSuper'));
    }

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

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

        return view('admin.services.create', compact('categories', 'isAdminOrSuper'));
    }

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

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

        $data['created_by'] = $user->id;
        $data['slug'] = $data['slug'] ?? Str::slug($data['name']);
        $data['is_active'] = $isAdminOrSuper
            ? (bool) ($data['is_active'] ?? true)
            : false;

        Service::create($data);

        $message = $isAdminOrSuper
            ? 'Service created successfully.'
            : 'Service created in pending status.';

        return redirect()->route('admin.services.index')->with('status', $message);
    }

    public function show(Service $service)
    {
        $this->authorizeServiceAccess($service);

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

    public function edit(Service $service)
    {
        $this->authorizeServiceAccess($service);

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

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

        return view('admin.services.edit', compact('service', 'categories', 'isAdminOrSuper'));
    }

    public function update(UpdateServiceRequest $request, Service $service)
    {
        $this->authorizeServiceAccess($service);

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

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

        $data['slug'] = $data['slug'] ?? Str::slug($data['name']);

        if ($isAdminOrSuper) {
            $data['is_active'] = (bool) ($data['is_active'] ?? false);
        } else {
            unset($data['is_active']);
        }

        $service->update($data);

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

    public function destroy(Service $service)
    {
        $this->authorizeServiceAccess($service);

        $service->delete();

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

    private function authorizeServiceAccess(Service $service): void
    {
        $user = auth()->user();

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

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

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

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

        abort_if(! $hasAccess, 403);
    }
}
