<?php

declare(strict_types=1);

namespace CpCreation\VitiCore\Bridge\Doctrine\Migrations;

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

final class Version20260612121600 extends AbstractMigration
{
    public function getDescription(): string
    {
        return 'Ajoute les variants cibles aux codes promo.';
    }

    public function up(Schema $schema): void
    {
        $schemaManager = $this->sm;

        if (!$schemaManager->tablesExist(['promo_product_variant'])) {
            $this->addSql('CREATE TABLE promo_product_variant (promo_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', product_variant_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', INDEX IDX_542BF5CCD0C07AFF (promo_id), INDEX IDX_542BF5CCA80EF684 (product_variant_id), PRIMARY KEY(promo_id, product_variant_id)) DEFAULT CHARACTER SET UTF8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB');
            $this->addSql('ALTER TABLE promo_product_variant ADD CONSTRAINT FK_542BF5CCD0C07AFF FOREIGN KEY (promo_id) REFERENCES cart_promo (id) ON DELETE CASCADE');
            $this->addSql('ALTER TABLE promo_product_variant ADD CONSTRAINT FK_542BF5CCA80EF684 FOREIGN KEY (product_variant_id) REFERENCES product_variant (id) ON DELETE CASCADE');

            return;
        }

        $indexes = $schemaManager->listTableIndexes('promo_product_variant');
        if (!$this->hasIndexOnColumns($indexes, ['promo_id'])) {
            $this->addSql('CREATE INDEX IDX_542BF5CCD0C07AFF ON promo_product_variant (promo_id)');
        }
        if (!$this->hasIndexOnColumns($indexes, ['product_variant_id'])) {
            $this->addSql('CREATE INDEX IDX_542BF5CCA80EF684 ON promo_product_variant (product_variant_id)');
        }

        $foreignKeys = $schemaManager->listTableForeignKeys('promo_product_variant');
        if (!$this->hasForeignKey($foreignKeys, 'promo_id', 'cart_promo', 'id')) {
            $this->addSql('ALTER TABLE promo_product_variant ADD CONSTRAINT FK_542BF5CCD0C07AFF FOREIGN KEY (promo_id) REFERENCES cart_promo (id) ON DELETE CASCADE');
        }
        if (!$this->hasForeignKey($foreignKeys, 'product_variant_id', 'product_variant', 'id')) {
            $this->addSql('ALTER TABLE promo_product_variant ADD CONSTRAINT FK_542BF5CCA80EF684 FOREIGN KEY (product_variant_id) REFERENCES product_variant (id) ON DELETE CASCADE');
        }
    }

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

    private function hasIndexOnColumns(array $indexes, array $columns): bool
    {
        $expectedColumns = array_map('strtolower', $columns);

        foreach ($indexes as $index) {
            if (array_map('strtolower', $index->getColumns()) === $expectedColumns) {
                return true;
            }
        }

        return false;
    }

    private function hasForeignKey(array $foreignKeys, string $localColumn, string $foreignTable, string $foreignColumn): bool
    {
        foreach ($foreignKeys as $foreignKey) {
            if (
                array_map('strtolower', $foreignKey->getLocalColumns()) === [strtolower($localColumn)]
                && strtolower($foreignKey->getForeignTableName()) === strtolower($foreignTable)
                && array_map('strtolower', $foreignKey->getForeignColumns()) === [strtolower($foreignColumn)]
            ) {
                return true;
            }
        }

        return false;
    }
}
