<?php

declare(strict_types=1);

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

use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Maestro\Core\Http\Controllers\Controller;
use Maestro\Core\Modules\Customers\Models\Customer;
use Maestro\Core\Modules\HourRegistration\Models\HourInternalCategory;
use Maestro\Core\Modules\HourRegistration\Models\HourProject;
use Maestro\Core\Modules\HourRegistration\Models\HourTask;

class HourRegistryController extends Controller
{
    public function internalCategories(Request $request): JsonResponse
    {
        abort_unless($request->user()?->can('hours.week.manage') || $request->user()?->can('hours.admin'), 403);

        $categories = HourInternalCategory::query()
            ->where('is_active', true)
            ->orderBy('sort_order')
            ->orderBy('name')
            ->get(['id', 'name', 'slug']);

        return response()->json(['data' => $categories]);
    }

    public function customers(Request $request): JsonResponse
    {
        abort_unless($request->user()?->can('hours.week.manage') || $request->user()?->can('hours.admin'), 403);

        $customers = Customer::query()
            ->active()
            ->orderBy('name')
            ->get(['id', 'name']);

        return response()->json(['data' => $customers]);
    }

    public function projects(Request $request): JsonResponse
    {
        abort_unless($request->user()?->can('hours.week.manage') || $request->user()?->can('hours.export') || $request->user()?->can('hours.approve') || $request->user()?->can('hours.admin'), 403);

        $projects = HourProject::query()
            ->where('is_active', true)
            ->with('customer:id,name')
            ->orderBy('name')
            ->get();

        return response()->json([
            'data' => $projects->map(static fn ($p): array => [
                'id' => $p->id,
                'name' => $p->name,
                'customer_id' => $p->customer_id,
                'project_lead_id' => $p->project_lead_id,
                'customer' => $p->customer ? ['id' => $p->customer->id, 'name' => $p->customer->name] : null,
            ]),
        ]);
    }

    public function tasks(Request $request): JsonResponse
    {
        abort_unless($request->user()?->can('hours.week.manage') || $request->user()?->can('hours.admin'), 403);

        $validated = validator($request->query(), [
            'hour_project_id' => ['required', 'integer', 'exists:hour_projects,id'],
        ])->validated();

        $tasks = HourTask::query()
            ->where('hour_project_id', (int) $validated['hour_project_id'])
            ->where('is_active', true)
            ->orderBy('title')
            ->get(['id', 'title', 'hour_project_id']);

        return response()->json(['data' => $tasks]);
    }

    /** Admin: create registrable projects for hour linking. */
    public function storeProject(Request $request): JsonResponse
    {
        abort_unless($request->user()?->can('hours.admin'), 403);

        $validated = validator($request->all(), [
            'name' => ['required', 'string', 'max:255'],
            'customer_id' => ['nullable', 'integer', 'exists:customers,id'],
            'project_lead_id' => ['required', 'integer', 'exists:users,id'],
        ])->validate();

        $project = HourProject::query()->create([
            ...$validated,
            'is_active' => true,
        ]);

        return response()->json(['data' => $project->load('customer')], 201);
    }

    public function storeTask(Request $request): JsonResponse
    {
        abort_unless($request->user()?->can('hours.admin'), 403);

        $validated = validator($request->all(), [
            'hour_project_id' => ['required', 'integer', 'exists:hour_projects,id'],
            'title' => ['required', 'string', 'max:255'],
            'override_lead_id' => ['nullable', 'integer', 'exists:users,id'],
        ])->validate();

        $task = HourTask::query()->create([
            ...$validated,
            'is_active' => true,
        ]);

        return response()->json(['data' => $task], 201);
    }
}
