<?php

declare(strict_types=1);

namespace App\Services;

use App\Repositories\AppointmentRepository;
use App\Repositories\ReferenceDataRepository;
use DateInterval;
use DateTimeImmutable;

final class CalendarService
{
    public function validate(int $tenantId, array $payload, ?int $appointmentId = null): array
    {
        $appointmentRepository = new AppointmentRepository();
        $lessonType = (new ReferenceDataRepository())->findLessonType($tenantId, (int) $payload['lesson_type_id']);
        $warnings = [
            'conflicts' => [],
            'rest_period_warnings' => [],
        ];

        $conflicts = $appointmentRepository->overlappingForInstructor(
            $tenantId,
            (int) $payload['instructor_id'],
            $payload['start_at'],
            $payload['end_at'],
            $appointmentId
        );

        foreach ($conflicts as $conflict) {
            $warnings['conflicts'][] = [
                'type' => 'instructor_overlap',
                'message' => 'Fahrlehrer ist in diesem Zeitraum bereits verplant.',
                'appointment_id' => (int) $conflict['id'],
            ];
        }

        if (!empty($payload['student_id'])) {
            $studentConflicts = $appointmentRepository->overlappingForStudent(
                $tenantId,
                (int) $payload['student_id'],
                $payload['start_at'],
                $payload['end_at'],
                $appointmentId
            );
            foreach ($studentConflicts as $conflict) {
                $warnings['conflicts'][] = [
                    'type' => 'student_overlap',
                    'message' => 'Fahrschueler ist in diesem Zeitraum bereits verplant.',
                    'appointment_id' => (int) $conflict['id'],
                ];
            }
        }

        if ($lessonType !== null && (int) $lessonType['is_rest_relevant'] === 1) {
            $newStart = new DateTimeImmutable($payload['start_at']);
            $dayStart = $newStart->setTime(0, 0, 0);
            $dayEnd = $dayStart->modify('+1 day');
            $hasLaterRelevantOnDay = $appointmentRepository->hasRestRelevantAfterStartOnDay(
                $tenantId,
                (int) $payload['instructor_id'],
                $dayStart->format(DATE_ATOM),
                $dayEnd->format(DATE_ATOM),
                $payload['start_at']
            );

            if ($hasLaterRelevantOnDay) {
                return $warnings;
            }

            $lastRelevant = $appointmentRepository->lastRestRelevantForInstructor(
                $tenantId,
                (int) $payload['instructor_id'],
                $payload['start_at'],
                $appointmentId
            );
            if ($lastRelevant !== null) {
                $restEnds = (new DateTimeImmutable($lastRelevant['end_at']))->add(new DateInterval('PT11H'));
                if ($newStart < $restEnds) {
                    $warnings['rest_period_warnings'][] = [
                        'type' => 'rest_period',
                        'message' => 'Achtung: Dieser Termin liegt innerhalb der 11-Stunden-Ruhezeit.',
                        'rest_until' => $restEnds->format(DATE_ATOM),
                        'blocking_appointment_id' => (int) $lastRelevant['id'],
                    ];
                }
            }
        }

        return $warnings;
    }
}
