<?php

namespace App\Http\Controllers;

use App\Models\Branch;
use App\Models\Business;
use App\Models\Collateral;
use App\Models\CollateralCategory;
use App\Services\AuditService;
use App\Services\BranchAccessService;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
use Illuminate\Validation\Rule;
use Illuminate\View\View;

class CollateralCategoryController extends Controller
{
    public function __construct(private BranchAccessService $branchAccess)
    {
    }

    public function index(Request $request): View
    {
        Gate::authorize('manageCategories', Collateral::class);
        $businessIds = $this->allowedBusinessIds($request);
        $query = CollateralCategory::withCount('collaterals')->whereIn('business_id', $businessIds)->orderBy('name');

        if ($request->filled('search')) {
            $search = trim((string) $request->string('search'));
            $query->where('name', 'like', "%{$search}%");
        }
        if ($request->filled('status')) {
            $query->where('status', $request->string('status'));
        }

        return view('collateral.categories', [
            'categories' => $query->paginate(20)->withQueryString(),
            'businessId' => $businessIds->first(),
        ]);
    }

    public function store(Request $request): RedirectResponse
    {
        Gate::authorize('manageCategories', Collateral::class);
        $businessIds = $this->allowedBusinessIds($request);
        $data = $request->validate([
            'business_id' => ['required', 'integer', Rule::in($businessIds->all())],
            'name' => ['required', 'string', 'max:150', Rule::unique('collateral_categories')->where(fn ($q) => $q->where('business_id', $request->integer('business_id')))],
            'description' => ['nullable', 'string', 'max:1000'],
            'status' => ['required', Rule::in(['active', 'inactive'])],
        ]);

        $category = CollateralCategory::create($data);
        AuditService::record('collateral.category_created', $category, [], $category->toArray());

        return back()->with('success', 'Collateral category created.');
    }

    public function update(Request $request, CollateralCategory $category): RedirectResponse
    {
        Gate::authorize('manageCategories', Collateral::class);
        abort_unless($this->allowedBusinessIds($request)->contains($category->business_id), 403);
        $data = $request->validate([
            'name' => ['required', 'string', 'max:150', Rule::unique('collateral_categories')->where(fn ($q) => $q->where('business_id', $category->business_id))->ignore($category->id)],
            'description' => ['nullable', 'string', 'max:1000'],
            'status' => ['required', Rule::in(['active', 'inactive'])],
        ]);

        $before = $category->toArray();
        $category->update($data);
        AuditService::record('collateral.category_updated', $category, $before, $category->fresh()->toArray());

        return back()->with('success', 'Collateral category updated.');
    }

    private function allowedBusinessIds(Request $request)
    {
        if ($this->branchAccess->isSystemWide($request->user())) {
            return Business::pluck('id');
        }

        return Branch::query()
            ->whereIn('id', $this->branchAccess->accessibleBranchIds($request->user()))
            ->pluck('business_id')
            ->unique()
            ->values();
    }
}
