<?php
declare(strict_types=1);

use Phinx\Migration\AbstractMigration;

final class Task2311171701 extends AbstractMigration
{
    public function up(): void
    {
        $this->upMenus();
        $this->upTables();
    }

    public function down(): void
    {
        $this->downMenus();
        $this->downTables();
    }

    private function downMenus()
    {
        $idCriteriosRestricao = $this->getIdCriteriosRestricao();
        $idRestricoes = $this->getIdRestricoes();
        $rowsAcoesFilha = $this->getIdCriteriosRestricaoAcoesFilha((int)$idCriteriosRestricao);

        foreach ($rowsAcoesFilha as $row) {
            $this->execute(<<<SQL
DELETE FROM sistema.roles_acao WHERE id_acao = {$row['id']};
SQL
            );
        }

        $rowsRestricoesAcoesFilha = $this->getIdRestricoesAcoesFilha((int)$idRestricoes);

        foreach ($rowsRestricoesAcoesFilha as $row) {
            $this->execute(<<<SQL
DELETE FROM sistema.roles_acao WHERE id_acao = {$row['id']};
SQL
            );
        }

        $this->execute(<<<SQL
DELETE FROM sistema.roles_acao WHERE id_acao = {$idCriteriosRestricao};
DELETE FROM sistema.roles_acao WHERE id_acao = {$idRestricoes};

DELETE FROM sistema.acao WHERE id_parent = {$idCriteriosRestricao};
DELETE FROM sistema.acao WHERE id = {$idCriteriosRestricao};
DELETE FROM sistema.acao WHERE id_parent = {$idRestricoes};
DELETE FROM sistema.acao WHERE id = {$idRestricoes};
SQL
        );
    }

    private function downTables()
    {
        $this->execute(<<<SQL
DROP TABLE produto.validacoes_restricoes_criterios_propostas_excecoes;
DROP TABLE produto.validacoes_restricoes_criterios_tipo_solo;
DROP TABLE produto.validacoes_restricoes_criterios_sistema_plantio;
DROP TABLE produto.validacoes_restricoes_criterios_semeadura;
DROP TABLE produto.validacoes_restricoes_criterios;
DROP TABLE produto.validacoes_restricoes_municipios;
DROP TABLE produto.validacoes_restricoes_coberturas;
DROP TABLE produto.validacoes_restricoes_produtos;
DROP TABLE produto.validacoes_restricoes_culturas;
DROP TABLE produto.validacoes_restricoes;
DROP TABLE produto.criterios_restricao;
SQL
        );
    }

    private function getIdCriteriosRestricao()
    {
        $sql = $this->query("SELECT id FROM sistema.acao WHERE ds_label = 'Critérios para Restrição' AND ds_module = 'produto' AND ds_controller = 'criteriosrestricao'");
        $rows = $sql->fetchAll();

        return $rows[0]['id'];
    }

    private function getIdCriteriosRestricaoAcoesFilha(int $id)
    {
        $sql = $this->query("SELECT id FROM sistema.acao WHERE id_parent = {$id}");
        return $sql->fetchAll();
    }

    private function getIdRestricoes()
    {
        $sql = $this->query("SELECT id FROM sistema.acao WHERE ds_label = 'Restrições' AND ds_module = 'produto' AND ds_controller = 'validacoesrestricoes'");
        $rows = $sql->fetchAll();

        return $rows[0]['id'];
    }

    private function getIdRestricoesAcoesFilha(int $id)
    {
        $sql = $this->query("SELECT id FROM sistema.acao WHERE id_parent = {$id}");
        return $sql->fetchAll();
    }

    private function upMenus()
    {
        $this->execute(<<<SQL
INSERT INTO sistema.acao (ds_label, ds_module, ds_controller, ds_action, ds_param, id_parent, ds_image, ds_descricao, fl_tipo, dt_criacao, id_usuario_criacao, id) 
                  VALUES ('Critérios para Restrição', 'produto', 'criteriosrestricao', 'index', '', 35, '', 'Critérios para Restrição', 'M', '2024-04-19 10:57:54', 3379, nextval('sistema.acao_id_seq'::regclass)),
                         ('Restrições', 'produto', 'validacoesrestricoes', 'index', '', 47, '', 'Restrições', 'M', '2024-04-19 11:12:42', 3379, nextval('sistema.acao_id_seq'::regclass)),
                         ('Relacionar Municípios', 'produto', 'validacoesrestricoes', 'relacionarmunicipios', '', 2081, '', 'Relacionar Municípios', 'L', '2024-05-15 11:38:39', 3379, nextval('sistema.acao_id_seq'::regclass)),
                         ('Configurar', 'produto', 'validacoesrestricoes', 'configurar', '', 2081, '', 'Configurar', 'L', '2024-05-15 11:38:39', 3379, nextval('sistema.acao_id_seq'::regclass)),
                         ('Relacionar Propostas - Exceções', 'produto', 'validacoesrestricoescriterios', 'relacionarpropostasexcecoes', '', 2081, '', 'Relacionar Propostas - Exceções', 'L', '2024-05-15 11:38:39', 3379, nextval('sistema.acao_id_seq'::regclass)),
                         ('Copiar', 'produto', 'validacoesrestricoes', 'copiar', '', 2081, '', 'Copiar', 'L', '2024-05-15 11:38:39', 3379, nextval('sistema.acao_id_seq'::regclass));
SQL
        );

        $idCriteriosRestricao = $this->getIdCriteriosRestricao();
        $idRestricoes = $this->getIdRestricoes();

        $this->execute(<<<SQL
INSERT INTO sistema.acao (ds_label, ds_module, ds_controller, ds_action, ds_param, id_parent, ds_image, nr_ordem, fl_tipo, dt_criacao, id_usuario_criacao, id)
                  VALUES ('Editar', 'produto', 'criteriosrestricao', 'form', 'id', {$idCriteriosRestricao}, 'edit.png', '0', 'L', '2024-04-19 10:57:54', 3379, nextval('sistema.acao_id_seq'::regclass)),
                         ('Ativar/Desativar', 'produto', 'criteriosrestricao', 'active', 'id', {$idCriteriosRestricao}, 'active.png', '1', 'L', '2024-04-19 10:57:54', 3379, nextval('sistema.acao_id_seq'::regclass)),
                         ('Deletar', 'produto', 'criteriosrestricao', 'delete', 'id', {$idCriteriosRestricao}, 'delete.png', '2', 'L', '2024-04-19 10:57:55', 3379, nextval('sistema.acao_id_seq'::regclass)),
                         ('Editar', 'produto', 'validacoesrestricoes', 'form', 'id', {$idRestricoes}, 'edit.png', '0', 'L', '2024-04-24 13:36:03', 3379, nextval('sistema.acao_id_seq'::regclass)),
                         ('Ativar/Desativar', 'produto', 'validacoesrestricoes', 'active', 'id', {$idRestricoes}, 'active.png', '1', 'L', '2024-04-24 13:36:03', 3379, nextval('sistema.acao_id_seq'::regclass)),
                         ('Deletar', 'produto', 'validacoesrestricoes', 'delete', 'id', {$idRestricoes}, 'delete.png', '2', 'L', '2024-04-24 13:36:03', 3379, nextval('sistema.acao_id_seq'::regclass));

INSERT INTO sistema.roles_acao (id_role, id_acao)
                        VALUES (20, {$idCriteriosRestricao}),
                               (20, {$idRestricoes});
SQL
        );

        $rowsCriteriosRestricaoAcoesFilha = $this->getIdCriteriosRestricaoAcoesFilha((int)$idCriteriosRestricao);

        foreach ($rowsCriteriosRestricaoAcoesFilha as $row) {
            $this->execute(<<<SQL
INSERT INTO sistema.roles_acao (id_role, id_acao) VALUES (20, {$row['id']});
SQL
            );
        }

        $rowsRestricoesAcoesFilha = $this->getIdRestricoesAcoesFilha((int)$idRestricoes);

        foreach ($rowsRestricoesAcoesFilha as $row) {
            $this->execute(<<<SQL
INSERT INTO sistema.roles_acao (id_role, id_acao) VALUES (20, {$row['id']});
SQL
            );
        }
    }

    private function upTables()
    {
        $this->execute(<<<SQL
CREATE TABLE produto.criterios_restricao(
  id SERIAL NOT NULL,
  ds_nome VARCHAR(100) NOT NULL,
  ds_mensagem TEXT NOT NULL,
  CONSTRAINT pk_criterios_restricao PRIMARY KEY (id)
) INHERITS (public.campos_default);

INSERT INTO produto.criterios_restricao (ds_nome, ds_mensagem)
                                 VALUES ('1º ano de Plantio', 'A informação na coluna 1º ano de plantio não está de acordo com as Restrições para Cobertura dos Riscos, em virtude disso, o valor segurado deve ser zerado.'),
                                        ('1º ou 2º ano de Plantio', 'A informação na coluna 1º ou 2º ano de plantio não está de acordo com as Restrições para Cobertura dos Riscos, em virtude disso, o valor segurado deve ser zerado.'),
                                        ('Data Inicial e/ou Final de semeadura', 'A data de semeadura informada não está de acordo com as Restrições para Cobertura dos Riscos, em virtude disso, o valor segurado deve ser zerado.'),
                                        ('Sistema de Plantio', 'O sistema de plantio selecionado não está de acordo com as Restrições para Cobertura dos Riscos, em virtude disso, o valor segurado deve ser zerado.'),
                                        ('Tipo de solo', 'O solo selecionado não está de acordo com as Restrições para Cobertura dos Riscos, em virtude disso, o valor segurado deve ser zerado.'),
                                        ('Variedades Transgênicas', 'A variedade selecionada não está de acordo com as Restrições para Cobertura dos Riscos, em virtude disso, o valor segurado deve ser zerado.');

CREATE TABLE produto.validacoes_restricoes(
  id SERIAL NOT NULL,
  ds_nome VARCHAR(100) NOT NULL,
  id_safra INT NOT NULL,
  CONSTRAINT pk_validacoes_restricoes PRIMARY KEY (id),
  CONSTRAINT fk_validacoes_restricoes FOREIGN KEY (id_safra) REFERENCES produto.safras (id)
) INHERITS (public.campos_default);

CREATE TABLE produto.validacoes_restricoes_culturas(
  id SERIAL NOT NULL,
  id_validacoes_restricoes INT NOT NULL,
  id_cultura INT NOT NULL,
  CONSTRAINT pk_validacoes_restricoes_culturas PRIMARY KEY (id),
  CONSTRAINT fk_validacoes_restricoes_culturas_restricoes FOREIGN KEY (id_validacoes_restricoes) REFERENCES produto.validacoes_restricoes (id),
  CONSTRAINT fk_validacoes_restricoes_culturas_culturas FOREIGN KEY (id_cultura) REFERENCES produto.culturas (id)
) INHERITS (public.campos_default);

CREATE TABLE produto.validacoes_restricoes_produtos(
  id SERIAL NOT NULL,
  id_validacoes_restricoes INT NOT NULL,
  id_produto INT NOT NULL,
  CONSTRAINT pk_validacoes_restricoes_produtos PRIMARY KEY (id),
  CONSTRAINT fk_validacoes_restricoes_produtos_restricoes FOREIGN KEY (id_validacoes_restricoes) REFERENCES produto.validacoes_restricoes (id),
  CONSTRAINT fk_validacoes_restricoes_produtos_produtos FOREIGN KEY (id_produto) REFERENCES produto.produtos (id)
) INHERITS (public.campos_default);

CREATE TABLE produto.validacoes_restricoes_coberturas(
  id SERIAL NOT NULL,
  id_validacoes_restricoes INT NOT NULL,
  id_cobertura INT NOT NULL,
  CONSTRAINT pk_validacoes_restricoes_coberturas PRIMARY KEY (id),
  CONSTRAINT fk_validacoes_restricoes_coberturas_restricoes FOREIGN KEY (id_validacoes_restricoes) REFERENCES produto.validacoes_restricoes (id),
  CONSTRAINT fk_validacoes_restricoes_coberturas_coberturas FOREIGN KEY (id_cobertura) REFERENCES produto.coberturas (id)
) INHERITS (public.campos_default);

CREATE TABLE produto.validacoes_restricoes_municipios(
  id SERIAL NOT NULL,
  id_validacoes_restricoes INT NOT NULL,
  id_municipio INT NOT NULL,
  CONSTRAINT pk_validacoes_restricoes_municipios PRIMARY KEY (id),
  CONSTRAINT fk_validacoes_restricoes_municipios_restricoes FOREIGN KEY (id_validacoes_restricoes) REFERENCES produto.validacoes_restricoes (id),
  CONSTRAINT fk_validacoes_restricoes_municipios_municipios FOREIGN KEY (id_municipio) REFERENCES sistema.municipios (id)
) INHERITS (public.campos_default);

CREATE TABLE produto.validacoes_restricoes_criterios(
  id SERIAL NOT NULL,
  id_validacoes_restricoes INT NOT NULL,
  id_criterios_restricao INT NOT NULL,
  CONSTRAINT pk_validacoes_restricoes_criterios PRIMARY KEY (id),
  CONSTRAINT fk_validacoes_restricoes_criterios_restricoes FOREIGN KEY (id_validacoes_restricoes) REFERENCES produto.validacoes_restricoes (id),
  CONSTRAINT fk_validacoes_restricoes_criterios_criterios FOREIGN KEY (id_criterios_restricao) REFERENCES produto.criterios_restricao (id)
) INHERITS (public.campos_default);

CREATE TABLE produto.validacoes_restricoes_criterios_semeadura(
  id SERIAL NOT NULL,
  id_validacoes_restricoes_criterios INT NOT NULL,
  dt_semeadura_inicio DATE,
  dt_semeadura_fim DATE,
  CONSTRAINT pk_validacoes_restricoes_criterios_semeadura PRIMARY KEY (id),
  CONSTRAINT fk_validacoes_restricoes_criterios_semeadura_validacoes FOREIGN KEY (id_validacoes_restricoes_criterios) REFERENCES produto.validacoes_restricoes_criterios (id)
) INHERITS (public.campos_default);

CREATE TABLE produto.validacoes_restricoes_criterios_sistema_plantio(
  id SERIAL NOT NULL,
  id_validacoes_restricoes_criterios INT NOT NULL,
  id_sistema_plantio INT NOT NULL,
  CONSTRAINT pk_validacoes_restricoes_criterios_sistema_plantio PRIMARY KEY (id),
  CONSTRAINT fk_validacoes_restricoes_criterios_sistema_plantio_validacoes FOREIGN KEY (id_validacoes_restricoes_criterios) REFERENCES produto.validacoes_restricoes_criterios (id)
) INHERITS (public.campos_default);

CREATE TABLE produto.validacoes_restricoes_criterios_tipo_solo(
  id SERIAL NOT NULL,
  id_validacoes_restricoes_criterios INT NOT NULL,
  id_tipo_solo INT NOT NULL,
  CONSTRAINT pk_validacoes_restricoes_criterios_tipo_solo PRIMARY KEY (id),
  CONSTRAINT fk_validacoes_restricoes_criterios_tipo_solo_validacoes FOREIGN KEY (id_validacoes_restricoes_criterios) REFERENCES produto.validacoes_restricoes_criterios (id),
  CONSTRAINT fk_validacoes_restricoes_criterios_tipo_solo_solo FOREIGN KEY (id_tipo_solo) REFERENCES produto.tipo_solo (id)
) INHERITS (public.campos_default);

CREATE TABLE produto.validacoes_restricoes_criterios_propostas_excecoes(
  id SERIAL NOT NULL,
  id_validacoes_restricoes_criterios INT NOT NULL,
  id_proposta INT NOT NULL,
  CONSTRAINT pk_validacoes_restricoes_criterios_propostas_excecoes PRIMARY KEY (id),
  CONSTRAINT fk_validacoes_restricoes_criterios_propostas_excecoes_restricao FOREIGN KEY (id_validacoes_restricoes_criterios) REFERENCES produto.validacoes_restricoes_criterios (id),
  CONSTRAINT fk_validacoes_restricoes_criterios_propostas_excecoes_proposta FOREIGN KEY (id_proposta) REFERENCES seguro.propostas (id)
) INHERITS (public.campos_default);
SQL
        );
    }
}
