<?php

namespace App\Resource\Command;

use App\Resource\Service\HolidayService;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

/**
 * تعطیلات رسمی یک سال شمسی را وارد می‌کند.
 *
 * تعطیلات **ثابتِ** تقویم (مناسبت‌های شمسی) درون خود دستور است، چون هر سال تکرار
 * می‌شوند و وابسته به منبع بیرونی نیستند. مناسبت‌های **قمری** (مثل عید فطر) هر سال
 * جابه‌جا می‌شوند و اینجا نمی‌آیند: حدس زدنشان بدتر از نداشتنشان است — با
 * `--extra` یا از پنل دستی اضافه می‌شوند.
 */
#[AsCommand(
    name: 'app:holiday:import',
    description: 'Import the fixed Jalali national holidays for a year',
)]
class ImportHolidayCommand extends Command
{
    /** مناسبت‌های ثابتِ شمسی: [ماه, روز, عنوان] */
    private const FIXED = [
        [1, 1,  'نوروز'],
        [1, 2,  'نوروز'],
        [1, 3,  'نوروز'],
        [1, 4,  'نوروز'],
        [1, 12, 'روز جمهوری اسلامی'],
        [1, 13, 'روز طبیعت'],
        [3, 14, 'رحلت امام خمینی'],
        [3, 15, 'قیام ۱۵ خرداد'],
        [11, 22, 'پیروزی انقلاب اسلامی'],
        [12, 29, 'روز ملی شدن صنعت نفت'],
    ];

    public function __construct(
        private readonly HolidayService $holidays,
    ) {
        parent::__construct();
    }

    protected function configure(): void
    {
        $this->addOption('year', null, InputOption::VALUE_REQUIRED, 'Jalali year, e.g. 1405');
        $this->addOption('force', null, InputOption::VALUE_NONE, 'Actually write; without it the command only reports');
        $this->addOption(
            'replace',
            null,
            InputOption::VALUE_NONE,
            'Delete this year rows first — use when previously imported dates were wrong',
        );
        $this->addOption(
            'extra',
            null,
            InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
            'Extra holiday as month/day/title, e.g. --extra=10/12/عید فطر',
        );
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $io    = new SymfonyStyle($input, $output);
        $force = (bool) $input->getOption('force');

        $year = $input->getOption('year');

        if (!is_numeric($year)) {
            $io->error('گزینهٔ --year الزامی است، مثلاً --year=1405');

            return Command::INVALID;
        }

        $year    = (int) $year;
        $entries = self::FIXED;

        foreach ((array) $input->getOption('extra') as $extra) {
            $parts = explode('/', (string) $extra, 3);

            if (count($parts) !== 3 || !is_numeric($parts[0]) || !is_numeric($parts[1])) {
                $io->error(sprintf('قالب --extra باید ماه/روز/عنوان باشد؛ «%s» خوانده نشد.', $extra));

                return Command::INVALID;
            }

            $entries[] = [(int) $parts[0], (int) $parts[1], $parts[2]];
        }

        if (!$force) {
            $io->note('Dry run — nothing will be written. Re-run with --force to apply.');
        }

        // upsert روی `date` کلید می‌خورد، پس ردیفی که با تاریخِ **غلط** نوشته شده هرگز
        // خودش را تصحیح نمی‌کند: اجرای دوباره ردیف درست را کنارش می‌سازد و غلط سرِ
        // جایش می‌ماند. دقیقاً همین بعد از اصلاح باگ تبدیل شمسی پیش آمد.
        if ($force && $input->getOption('replace')) {
            $removed = $this->holidays->purgeYear($year);
            $io->note(sprintf('%d ردیف سال %d پاک شد.', $removed, $year));
        }

        $rows = [];

        foreach ($entries as [$month, $day, $title]) {
            $rows[] = [sprintf('%04d-%02d-%02d', $year, $month, $day), $title];

            if ($force) {
                $this->holidays->upsertNational($year, $month, $day, $title);
            }
        }

        $io->table(['تاریخ شمسی', 'مناسبت'], $rows);
        $io->success(sprintf('%s — %d تعطیل رسمی سال %d', $force ? 'ثبت شد' : 'ثبت می‌شود', count($rows), $year));

        return Command::SUCCESS;
    }
}
