<?php

namespace App\Http\Controllers\Company\Inventory;

use App\Http\Controllers\Controller;
use App\Models\{AuditLog, ItemCategory};
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;

class ItemCategoriesController extends Controller
{
    public function index()
    {
        $this->gate('view');

        $companyId  = auth()->user()->company_id;
        $categories = ItemCategory::withoutGlobalScopes()
            ->where('company_id', $companyId)
            ->whereNull('deleted_at')
            ->withCount('items')
            ->orderBy('name')
            ->get();

        $tree = $this->buildTree($categories);

        return view('inventory.categories.index', compact('tree', 'categories'));
    }

    public function store(Request $request)
    {
        $this->gate('create');
        $companyId = auth()->user()->company_id;

        $validated = $request->validate([
            'name'      => 'required|string|max:150',
            'code'      => [
                'nullable', 'string', 'max:30',
                Rule::unique('item_categories')
                    ->where(fn($q) => $q->where('company_id', $companyId)->whereNull('deleted_at')),
            ],
            'parent_id' => 'nullable|integer',
        ]);

        $parentId = null;
        $depth    = 0;

        if (!empty($validated['parent_id'])) {
            $parent = ItemCategory::withoutGlobalScopes()
                ->where('company_id', $companyId)
                ->find($validated['parent_id']);
            if ($parent) {
                $parentId = $parent->id;
                $depth    = $parent->depth + 1;
            }
        }

        $cat = ItemCategory::withoutGlobalScopes()->create([
            'company_id' => $companyId,
            'parent_id'  => $parentId,
            'code'       => $validated['code'] ?? null,
            'name'       => $validated['name'],
            'depth'      => $depth,
            'is_active'  => true,
        ]);

        AuditLog::record('create', 'item_categories', (string) $cat->id, null,
            ['name' => $cat->name], "Item category created: {$cat->name}");

        return back()->with('success', "Category '{$cat->name}' created.");
    }

    public function update(Request $request, ItemCategory $itemCategory)
    {
        $this->gate('edit');
        $this->sameCompany($itemCategory);

        $companyId = auth()->user()->company_id;

        $request->validate([
            'name'      => 'required|string|max:150',
            'is_active' => 'boolean',
            'code'      => [
                'nullable', 'string', 'max:30',
                Rule::unique('item_categories')
                    ->where(fn($q) => $q->where('company_id', $companyId)->whereNull('deleted_at'))
                    ->ignore($itemCategory->id),
            ],
        ]);

        $itemCategory->update([
            'name'      => $request->name,
            'code'      => $request->code,
            'is_active' => $request->boolean('is_active', true),
        ]);

        AuditLog::record('update', 'item_categories', (string) $itemCategory->id,
            null, ['name' => $itemCategory->name], "Category updated: {$itemCategory->name}");

        return back()->with('success', "Category '{$itemCategory->name}' updated.");
    }

    public function destroy(ItemCategory $itemCategory)
    {
        $this->gate('delete');
        $this->sameCompany($itemCategory);

        $guard = app(\App\Services\MasterDeletionGuard::class);
        if ($message = $guard->blockingMessage($itemCategory)) {
            return back()->withErrors(['error' => $message]);
        }

        $name = $itemCategory->name;
        $id = $itemCategory->id;
        $guard->hardDelete($itemCategory);

        AuditLog::record('hard_delete', 'item_categories', (string) $id,
            null, null, "Category permanently deleted: {$name}");

        return back()->with('success', "Category '{$name}' permanently deleted.");
    }

    private function buildTree($categories, $parentId = null): array
    {
        $tree = [];
        foreach ($categories->where('parent_id', $parentId) as $cat) {
            $cat->children_tree = $this->buildTree($categories, $cat->id);
            $tree[] = $cat;
        }
        return $tree;
    }

    private function gate(string $action): void
    {
        if (!auth()->user()->hasPermission('inventory', $action)) abort(403);
    }

    private function sameCompany(ItemCategory $cat): void
    {
        if ($cat->company_id !== auth()->user()->company_id) abort(403);
    }
}
