<?php

declare(strict_types=1);

namespace DoctrineMigrations;

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

final class Version20260506140000_FixComposantCascadeFKs extends AbstractMigration
{
    public function getDescription(): string
    {
        return 'Add missing CASCADE FKs documents.composantid and machine_component_links.composantid; cleanup pre-existing orphan rows';
    }

    public function up(Schema $schema): void
    {
        // 1. Trace des suppressions à venir dans audit_logs (actor = NULL = "system").
        //    On copie un snapshot minimal avant DELETE pour cohérence avec les autres "delete".
        $this->addSql(<<<'SQL'
            INSERT INTO audit_logs (id, entitytype, entityid, action, snapshot, actorprofileid, createdat)
            SELECT
              'cl' || substring(md5(random()::text || clock_timestamp()::text), 1, 24),
              'document',
              d.id,
              'delete',
              json_build_object(
                'id', d.id,
                'name', d.name,
                'filename', d.filename,
                'composantId', d.composantid,
                'note', 'Cleaned by FK cascade fix migration (Version20260506140000) - referenced composant no longer existed'
              ),
              NULL,
              NOW()
            FROM documents d
            WHERE d.composantid IS NOT NULL
              AND d.composantid NOT IN (SELECT id FROM composants)
            SQL);

        $this->addSql(<<<'SQL'
            INSERT INTO audit_logs (id, entitytype, entityid, action, snapshot, actorprofileid, createdat)
            SELECT
              'cl' || substring(md5(random()::text || clock_timestamp()::text), 1, 24),
              'machine_component_link',
              l.id,
              'delete',
              json_build_object(
                'id', l.id,
                'machineId', l.machineid,
                'composantId', l.composantid,
                'note', 'Cleaned by FK cascade fix migration (Version20260506140000) - referenced composant no longer existed'
              ),
              NULL,
              NOW()
            FROM machine_component_links l
            WHERE l.composantid IS NOT NULL
              AND l.composantid NOT IN (SELECT id FROM composants)
            SQL);

        // 2. Nettoyage des orphelins.
        $this->addSql(<<<'SQL'
            DELETE FROM documents
            WHERE composantid IS NOT NULL
              AND composantid NOT IN (SELECT id FROM composants)
            SQL);

        $this->addSql(<<<'SQL'
            DELETE FROM machine_component_links
            WHERE composantid IS NOT NULL
              AND composantid NOT IN (SELECT id FROM composants)
            SQL);

        // 3. Ajout idempotent des 2 FK manquantes (alignement avec les entités Doctrine).
        $this->addSql(<<<'SQL'
            DO $$ BEGIN
              IF NOT EXISTS (
                SELECT 1 FROM information_schema.table_constraints
                WHERE constraint_name = 'fk_documents_composant' AND table_name = 'documents'
              ) THEN
                ALTER TABLE documents ADD CONSTRAINT fk_documents_composant
                  FOREIGN KEY (composantid) REFERENCES composants(id) ON DELETE CASCADE;
              END IF;
            END $$;
            SQL);

        $this->addSql(<<<'SQL'
            DO $$ BEGIN
              IF NOT EXISTS (
                SELECT 1 FROM information_schema.table_constraints
                WHERE constraint_name = 'fk_mcl_composant' AND table_name = 'machine_component_links'
              ) THEN
                ALTER TABLE machine_component_links ADD CONSTRAINT fk_mcl_composant
                  FOREIGN KEY (composantid) REFERENCES composants(id) ON DELETE CASCADE;
              END IF;
            END $$;
            SQL);
    }

    public function down(Schema $schema): void
    {
        $this->addSql('ALTER TABLE documents DROP CONSTRAINT IF EXISTS fk_documents_composant');
        $this->addSql('ALTER TABLE machine_component_links DROP CONSTRAINT IF EXISTS fk_mcl_composant');
    }
}
