<?php

namespace App\Support;

use Carbon\Carbon;
use Carbon\CarbonInterface;
use Morilog\Jalali\Jalalian;

/**
 * Salary months follow the Solar Hijri (Shamsi) calendar.
 * Stored as the Gregorian date of the first day of the Shamsi month.
 */
final class SalaryMonth
{
    /** @var list<string> Dari month names (حمل … حوت). */
    private const DARI_MONTH_NAMES = [
        'حمل',
        'ثور',
        'جوزا',
        'سرطان',
        'اسد',
        'سنبله',
        'میزان',
        'عقرب',
        'قوس',
        'جدی',
        'دلو',
        'حوت',
    ];

    /**
     * @return array{
     *     start: Carbon,
     *     end: Carbon,
     *     days: int,
     *     jalali_year: int,
     *     jalali_month: int,
     * }
     */
    public static function period(CarbonInterface|string $anchor): array
    {
        $start = self::normalizeStart($anchor);
        $jalali = Jalalian::fromCarbon($start)->getFirstDayOfMonth();
        $endJalali = $jalali->getEndDayOfMonth();

        $startCarbon = $jalali->toCarbon()->startOfDay();
        $endCarbon = $endJalali->toCarbon()->startOfDay();

        return [
            'start' => $startCarbon,
            'end' => $endCarbon,
            'days' => $jalali->getMonthDays(),
            'jalali_year' => $jalali->getYear(),
            'jalali_month' => $jalali->getMonth(),
        ];
    }

    public static function normalizeStart(CarbonInterface|string|null $input = null): Carbon
    {
        if ($input instanceof CarbonInterface) {
            $input = $input->toDateString();
        }

        $input = trim((string) $input);

        if ($input === '') {
            return self::defaultStart();
        }

        if (preg_match('/^(\d{4})[-\/](\d{1,2})$/', $input, $matches) === 1) {
            $year = (int) $matches[1];
            $month = (int) $matches[2];

            if ($year >= 1000 && $year < 1700) {
                return (new Jalalian($year, $month, 1))->toCarbon()->startOfDay();
            }
        }

        if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $input) === 1) {
            return Jalalian::fromCarbon(Carbon::parse($input)->startOfDay())
                ->getFirstDayOfMonth()
                ->toCarbon()
                ->startOfDay();
        }

        // Legacy Gregorian YYYY-MM query params (e.g. 2026-04) — use current Shamsi month.
        if (preg_match('/^\d{4}-\d{2}$/', $input) === 1) {
            return self::defaultStart();
        }

        return self::defaultStart();
    }

    public static function defaultStart(): Carbon
    {
        return Jalalian::now()->getFirstDayOfMonth()->toCarbon()->startOfDay();
    }

    public static function urlKey(Carbon $start): string
    {
        return $start->toDateString();
    }

    /**
     * Canonical Y-m-d anchor stored on salary payment rows (first day of the Shamsi month).
     */
    public static function anchorForQuery(CarbonInterface|string|null $input = null): string
    {
        return self::urlKey(self::normalizeStart($input));
    }

    public static function displayLabel(Carbon $start): string
    {
        $jalali = Jalalian::fromCarbon($start)->getFirstDayOfMonth();
        $monthName = self::DARI_MONTH_NAMES[$jalali->getMonth() - 1] ?? (string) $jalali->getMonth();

        return $monthName.' '.$jalali->getYear();
    }
}
