<?php

declare(strict_types=1);

namespace DoctrineMigrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

/**
 * ERP-116 — Referentiel Pays (Country), 1re iteration : creation de la table
 * `country` + seed des 7 pays (France, Allemagne, Belgique, Espagne, Italie,
 * Royaume-Uni, Suisse). Devient la source unique du select pays, en
 * remplacement de la liste codee en dur cote front.
 *
 * Perimetre minimal voulu : code ISO 3166-1 alpha-2 + libelle FR + ordre
 * d'affichage UNIQUEMENT. Aucune longueur bancaire/fiscale (numero de compte,
 * IBAN, TVA, BIC, SIREN) a ce stade — iteration ulterieure du meme ticket.
 *
 * Pas de FK posee sur les adresses (client_address.country / supplier_address)
 * a cette etape : ces colonnes restent des chaines libres (« France »...), donc
 * aucune migration de donnees ni rupture de l'existant.
 *
 * Namespace racine `DoctrineMigrations` (regle ABSOLUE Starseed n°11) comme les
 * migrations M1/M2 du module Commercial : pas de migrations_path modulaire
 * configure pour Commercial, et le tri par timestamp reste garanti.
 *
 * Seed idempotent `ON CONFLICT (code) DO NOTHING` : la table peut deja porter
 * des donnees en prod lors d'un rejeu. Chaque colonne porte un `COMMENT ON
 * COLUMN` (regle ABSOLUE n°12, garde-fou ColumnsHaveSqlCommentTest) ; la table
 * est aussi mirroree dans ColumnCommentsCatalog pour survivre au
 * `schema:update --force` du setup de test.
 */
final class Version20260609100000 extends AbstractMigration
{
    public function getDescription(): string
    {
        return 'ERP-116 : table country (referentiel pays) + seed des 7 pays.';
    }

    public function up(Schema $schema): void
    {
        $this->addSql(<<<'SQL'
            CREATE TABLE country (
                id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL,
                code VARCHAR(2) NOT NULL,
                name VARCHAR(80) NOT NULL,
                position INT DEFAULT 0 NOT NULL,
                PRIMARY KEY (id)
            )
            SQL);
        $this->addSql('CREATE UNIQUE INDEX uq_country_code ON country (code)');

        $this->comment('country', '_table', 'Referentiel des pays selectionnables dans les adresses (clients/fournisseurs). Perimetre minimal : code ISO + libelle + ordre (pas de longueurs bancaires/fiscales).');
        $this->comment('country', 'id', 'Identifiant interne auto-incremente.');
        $this->comment('country', 'code', 'Code pays ISO 3166-1 alpha-2 (2 lettres MAJUSCULES, ex: FR) — unique (uq_country_code), fige a la creation.');
        $this->comment('country', 'name', 'Libelle FR du pays (≤ 80 caracteres) — valeur stockee telle quelle dans les adresses (country en chaine libre a ce stade).');
        $this->comment('country', 'position', 'Ordre d affichage croissant dans le selecteur pays (tri position ASC puis name ASC ; France en tete).');

        // Seed initial. France en tete (position 10) puis ordre alphabetique.
        // Table fraichement creee, mais ON CONFLICT pour rejouabilite en prod.
        $this->addSql(<<<'SQL'
            INSERT INTO country (code, name, position) VALUES
                ('FR', 'France',       10),
                ('DE', 'Allemagne',    20),
                ('BE', 'Belgique',     30),
                ('ES', 'Espagne',      40),
                ('IT', 'Italie',       50),
                ('GB', 'Royaume-Uni',  60),
                ('CH', 'Suisse',       70)
            ON CONFLICT (code) DO NOTHING
            SQL);
    }

    public function down(Schema $schema): void
    {
        $this->addSql('DROP TABLE country');
    }

    /**
     * Pose un `COMMENT ON TABLE` (colonne speciale `_table`) ou
     * `COMMENT ON COLUMN`. Quoting defensif des identifiants + delimiteur $_$
     * pour ne pas casser sur les apostrophes des descriptions.
     */
    private function comment(string $table, string $column, string $description): void
    {
        $quotedTable = '"'.str_replace('"', '""', $table).'"';

        if ('_table' === $column) {
            $this->addSql(sprintf('COMMENT ON TABLE %s IS $_$%s$_$', $quotedTable, $description));

            return;
        }

        $this->addSql(sprintf(
            'COMMENT ON COLUMN %s.%s IS $_$%s$_$',
            $quotedTable,
            '"'.str_replace('"', '""', $column).'"',
            $description,
        ));
    }
}
