<?php

namespace App\Services\ClassProgress;

use App\Models\Configuration;
use App\Models\SubjectCurriculum;
use App\Services\SemesterRangeService;

class ClassProgressMetaService
{
    public function subjectSections(): array
    {
        return (array) config('progress.subject_sections', []);
    }

    public function statusOptions(): array
    {
        return (array) config('progress.status_options', []);
    }

    /**
     * Fallback: next N Sundays from today (legacy `buildUpcomingSundayOptions`).
     *
     * @return list<string>
     */
    public function sundayOptions(int $count = 12): array
    {
        return $this->buildUpcomingSundayOptions($count);
    }

    /**
     * legacy-aligned Sundays within semester/school-year range when configuration allows.
     *
     * @return list<string>
     */
    public function sundayOptionsAlignedWithCi(int $count = 12): array
    {
        $range = $this->resolveProgressDateRange();
        if ($range === null) {
            return $this->buildUpcomingSundayOptions($count);
        }

        [$rangeStart, $rangeEnd] = $range;

        try {
            $start = new \DateTime($rangeStart);
            $end = new \DateTime($rangeEnd);
        } catch (\Exception $e) {
            return $this->buildUpcomingSundayOptions($count);
        }

        if ($end < $start) {
            [$start, $end] = [$end, $start];
        }

        $weekday = (int) $start->format('w');
        if ($weekday !== 0) {
            $start->modify('next sunday');
        }

        $options = [];
        while ($start <= $end) {
            $options[] = $start->format('Y-m-d');
            $start->modify('+7 days');
        }

        return $options !== [] ? $options : $this->buildUpcomingSundayOptions($count);
    }

    /** legacy `pickDefaultWeekStart`. */
    public function pickDefaultWeekStart(array $options): string
    {
        if ($options === []) {
            return '';
        }

        $today = date('Y-m-d');
        $default = '';
        foreach ($options as $option) {
            if ($option <= $today) {
                $default = $option;

                continue;
            }
            break;
        }

        return $default !== '' ? $default : $options[0];
    }

    /**
     * @return list<string>
     */
    private function buildUpcomingSundayOptions(int $count): array
    {
        $start = new \DateTime('today');
        $weekday = (int) $start->format('w');
        if ($weekday !== 0) {
            $start->modify('next sunday');
        }

        $options = [];
        for ($i = 0; $i < $count; $i++) {
            $options[] = $start->format('Y-m-d');
            $start->modify('+7 days');
        }

        return $options;
    }

    /**
     * legacy `resolveProgressDateRange`.
     *
     * @return array{0:string,1:string}|null
     */
    private function resolveProgressDateRange(): ?array
    {
        $schoolYear = (string) (Configuration::getConfig('school_year') ?? '');
        if ($schoolYear === '') {
            return null;
        }

        /** @var SemesterRangeService $svc */
        $svc = app(SemesterRangeService::class);

        $semester = $svc->normalizeSemester((string) (Configuration::getConfig('semester') ?? ''));
        if ($semester === '') {
            $semester = $svc->getSemesterForDate();
        }

        if ($semester !== '') {
            $range = $svc->getSemesterRange($schoolYear, $semester);
            if ($range !== null) {
                return $range;
            }
        }

        return $svc->getSchoolYearRange($schoolYear);
    }

    public function curriculumOptions(?int $classId, ?string $schoolYear = null): array
    {
        if (!$classId) {
            return [];
        }

        $options = [];
        foreach ($this->subjectSections() as $slug => $section) {
            $options[$slug] = SubjectCurriculum::getOptionsForClass((int) $classId, (string) $slug, $schoolYear);
        }

        return $options;
    }
}
