<?php

namespace App\Modules\HR\Attendance\Controllers;

use App\Http\Controllers\Controller;
use App\Modules\Admin\Tenancy\Models\Tenant;
use App\Modules\HR\Attendance\Models\AttendanceRecord;
use App\Modules\HR\Attendance\Repositories\AttendanceRecordRepository;
use App\Modules\HR\Attendance\Requests\StoreManualAttendanceRequest;
use App\Modules\HR\Attendance\Requests\UpdateAttendanceCheckoutRequest;
use App\Modules\HR\Attendance\Services\AttendanceHistoryWindowService;
use App\Modules\HR\Attendance\Services\AttendanceManualEntryService;
use App\Modules\HR\Attendance\Support\AttendanceRecordStatus;
use App\Modules\HR\Employees\Models\Employee;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;

class AttendanceRecordsPageController extends Controller
{
    public function index(
        Request $request,
        AttendanceRecordRepository $records,
        AttendanceHistoryWindowService $historyWindow,
    ): View {
        $this->authorize('viewAny', AttendanceRecord::class);
        $tenant = $this->tenant();
        $floor = $historyWindow->earliestReportDate($tenant);
        $defaultFrom = $floor?->toDateString() ?? now()->subMonth()->toDateString();
        $from = (string) $request->query('from', $defaultFrom);
        $to = (string) $request->query('to', now()->toDateString());

        return view('pages.hr.attendance.index', [
            'records' => $records->paginateForTenant((int) $tenant->id, $from, $to),
            'from' => $from,
            'to' => $to,
            'employees' => Employee::query()->where('tenant_id', $tenant->id)->orderBy('full_name')->get(),
            'manualStatusOptions' => [
                AttendanceRecordStatus::PRESENT,
                AttendanceRecordStatus::ABSENT,
                AttendanceRecordStatus::LATE,
                AttendanceRecordStatus::HALF_DAY,
                AttendanceRecordStatus::HOLIDAY,
            ],
        ]);
    }

    public function store(StoreManualAttendanceRequest $request, AttendanceManualEntryService $service): RedirectResponse
    {
        $this->authorize('create', AttendanceRecord::class);
        $employee = Employee::query()->findOrFail((int) $request->validated('employee_id'));
        $v = $request->validated();
        $checkOut = $v['check_out_at'] ?? null;
        if ($checkOut !== null && $checkOut !== '' && ! $request->user()?->can('registerCheckout', AttendanceRecord::class)) {
            $checkOut = null;
        }
        $service->upsert($employee, [
            'attendance_date' => $v['attendance_date'],
            'check_in_at' => $v['check_in_at'] ?? null,
            'check_out_at' => $checkOut,
            'status' => $v['status'],
            'notes' => $v['notes'] ?? null,
        ], (int) $request->user()->id);

        return redirect()
            ->route('hr.attendance.index', ['from' => $v['attendance_date'], 'to' => $v['attendance_date']])
            ->with('status', __('attendance.flash.saved'));
    }

    public function updateCheckout(
        UpdateAttendanceCheckoutRequest $request,
        AttendanceRecord $record,
        AttendanceManualEntryService $service,
    ): RedirectResponse {
        $service->updateCheckout($record, (string) $request->validated('check_out_at'), (int) $request->user()->id);
        $date = $record->attendance_date?->toDateString() ?? now()->toDateString();

        return redirect()
            ->route('hr.attendance.index', ['from' => $date, 'to' => $date])
            ->with('status', __('attendance.flash.checkout_updated'));
    }

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

        return $t;
    }
}
