<?php

namespace App\Modules\HR\Shifts\Controllers;

use App\Http\Controllers\Controller;
use App\Modules\Admin\Tenancy\Models\Tenant;
use App\Modules\HR\Employees\Models\Employee;
use App\Modules\HR\Shifts\Models\EmployeeShiftAssignment;
use App\Modules\HR\Shifts\Repositories\EmployeeShiftAssignmentRepository;
use App\Modules\HR\Shifts\Repositories\ShiftRepository;
use App\Modules\HR\Shifts\Requests\EndEmployeeShiftAssignmentRequest;
use App\Modules\HR\Shifts\Requests\StoreEmployeeShiftAssignmentRequest;
use App\Modules\HR\Shifts\Services\EmployeeShiftAssignmentService;
use Carbon\CarbonImmutable;
use Illuminate\Http\RedirectResponse;
use Illuminate\View\View;

class EmployeeShiftAssignmentPageController extends Controller
{
    public function __construct(
        private readonly EmployeeShiftAssignmentService $assignments,
        private readonly EmployeeShiftAssignmentRepository $assignmentRows,
        private readonly ShiftRepository $shifts,
    ) {}

    public function index(): View
    {
        abort_unless(auth()->user()?->can('shifts.view'), 403);
        $tenant = $this->tenant();

        return view('pages.hr.shifts.assignments', [
            'assignments' => $this->assignmentRows->paginateForTenant((int) $tenant->id),
        ]);
    }

    public function create(): View
    {
        abort_unless(auth()->user()?->can('shifts.assign'), 403);
        $tenant = $this->tenant();

        return view('pages.hr.shifts.assign', [
            'employees' => Employee::query()
                ->where('tenant_id', $tenant->id)
                ->where('is_active', true)
                ->orderBy('full_name')
                ->get(['id', 'full_name']),
            'shifts' => $this->shifts->activeForTenant((int) $tenant->id),
        ]);
    }

    public function store(StoreEmployeeShiftAssignmentRequest $request): RedirectResponse
    {
        $tenant = $this->tenant();
        $v = $request->validated();
        $startsAt = ! empty($v['starts_at'])
            ? CarbonImmutable::parse($v['starts_at'], $tenant->timezone ?: config('app.timezone'))
            : null;
        $this->assignments->assign(
            (int) $tenant->id,
            (int) $v['employee_id'],
            (int) $v['shift_id'],
            (int) $request->user()->id,
            $startsAt,
        );

        return redirect()
            ->route('hr.shifts.assignments.index')
            ->with('status', __('shifts.flash.assigned'));
    }

    public function end(
        EndEmployeeShiftAssignmentRequest $request,
        EmployeeShiftAssignment $assignment,
    ): RedirectResponse {
        abort_unless((int) $assignment->tenant_id === (int) $this->tenant()->id, 404);
        $this->assignments->end($assignment, (int) $request->user()->id);

        return redirect()
            ->route('hr.shifts.assignments.index')
            ->with('status', __('shifts.flash.assignment_ended'));
    }

    private function tenant(): Tenant
    {
        $t = auth()->user()?->tenant;
        abort_if($t === null, 403);

        return $t;
    }
}
