<?php

declare(strict_types=1);

namespace App\Console\Commands;

use App\Services\MonthlyPartitionManager;
use Illuminate\Console\Command;
use Illuminate\Support\Carbon;

/**
 * Создаёт ежемесячные партиции для всех таблиц в MonthlyPartitionManager::PARTITIONED_TABLES
 * на N месяцев вперёд от текущей даты.
 *
 * Hole #2 (23.05.2026): расширен с 2 бизнес-таблиц до 9 (+ 7 audit-таблиц).
 *
 * Замена `pg_partman` на native Windows-стеке (расширение недоступно
 * без сборки из исходников). Запускается ежесуточно через Windows Task
 * Scheduler / cron — идемпотентна (проверяет pg_class перед CREATE).
 *
 * По дефолту 2 месяца вперёд (паритет с инициализацией schema.sql:
 * 6 партиций при `migrate:fresh`, последующие месяцы — этим cron'ом).
 *
 * Источник: MonthlyPartitionManager::PARTITIONED_TABLES (единственный SoT списка таблиц);
 * project_phase1_strategy.md (pg_partman заменён ручным cron'ом).
 */
class PartitionsCreateMonths extends Command
{
    /** @var string */
    protected $signature = 'partitions:create-months {--ahead=2 : Сколько месяцев вперёд создать партиций}';

    /** @var string */
    protected $description = 'Создаёт ежемесячные партиции для всех партиционированных таблиц на N месяцев вперёд (idempotent)';

    public function handle(MonthlyPartitionManager $manager): int
    {
        $ahead = max(1, (int) $this->option('ahead'));
        $now = Carbon::now()->startOfMonth();

        $created = 0;
        $skipped = 0;

        for ($i = 0; $i <= $ahead; $i++) {
            $monthStart = $now->copy()->addMonths($i);

            foreach (array_keys(MonthlyPartitionManager::PARTITIONED_TABLES) as $table) {
                $partitionName = $manager->partitionName($table, $monthStart);

                if ($manager->ensureMonth($table, $monthStart)) {
                    $created++;
                    $this->info("  create <fg=green>{$partitionName}</>");
                } else {
                    $skipped++;
                    $this->line("  skip   <fg=gray>{$partitionName}</> (already exists)");
                }
            }
        }

        $this->newLine();
        $this->info("Done: {$created} created, {$skipped} skipped (ahead={$ahead}).");

        return self::SUCCESS;
    }
}
