<?php

declare(strict_types=1);

use Phinx\Migration\AbstractMigration;

final class TaskSr62767 extends AbstractMigration
{
    public function up(): void
    {
        $this->execute(<<<SQL
            INSERT INTO sistema.configuracao_sistema (ds_nome, ds_valor, id_usuario_criacao)
            VALUES('DATA_CORTE_CONDICOES_GERAIS_SUSEPE_2026', '2026-01-17', 2068);

            CREATE TABLE produto.configuracao_data_corte (
                id SERIAL PRIMARY KEY,
                dt_corte DATE NOT NULL,
                ds_data_corte VARCHAR(255)
            ) INHERITS (public.campos_default);

            INSERT INTO produto.configuracao_data_corte (dt_corte, ds_data_corte, id_usuario_criacao)
                VALUES
                    ('2000-01-01','Textos antigos de configuração', 2068),
                    ('2025-12-10','Textos referentes a Nova Lei de Seguro', 2068),
                    ('2026-01-17','Textos referentes as Condições Gerais aprovadas pela SUSEP em 2026', 2068);

            -- CONFIGURAÇÃO CONDIÇÃO ESPECIAL
            CREATE TABLE produto.condicao_especial_configuracao (
                id SERIAL PRIMARY KEY,
                id_condicao_especial INTEGER NOT NULL,
                ds_condicao_especial TEXT NOT NULL,
                dt_inicio_validade DATE NOT NULL,
                CONSTRAINT fk_id_condicao_especial FOREIGN KEY (id_condicao_especial) REFERENCES produto.condicoes_especiais (id)
            ) INHERITS (public.campos_default);

            -- insere registros antigos
            INSERT INTO produto.condicao_especial_configuracao (id_condicao_especial, ds_condicao_especial, id_usuario_criacao, fl_ativo, dt_inicio_validade)
            SELECT
                id,
                ds_condicao_especial,
                id_usuario_criacao,
                true,
                '2000-01-01'
            FROM produto.condicoes_especiais;

            INSERT INTO produto.condicao_especial_configuracao (id_condicao_especial, ds_condicao_especial, id_usuario_criacao, fl_ativo, dt_inicio_validade)
            SELECT
                id,
                ds_condicao_especial,
                id_usuario_criacao,
                true,
                '2025-12-10'
            FROM produto.condicoes_especiais;

            -- insere registros novos
            INSERT INTO produto.condicao_especial_configuracao (id_condicao_especial, ds_condicao_especial, id_usuario_criacao, fl_ativo, dt_inicio_validade)
            SELECT
                condicoes_especiais.id,
                'Verifique a carência da cobertura principal e das coberturas adicionais conforme estabelecido nas Condições Gerais, Especiais, Adicionais, Complementares e Particulares do Seguro vigentes no momento da contratação.',
                condicoes_especiais.id_usuario_criacao,
                true,
                '2026-01-17'
            FROM (
                SELECT
                    condicoes_especiais.id
                FROM produto.condicoes_especiais
                INNER JOIN produto.produtos_coberturas_condicoes_especiais
                    ON produtos_coberturas_condicoes_especiais.id_condicao_especial = condicoes_especiais.id
                INNER JOIN produto.produtos_coberturas
                    ON produtos_coberturas.id_produto = produtos_coberturas_condicoes_especiais.id_produto
                        AND produtos_coberturas.id_cobertura = produtos_coberturas_condicoes_especiais.id_cobertura
                        AND produtos_coberturas.fl_cobertura_principal IS TRUE
                GROUP BY condicoes_especiais.id
            ) AS condicoes_vinculadas_cobertura_principal
            INNER JOIN produto.condicoes_especiais
                ON condicoes_especiais.id = condicoes_vinculadas_cobertura_principal.id;

            ALTER TABLE produto.condicoes_especiais DROP COLUMN ds_condicao_especial;

            -- ADICIONA COLUNA dt_inicio_validade
            ALTER TABLE produto.produto_config ADD COLUMN dt_inicio_validade DATE;
            ALTER TABLE produto.produto_cobertura_config ADD COLUMN dt_inicio_validade DATE;

            -- INSERIR DATA DE INÍCIO VALIDADE NA TABELA DE CONFIGURAÇÃO DE PRODUTO
            WITH primeiro_registro AS (
                SELECT
                    id
                FROM (
                    SELECT
                        id,
                        id_produto,
                        fl_ativo,
                        ROW_NUMBER() OVER (
                            PARTITION BY id_produto
                            ORDER BY dt_criacao ASC, id ASC
                        ) AS rn
                    FROM produto.produto_config
                )AS aux
                WHERE rn = 1
            )
            UPDATE produto.produto_config SET dt_inicio_validade = '2000-01-01'
            FROM primeiro_registro
            WHERE primeiro_registro.id = produto_config.id;

            UPDATE produto.produto_config SET dt_inicio_validade = '2025-12-10'
            FROM produto.produtos p1
            INNER JOIN (
                SELECT count(id_produto) AS contador, id_produto, id_safra
                FROM produto.produto_config
                INNER JOIN produto.produtos ON produtos.id = produto_config.id_produto
                GROUP BY id_produto, id_safra
            ) p2
                ON p1.id = p2.id_produto AND p2.contador > 1
            WHERE
                produto_config.id_produto = p1.id
                AND dt_inicio_validade IS NULL
                AND p2.id_safra >= 28;

            UPDATE produto.produto_config SET dt_inicio_validade = '2000-01-01', fl_ativo = FALSE WHERE dt_inicio_validade IS NULL;

            UPDATE produto.produto_config SET fl_ativo = false;

            UPDATE produto.produto_config SET fl_ativo = TRUE
            WHERE id IN (
                SELECT MAX(id)
                FROM produto.produto_config
                GROUP BY id_produto, dt_inicio_validade
            );

            INSERT INTO produto.produto_config (id_produto, ds_frase_restricoes, ds_url_condicoes, ds_frase_risco, ds_frase_padrao_orcamento, id_modelo_vistoria_previa, fl_ativo, dt_inicio_validade)
            SELECT
                id_produto,
                ds_frase_restricoes,
                ds_url_condicoes,
                ds_frase_risco,
                ds_frase_padrao_orcamento,
                id_modelo_vistoria_previa,
                true,
                '2026-01-17'
            FROM
                produto.produto_config
            WHERE
                dt_inicio_validade = '2025-12-10'
                AND fl_ativo IS TRUE;

            -- INSERIR DATA DE INÍCIO VALIDADE NA TABELA DE CONFIGURAÇÃO DE COBERTURA
            WITH primeiro_registro AS (
                SELECT
                    id
                FROM (
                    SELECT
                        id,
                        id_produto,
                        id_cobertura,
                        fl_ativo,
                        ROW_NUMBER() OVER (
                            PARTITION BY id_produto, id_cobertura
                            ORDER BY dt_criacao ASC, id ASC
                        ) AS rn
                    FROM produto.produto_cobertura_config
                ) AS aux
                WHERE rn = 1
            )
            UPDATE produto.produto_cobertura_config SET dt_inicio_validade = '2000-01-01'
            FROM primeiro_registro
            WHERE primeiro_registro.id = produto_cobertura_config.id;

            UPDATE produto.produto_cobertura_config SET dt_inicio_validade = '2025-12-10'
            FROM produto.produtos_coberturas p1
            INNER JOIN (
                SELECT
                    count(produto_cobertura_config.id_produto) AS contador,
                    produto_cobertura_config.id_produto,
                    produto_cobertura_config.id_cobertura,
                    produtos.id_safra
                FROM produto.produto_cobertura_config
                INNER JOIN produto.produtos_coberturas
                    ON produtos_coberturas.id_produto = produto_cobertura_config.id_produto
                        AND produtos_coberturas.id_cobertura = produto_cobertura_config.id_cobertura
                INNER JOIN produto.produtos
                    ON produtos.id = produto_cobertura_config.id_produto
                GROUP BY
                    produto_cobertura_config.id_produto,
                    produto_cobertura_config.id_cobertura,
                    produtos.id_safra
            ) p2
                ON p1.id_produto = p2.id_produto
                    AND p1.id_cobertura = p2.id_cobertura
                    AND p2.contador > 1
            WHERE
                produto_cobertura_config.id_produto = p1.id_produto
                AND dt_inicio_validade IS NULL
                AND produto_cobertura_config.id_cobertura = p1.id_cobertura
                AND p2.id_safra >= 28;

            UPDATE produto.produto_cobertura_config SET dt_inicio_validade = '2000-01-01' WHERE dt_inicio_validade IS NULL;

            UPDATE produto.produto_cobertura_config SET fl_ativo = false;

            UPDATE produto.produto_cobertura_config SET fl_ativo = TRUE
            WHERE id IN (
                SELECT MAX(id)
                FROM produto.produto_cobertura_config
                GROUP BY id_produto, id_cobertura, dt_inicio_validade
            );

            ALTER TABLE produto.produto_config ALTER COLUMN dt_inicio_validade SET NOT NULL;
            ALTER TABLE produto.produto_cobertura_config ALTER COLUMN dt_inicio_validade SET NOT NULL;
            ALTER TABLE produto.condicao_especial_configuracao ALTER COLUMN dt_inicio_validade SET NOT NULL;
SQL
        );
    }

    public function down(): void
    {
        $this->execute(<<<SQL
            DROP TABLE produto.configuracao_data_corte;

            ALTER TABLE produto.condicoes_especiais
                ADD COLUMN ds_condicao_especial TEXT;

            UPDATE produto.condicoes_especiais
            SET
                ds_condicao_especial = conf.ds_condicao_especial
            FROM produto.condicao_especial_configuracao AS conf
            INNER JOIN (
                SELECT
                    MIN(id) AS id
                FROM
                    produto.condicao_especial_configuracao
                GROUP BY id_condicao_especial
            ) AS configuracao_original ON configuracao_original.id = conf.id
            WHERE condicoes_especiais.id = conf.id_condicao_especial;

            DELETE FROM sistema.configuracao_sistema WHERE ds_nome = 'DATA_CORTE_CONDICOES_GERAIS_SUSEPE_2026';
            DROP TABLE produto.condicao_especial_configuracao;

            ALTER TABLE produto.produto_config DROP COLUMN dt_inicio_validade;
            ALTER TABLE produto.produto_cobertura_config DROP COLUMN dt_inicio_validade;

            UPDATE produto.produto_config SET fl_ativo = FALSE;
            UPDATE produto.produto_cobertura_config SET fl_ativo = FALSE;

            UPDATE produto.produto_config SET fl_ativo = TRUE
            WHERE id IN (
                SELECT MAX(id)
                FROM produto.produto_config
                GROUP BY id_produto
            );

            UPDATE produto.produto_cobertura_config SET fl_ativo = TRUE
            WHERE id IN (
                SELECT MAX(id)
                FROM produto.produto_cobertura_config
                GROUP BY id_produto, id_cobertura
            );
SQL
        );
    }
}
