<?php

namespace App\Http\Requests\Admin\Master;

use App\Enums\Semester;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;

class AcademicTermRequest extends FormRequest
{
    public function authorize(): bool
    {
        return $this->user()->can($this->isMethod('post') ? 'create-academic-terms' : 'update-academic-terms');
    }

    public function rules(): array
    {
        return [
            'name' => [
                'required',
                'string',
                'max:20',
                function ($attribute, $value, $fail) {
                    if (! preg_match('/^(\d{4})\/(\d{4})$/', $value, $matches)) {
                        $fail('Format name harus YYYY/YYYY, contoh: 2025/2026.');

                        return;
                    }

                    $startYear = (int) $matches[1];
                    $endYear = (int) $matches[2];

                    if ($endYear !== $startYear + 1) {
                        $fail('Tahun kedua harus selisih 1 tahun dari tahun pertama. Contoh: 2025/2026, 2026/2027.');
                    }
                },
            ],
            'semester' => [
                'required',
                'string',
                Rule::in(Semester::values()),
                Rule::unique('academic_terms')->where(function ($query) {
                    return $query->where('name', $this->input('name'));
                })->ignore($this->route('academic_term')),
            ],
            'start_date' => [
                'required',
                'date',
                function ($attribute, $value, $fail) {
                    $name = $this->input('name');
                    $semester = $this->input('semester');
                    if ($name && preg_match('/^(\d{4})\/(\d{4})$/', $name, $matches)) {
                        $startYear = (int) $matches[1];
                        $endYear = (int) $matches[2];
                        $dateYear = (int) date('Y', strtotime($value));
                        $expectedYear = $semester === 'even' ? $endYear : $startYear;
                        if ($dateYear !== $expectedYear) {
                            $fail('Start date harus berada di tahun '.$expectedYear.' untuk semester '.($semester === 'even' ? 'Genap' : 'Ganjil').'.');
                        }
                    }
                },
            ],
            'end_date' => [
                'required',
                'date',
                'after_or_equal:start_date',
                function ($attribute, $value, $fail) {
                    $name = $this->input('name');
                    $semester = $this->input('semester');
                    if ($name && preg_match('/^(\d{4})\/(\d{4})$/', $name, $matches)) {
                        $startYear = (int) $matches[1];
                        $endYear = (int) $matches[2];
                        $dateYear = (int) date('Y', strtotime($value));
                        $expectedYear = $semester === 'even' ? $endYear : $startYear;
                        if ($dateYear !== $expectedYear) {
                            $fail('End date harus berada di tahun '.$expectedYear.' untuk semester '.($semester === 'even' ? 'Genap' : 'Ganjil').'.');
                        }
                    }
                },
            ],
            'is_active' => ['boolean'],
        ];
    }
}
