<?php

declare(strict_types=1);

namespace Maestro\Core\Modules\Items\Http\Controllers;

use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Schema;
use Maestro\Core\Http\Controllers\Controller;
use Maestro\Core\Modules\Invoices\Models\InvoiceLine;
use Maestro\Core\Modules\Items\Http\Requests\StoreItemRequest;
use Maestro\Core\Modules\Items\Http\Requests\UpdateItemRequest;
use Maestro\Core\Modules\Items\Http\Resources\ItemResource;
use Maestro\Core\Modules\Items\Models\Item;

final class ItemController extends Controller
{
    public function index(Request $request): JsonResponse
    {
        abort_unless($request->user()?->can('items.manage'), 403);

        $items = Item::query()
            ->when(! $request->boolean('include_inactive'), fn ($q) => $q->where('is_active', true))
            ->orderBy('sort_order')
            ->orderBy('name')
            ->get();

        return ItemResource::collection($items)->response();
    }

    public function store(StoreItemRequest $request): JsonResponse
    {
        abort_unless($request->user()?->can('items.manage'), 403);

        $item = Item::query()->create($request->validated());

        return (new ItemResource($item))->response()->setStatusCode(201);
    }

    public function update(UpdateItemRequest $request, Item $item): JsonResponse
    {
        abort_unless($request->user()?->can('items.manage'), 403);

        $item->fill($request->validated());
        $item->save();

        return (new ItemResource($item->fresh()))->response();
    }

    public function destroy(Request $request, Item $item): JsonResponse
    {
        abort_unless($request->user()?->can('items.manage'), 403);

        if (Schema::hasTable('invoice_lines') && InvoiceLine::query()->where('item_id', $item->id)->exists()) {
            return response()->json([
                'message' => 'This item is referenced on invoices. Deactivate it instead of deleting.',
            ], 422);
        }

        $item->delete();

        return response()->json(['message' => 'Deleted.']);
    }
}
