<?php

namespace App\Services\Administrator;

use App\Models\Configuration;
use Carbon\Carbon;

class AdministratorSharedService
{
    public function __construct(
        protected Configuration $configuration
    ) {
    }

    public function getSemester(): string
    {
        return (string) ($this->configuration->getConfig('semester') ?? '');
    }

    public function getSchoolYear(): string
    {
        return (string) ($this->configuration->getConfig('school_year') ?? '');
    }

    public function getPreviousSchoolYear(string $schoolYear): string
    {
        $schoolYear = trim($schoolYear);

        if ($schoolYear === '') {
            return '';
        }

        if (preg_match('/^(\d{4})\s*-\s*(\d{4})$/', $schoolYear, $m)) {
            return ((int) $m[1] - 1) . '-' . ((int) $m[2] - 1);
        }

        if (preg_match('/^(\d{4})\s*-\s*(\d{2})$/', $schoolYear, $m)) {
            $start = (int) $m[1] - 1;
            $end = (int) $m[2] - 1;
            if ($end < 0) {
                $end += 100;
            }
            return sprintf('%04d-%02d', $start, $end);
        }

        if (preg_match('/^\d{4}$/', $schoolYear)) {
            return (string) ((int) $schoolYear - 1);
        }

        return '';
    }

    public function getSchoolYearStartYear(string $schoolYear): ?int
    {
        $schoolYear = trim($schoolYear);

        if ($schoolYear === '') {
            return null;
        }

        if (preg_match('/^(\d{4})\s*-\s*(\d{4})$/', $schoolYear, $m)) {
            return (int) $m[1];
        }

        if (preg_match('/^(\d{4})\s*-\s*(\d{2})$/', $schoolYear, $m)) {
            return (int) $m[1];
        }

        if (preg_match('/^\d{4}$/', $schoolYear)) {
            return (int) $schoolYear;
        }

        return null;
    }

    public function allowedAbsenceDates(): array
    {
        $today = Carbon::today();
        $schoolYear = $this->getSchoolYear();

        $startYear = null;
        $endYear = null;

        if (preg_match('/^(\d{4})\D+(\d{4})$/', $schoolYear, $m)) {
            $startYear = (int) $m[1];
            $endYear = (int) $m[2];
        } else {
            $cy = (int) now()->format('Y');
            $cm = (int) now()->format('n');
            if ($cm >= 9) {
                $startYear = $cy;
                $endYear = $cy + 1;
            } else {
                $startYear = $cy - 1;
                $endYear = $cy;
            }
        }

        try {
            $start = Carbon::create($startYear, 9, 1)->startOfDay();
            $end = Carbon::create($endYear, 5, 31)->startOfDay();
        } catch (\Throwable) {
            return [];
        }

        if ($start->lt($today)) {
            $start = $today->copy();
        }

        $dates = [];
        $cursor = $start->copy();

        while ($cursor->lte($end)) {
            if ($cursor->dayOfWeek === Carbon::SUNDAY) {
                $dates[] = $cursor->format('Y-m-d');
            }
            $cursor->addDay();
        }

        return $dates;
    }

    public function countUniqueEntities($rows): int
    {
        if (!is_iterable($rows)) {
            return 0;
        }

        $ids = [];

        foreach ($rows as $row) {
            if (is_array($row)) {
                if (isset($row['id'])) {
                    $ids[] = (int) $row['id'];
                } elseif (isset($row['user_id'])) {
                    $ids[] = (int) $row['user_id'];
                }
            } elseif (is_object($row)) {
                if (isset($row->id)) {
                    $ids[] = (int) $row->id;
                } elseif (isset($row->user_id)) {
                    $ids[] = (int) $row->user_id;
                }
            }
        }

        return count(array_unique($ids));
    }
}