<?php

declare(strict_types=1);

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

use Carbon\Carbon;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Maestro\Core\Http\Controllers\Controller;
use Maestro\Core\Modules\HourRegistration\Enums\HourWorkflowStatus;
use Maestro\Core\Modules\HourRegistration\Models\HourTimesheetLine;
use Maestro\Core\Modules\HourRegistration\Models\HourTimesheetWeek;

final class HourBulkEntryController extends Controller
{
    public function __invoke(Request $request): JsonResponse
    {
        abort_unless($request->user()?->can('hours.week.manage'), 403);

        $validated = $request->validate([
            'dates'                => ['required', 'array', 'min:1', 'max:31'],
            'dates.*'              => ['required', 'date'],
            'hours'                => ['required', 'numeric', 'min:0.01', 'max:24'],
            'registration_type'    => ['required', 'string', 'in:internal,project,task,customer'],
            'internal_category_id' => ['nullable', 'integer'],
            'hour_project_id'      => ['nullable', 'integer'],
            'hour_task_id'         => ['nullable', 'integer'],
            'customer_id'          => ['nullable', 'integer'],
            'description'          => ['nullable', 'string', 'max:1000'],
        ]);

        $userId   = $request->user()->getAuthIdentifier();
        $hours    = round((float) $validated['hours'], 2);
        $type     = $validated['registration_type'];
        $desc     = $validated['description'] ?? '';

        $dayKeys = HourTimesheetLine::WEEKDAY_KEYS;

        foreach ($validated['dates'] as $dateStr) {
            $date   = Carbon::parse($dateStr)->startOfDay();
            $monday = $date->copy()->locale('en')->startOfWeek(Carbon::MONDAY);

            $week = HourTimesheetWeek::firstOrCreate(
                ['user_id' => $userId, 'week_start' => $monday->toDateString()],
                ['workflow_status' => HourWorkflowStatus::Draft, 'submitted_at' => null],
            );

            $dayIndex = (int) $date->diffInDays($monday);
            $dayKey   = $dayKeys[$dayIndex] ?? null;

            if ($dayKey === null) {
                continue;
            }

            $durations = array_fill_keys(
                array_map(fn (string $k): string => 'duration_'.$k, $dayKeys),
                0,
            );
            $durations['duration_'.$dayKey] = $hours;

            HourTimesheetLine::create([
                'hour_timesheet_week_id' => $week->id,
                'registration_type'      => $type,
                'description'            => $desc,
                'internal_category_id'   => $type === 'internal' ? ($validated['internal_category_id'] ?? null) : null,
                'hour_project_id'        => $type === 'project' ? ($validated['hour_project_id'] ?? null) : null,
                'hour_task_id'           => $type === 'task' ? ($validated['hour_task_id'] ?? null) : null,
                'customer_id'            => $type === 'customer' ? ($validated['customer_id'] ?? null) : null,
                ...$durations,
            ]);
        }

        return response()->json(['message' => 'Entries saved successfully.']);
    }
}
