<?php

namespace App\Services\Parents;

use Illuminate\Support\Facades\DB;

class ParentAttendanceReportCalendarService
{
    public function __construct(private ParentConfigService $configService)
    {
    }

    /**
     * @return array{0: array<int, array{value:string,label:string}>, 1: string}
     */
    public function computeSundays(int $weeksBefore = 4, int $weeksAfter = 26): array
    {
        $today = new \DateTime('today');
        $dow = (int) $today->format('w');

        $thisSunday = clone $today;
        if ($dow !== 0) {
            $thisSunday->modify('last sunday');
        }

        $default = clone $today;
        if ($dow !== 0) {
            $default->modify('next sunday');
        }

        $schoolYear = (string) ($this->configService->context()['school_year'] ?? '');
        $cap = $this->firstSundayOfJune($schoolYear);

        $dates = [];
        for ($i = $weeksBefore; $i >= 1; $i--) {
            $dates[] = (clone $thisSunday)->modify('-' . $i . ' week');
        }

        $cursor = clone $thisSunday;
        while ($cursor <= $cap) {
            $dates[] = clone $cursor;
            $cursor->modify('+1 week');
        }

        $rangeStart = reset($dates);
        $rangeEnd = end($dates);
        $rangeStartStr = $rangeStart instanceof \DateTime ? $rangeStart->format('Y-m-d') : null;
        $rangeEndStr = $rangeEnd instanceof \DateTime ? $rangeEnd->format('Y-m-d') : null;

        $noSchool = [];
        if ($rangeStartStr && $rangeEndStr) {
            $rows = DB::table('calendar_events')
                ->select('date')
                ->where('no_school', 1)
                ->groupStart()
                ->where('school_year', $schoolYear)
                ->orWhere('school_year IS NULL', null, false)
                ->groupEnd()
                ->where('date >=', $rangeStartStr)
                ->where('date <=', $rangeEndStr)
                ->get()
                ->toArray();

            foreach ($rows as $row) {
                $d = substr((string) ($row->date ?? ''), 0, 10);
                if ($d !== '') {
                    $noSchool[$d] = true;
                }
            }
        }

        $filtered = [];
        foreach ($dates as $d) {
            $ymd = $d->format('Y-m-d');
            if (!isset($noSchool[$ymd]) && $d >= $today && $d <= $cap) {
                $filtered[] = $d;
            }
        }

        $defaultYmd = $default->format('Y-m-d');
        if (!empty($filtered)) {
            $defaultYmd = $filtered[0]->format('Y-m-d');
        }

        $out = [];
        foreach ($filtered as $d) {
            $out[] = [
                'value' => $d->format('Y-m-d'),
                'label' => $d->format('m-d-Y'),
            ];
        }

        return [$out, $defaultYmd];
    }

    public function normalizeCutoffTime(string $raw, string $default = '09:00'): string
    {
        $raw = trim($raw);
        if ($raw === '') {
            return $default;
        }
        if (preg_match('/^(\\d{1,2}):(\\d{2})$/', $raw, $m)) {
            $hh = str_pad((string) ((int) $m[1]), 2, '0', STR_PAD_LEFT);
            return $hh . ':' . $m[2];
        }
        return $default;
    }

    public function firstSundayOfJune(string $schoolYear): \DateTime
    {
        $today = new \DateTime('today');
        $endYear = null;
        if (preg_match('/^(\\d{4})\\D(\\d{4})$/', $schoolYear, $m)) {
            $endYear = (int) $m[2];
        }
        if ($endYear === null) {
            $y = (int) $today->format('Y');
            $endYear = ((int) $today->format('n') > 6) ? ($y + 1) : $y;
        }

        $juneFirst = new \DateTime(sprintf('%04d-06-01', $endYear));
        if ((int) $juneFirst->format('w') !== 0) {
            $juneFirst->modify('next sunday');
        }
        return $juneFirst;
    }
}
