<?php

namespace App\Modules\HR\Attendance\Services;

use App\Models\User;
use App\Modules\HR\Attendance\Events\AttendanceCorrectionSubmitted;
use App\Modules\HR\Attendance\Models\AttendanceCorrectionRequest;
use App\Modules\HR\Attendance\Repositories\AttendanceCorrectionRequestRepository;
use App\Modules\HR\Attendance\Repositories\AttendanceRecordRepository;
use App\Modules\HR\Attendance\Support\AttendanceCorrectionStatus;
use Carbon\Carbon;

class AttendanceCorrectionSubmissionService
{
    public function __construct(
        private readonly AttendanceRecordRepository $records,
        private readonly AttendanceCorrectionRequestRepository $corrections,
        private readonly AttendanceCorrectionPayloadValidator $payloadValidator,
    ) {}

    /**
     * @param  array<string, mixed>  $input
     */
    public function submit(User $user, array $input): AttendanceCorrectionRequest
    {
        $tenantId = (int) $user->tenant_id;
        $employeeId = (int) $user->employee_id;
        $recordId = (int) $input['attendance_record_id'];
        $record = $this->records->findOwnedByEmployee($tenantId, $employeeId, $recordId);
        if ($record === null) {
            abort(404);
        }
        if ($this->corrections->hasPendingForRecord($tenantId, $recordId)) {
            throw \Illuminate\Validation\ValidationException::withMessages([
                'attendance_record_id' => [__('attendance_corrections.validation.pending_exists')],
            ]);
        }

        $type = (string) $input['type'];
        $reqIn = ! empty($input['requested_check_in']) ? Carbon::parse((string) $input['requested_check_in']) : null;
        $reqOut = ! empty($input['requested_check_out']) ? Carbon::parse((string) $input['requested_check_out']) : null;
        $this->payloadValidator->assertForSubmit($type, $record, $reqIn, $reqOut);

        $created = $this->corrections->create([
            'tenant_id' => $tenantId,
            'employee_id' => $employeeId,
            'attendance_record_id' => $recordId,
            'type' => $type,
            'requested_check_in' => $reqIn,
            'requested_check_out' => $reqOut,
            'reason' => (string) $input['reason'],
            'status' => AttendanceCorrectionStatus::PENDING,
            'metadata' => null,
        ]);
        event(new AttendanceCorrectionSubmitted($created, (int) $user->id));

        return $created;
    }
}
