<?php

declare(strict_types=1);

namespace DoctrineMigrations;

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

/**
 * Finish categories migration:
 *  - Remove orphan rows from doctor_expertise (bad test data pointing to province IDs)
 *  - Add FK constraint to doctor_expertise.service_id → doctor_services
 *  - Migrate doctor_cities.category_id → city_id with FK to cities
 *  - Drop categories table
 */
final class Version20260610140853 extends AbstractMigration
{
    public function getDescription(): string
    {
        return 'Finish categories migration: fix doctor_expertise orphans, doctor_cities → city_id, drop categories';
    }

    public function up(Schema $schema): void
    {
        // NOTE: All of this work is also performed by Version20260610103401
        // (same day, earlier timestamp). On a fresh database that migration runs
        // first and leaves doctor_expertise / doctor_cities already converted and
        // the categories table already dropped, so re-running these statements
        // verbatim fails (errno 121: duplicate constraint FK_ED88BE60ED5CA9E6).
        //
        // Existing databases, however, may have applied THIS migration without
        // 103401 having done the conversion. So instead of deleting this file we
        // make every step idempotent: each action is guarded against the state
        // 103401 leaves behind, so the migration is a safe no-op on a fresh DB
        // and still finishes the conversion on an older DB.

        // doctor_expertise: ensure category_id → service_id + FK exist (only if not already done by 103401)
        $this->addSql(<<<'SQL'
            DROP PROCEDURE IF EXISTS __mig_140853
        SQL);
        $this->addSql(<<<'SQL'
            CREATE PROCEDURE __mig_140853()
            BEGIN
                DECLARE db VARCHAR(64);
                SET db = DATABASE();

                -- doctor_expertise.service_id FK
                IF NOT EXISTS (
                    SELECT 1 FROM information_schema.TABLE_CONSTRAINTS
                    WHERE CONSTRAINT_SCHEMA = db AND TABLE_NAME = 'doctor_expertise'
                      AND CONSTRAINT_NAME = 'FK_ED88BE60ED5CA9E6'
                ) THEN
                    DELETE FROM doctor_expertise WHERE service_id NOT IN (SELECT id FROM doctor_services);
                    ALTER TABLE doctor_expertise
                        ADD CONSTRAINT FK_ED88BE60ED5CA9E6 FOREIGN KEY (service_id) REFERENCES doctor_services (id);
                    CREATE INDEX IDX_ED88BE60ED5CA9E6 ON doctor_expertise (service_id);
                END IF;

                -- doctor_cities: category_id → city_id with FK to cities
                IF EXISTS (
                    SELECT 1 FROM information_schema.COLUMNS
                    WHERE TABLE_SCHEMA = db AND TABLE_NAME = 'doctor_cities'
                      AND COLUMN_NAME = 'category_id'
                ) THEN
                    DELETE FROM doctor_cities WHERE category_id NOT IN (SELECT id FROM cities);
                    ALTER TABLE doctor_cities DROP FOREIGN KEY `FK_7DC181E612469DE2`;
                    DROP INDEX IDX_7DC181E612469DE2 ON doctor_cities;
                    ALTER TABLE doctor_cities CHANGE category_id city_id INT NOT NULL, DROP PRIMARY KEY, ADD PRIMARY KEY (doctor_id, city_id);
                    ALTER TABLE doctor_cities ADD CONSTRAINT FK_7DC181E68BAC62AF FOREIGN KEY (city_id) REFERENCES cities (id);
                    CREATE INDEX IDX_7DC181E68BAC62AF ON doctor_cities (city_id);
                END IF;

                -- Drop the now-unused categories table
                IF EXISTS (
                    SELECT 1 FROM information_schema.TABLES
                    WHERE TABLE_SCHEMA = db AND TABLE_NAME = 'categories'
                ) THEN
                    DROP TABLE categories;
                END IF;
            END
        SQL);
        $this->addSql('CALL __mig_140853()');
        $this->addSql('DROP PROCEDURE __mig_140853');
    }

    public function down(Schema $schema): void
    {
        $this->addSql('ALTER TABLE doctor_expertise DROP FOREIGN KEY FK_ED88BE60ED5CA9E6');
        $this->addSql('DROP INDEX IDX_ED88BE60ED5CA9E6 ON doctor_expertise');

        $this->addSql('ALTER TABLE doctor_cities DROP FOREIGN KEY FK_7DC181E68BAC62AF');
        $this->addSql('DROP INDEX IDX_7DC181E68BAC62AF ON doctor_cities');
        $this->addSql('ALTER TABLE doctor_cities CHANGE city_id category_id INT NOT NULL, DROP PRIMARY KEY, ADD PRIMARY KEY (doctor_id, category_id)');

        $this->addSql("
            CREATE TABLE categories (
                id INT AUTO_INCREMENT NOT NULL,
                uuid VARCHAR(36) NOT NULL,
                bundle VARCHAR(32) NOT NULL,
                label VARCHAR(255) DEFAULT NULL,
                status SMALLINT NOT NULL,
                parent_id INT DEFAULT NULL,
                weight INT NOT NULL,
                logo_id INT DEFAULT NULL,
                title VARCHAR(255) DEFAULT NULL,
                representation_id INT DEFAULT NULL,
                contact_phone VARCHAR(255) DEFAULT NULL,
                email VARCHAR(255) DEFAULT NULL,
                description LONGTEXT DEFAULT NULL,
                slogan VARCHAR(255) DEFAULT NULL,
                domain VARCHAR(255) DEFAULT NULL,
                keywords VARCHAR(255) DEFAULT NULL,
                footer_description LONGTEXT DEFAULT NULL,
                footer_disclaimer LONGTEXT DEFAULT NULL,
                social_media LONGTEXT DEFAULT NULL,
                logo_url VARCHAR(500) DEFAULT NULL,
                PRIMARY KEY (id)
            ) DEFAULT CHARACTER SET utf8mb4
        ");

        $this->addSql('ALTER TABLE doctor_cities ADD CONSTRAINT `FK_7DC181E612469DE2` FOREIGN KEY (category_id) REFERENCES categories (id)');
        $this->addSql('CREATE INDEX IDX_7DC181E612469DE2 ON doctor_cities (category_id)');
    }
}
