<?php
declare(strict_types=1);

use Phinx\Migration\AbstractMigration;

final class Task2208242044 extends AbstractMigration
{
    public function up(): void
    {
        $this->upCreateTables();
        $this->upMigrarDados();
        $this->upMenu();
    }

    public function down(): void
    {
        $this->downMenu();
        $this->downMigrarDados();
        $this->downCreateTables();
    }

    private function upCreateTables()
    {
        $this->execute(<<<SQL

            CREATE TABLE sistema.treinamentos (
                id SERIAL NOT NULL,
                dt_treinamento date NOT NULL,
                ds_local_treinamento VARCHAR(255),
                ds_assuntos_abordados TEXT,
                CONSTRAINT pk_treinamentos PRIMARY KEY(id)
            ) INHERITS (public.campos_default);

            CREATE TABLE sistema.treinamentos_tipos_vistoria (
                id SERIAL NOT NULL,
                id_treinamento INT NOT NULL,
                id_tipo_vistoria INT NOT NULL,
                CONSTRAINT pk_treinamentos_tipos_vistoria PRIMARY KEY(id),
                CONSTRAINT fk_treinamento FOREIGN KEY(id_treinamento) REFERENCES sistema.treinamentos(id),
                CONSTRAINT fk_tipo_vistoria FOREIGN KEY(id_tipo_vistoria) REFERENCES sistema.tipos_vistoria(id)
            ) INHERITS (public.campos_default);

            CREATE TABLE sistema.treinamentos_tipo_grupamento_culturas (
                id SERIAL NOT NULL,
                id_treinamento INT NOT NULL,
                id_grupamento_cultura INT NOT NULL,
                CONSTRAINT pk_treinamentos_tipo_grupamento_culturas PRIMARY KEY(id),
                CONSTRAINT fk_treinamento FOREIGN KEY(id_treinamento) REFERENCES sistema.treinamentos(id),
                CONSTRAINT fk_grupamento_cultura FOREIGN KEY(id_grupamento_cultura) REFERENCES produto.grupamento_culturas(id)
            ) INHERITS (public.campos_default);

            CREATE TABLE sistema.treinamentos_arquivos (
                id SERIAL NOT NULL,
                id_treinamento INT NOT NULL,
                ds_nome_arquivo VARCHAR,
                CONSTRAINT pk_treinamentos_arquivos PRIMARY KEY(id),
                CONSTRAINT fk_treinamento FOREIGN KEY(id_treinamento) REFERENCES sistema.treinamentos(id)
            ) INHERITS (public.campos_default);
SQL
        );
    }

    private function downCreateTables()
    {
        $this->execute(<<<SQL
            DROP TABLE sistema.treinamentos_arquivos;
            DROP TABLE sistema.treinamentos_tipo_grupamento_culturas;
            DROP TABLE sistema.treinamentos_tipos_vistoria;
            DROP TABLE sistema.treinamentos;
SQL
        );
    } 

    private function upMigrarDados()
    {
        $this->execute("UPDATE sistema.acao SET fl_del = FALSE WHERE ds_module = 'relatorio' AND id = 1932;");

        $this->execute(<<<SQL
            ALTER TABLE sistema.treinamento_vistorias ADD COLUMN id_treinamento INT REFERENCES sistema.treinamentos(id);
            ALTER TABLE sistema.treinamento_vistorias ADD COLUMN fl_ministrante BOOLEAN DEFAULT false;
SQL
        );

        $query = $this->query("SELECT * FROM sistema.treinamento_vistorias ORDER BY id");
        $treinamentoVistorias = $query->fetchAll();

        foreach ($treinamentoVistorias as $treinamentoVistoria) {
            $this->execute("INSERT INTO sistema.treinamentos (id_usuario_criacao, dt_criacao, dt_treinamento)
                                 VALUES ({$treinamentoVistoria['id_usuario_criacao']}, '{$treinamentoVistoria['dt_criacao']}', '{$treinamentoVistoria['dt_treinamento']}');");

            
            $this->execute("UPDATE sistema.treinamento_vistorias SET id_treinamento = currval('sistema.treinamentos_id_seq') WHERE id = {$treinamentoVistoria['id']};");

            $tiposVistorias = explode(',', $treinamentoVistoria['tipo_vistoria']);
            $tiposVistorias = array_unique($tiposVistorias);
            foreach($tiposVistorias as $tipoVistoria) {
                $this->execute("INSERT INTO sistema.treinamentos_tipos_vistoria (id_usuario_criacao, dt_criacao, id_tipo_vistoria, id_treinamento) 
                                     VALUES ({$treinamentoVistoria['id_usuario_criacao']}, '{$treinamentoVistoria['dt_criacao']}', {$tipoVistoria}, currval('sistema.treinamentos_id_seq'));");
            }

            $tiposAgrupamentoCultura = explode(',', $treinamentoVistoria['tipo_agrupamento_cultura']);
            $tiposAgrupamentoCultura = array_unique($tiposAgrupamentoCultura);
            foreach($tiposAgrupamentoCultura as $tipoAgrupamento) {
                $this->execute("INSERT INTO sistema.treinamentos_tipo_grupamento_culturas (id_usuario_criacao, dt_criacao, id_grupamento_cultura, id_treinamento) 
                                     VALUES ({$treinamentoVistoria['id_usuario_criacao']}, '{$treinamentoVistoria['dt_criacao']}', {$tipoAgrupamento}, currval('sistema.treinamentos_id_seq'));");
            }
        }

        $this->execute(<<<SQL
            ALTER TABLE sistema.treinamento_vistorias DROP COLUMN tipo_vistoria;
            ALTER TABLE sistema.treinamento_vistorias DROP COLUMN tipo_agrupamento_cultura;
            ALTER TABLE sistema.treinamento_vistorias DROP COLUMN dt_treinamento;
            ALTER TABLE sistema.treinamento_vistorias ALTER COLUMN id_treinamento SET NOT NULL;
SQL
        );
    }

    private function downMigrarDados()
    {
        $this->execute(<<<SQL
            ALTER TABLE sistema.treinamento_vistorias ADD COLUMN tipo_vistoria TEXT;
            ALTER TABLE sistema.treinamento_vistorias ADD COLUMN tipo_agrupamento_cultura TEXT;
            ALTER TABLE sistema.treinamento_vistorias ADD COLUMN dt_treinamento DATE;
SQL
        );

        $query = $this->query("SELECT * FROM sistema.treinamento_vistorias ORDER BY id");
        $treinamentoVistorias = $query->fetchAll();

        foreach ($treinamentoVistorias as $treinamentoVistoria) {
            $this->execute("UPDATE sistema.treinamento_vistorias SET tipo_vistoria = (SELECT string_agg(id_tipo_vistoria::text, ',') as tipo_vitoria FROM sistema.treinamentos_tipos_vistoria WHERE id_treinamento = {$treinamentoVistoria['id_treinamento']} GROUP BY id_treinamento),
                                                                     tipo_agrupamento_cultura = (SELECT string_agg(id_grupamento_cultura::text, ',') as tipo_agrupamento_cultura FROM sistema.treinamentos_tipo_grupamento_culturas WHERE id_treinamento = {$treinamentoVistoria['id_treinamento']} GROUP BY id_treinamento),
                                                                     dt_treinamento = (SELECT dt_treinamento FROM sistema.treinamentos WHERE id = {$treinamentoVistoria['id_treinamento']})
                                                               WHERE id = {$treinamentoVistoria['id']}");
        }

        $this->execute(<<<SQL
            ALTER TABLE sistema.treinamento_vistorias ALTER COLUMN tipo_vistoria SET NOT NULL;
            ALTER TABLE sistema.treinamento_vistorias ALTER COLUMN tipo_agrupamento_cultura SET NOT NULL;
            ALTER TABLE sistema.treinamento_vistorias ALTER COLUMN dt_treinamento SET NOT NULL;
            ALTER TABLE sistema.treinamento_vistorias DROP COLUMN fl_ministrante;
            ALTER TABLE sistema.treinamento_vistorias DROP COLUMN id_treinamento;
SQL
        );

        $this->execute("UPDATE sistema.acao SET fl_del = TRUE WHERE ds_module = 'relatorio' AND id = 1932;");
    }

    private function upMenu()
    {
        $this->execute(<<<SQL
            INSERT INTO sistema.acao (id_usuario_criacao, dt_criacao, ds_label, ds_module, ds_controller, ds_action, id_parent, ds_descricao, fl_tipo)
                VALUES (2068, now(), 'Treinamentos', 'sistema', 'treinamento', 'index', 4, 'Treinamentos', 'M');

            INSERT INTO sistema.acao (id_usuario_criacao, dt_criacao, ds_label, ds_module, ds_controller, ds_action, ds_param, id_parent, ds_image, fl_tipo, nr_ordem)
                VALUES (2068, now(), 'Editar', 'sistema', 'treinamento', 'form', 'id', (SELECT id FROM sistema.acao WHERE ds_module = 'sistema' AND ds_controller = 'treinamento' AND ds_action = 'index'), 'edit.png', 'L', 0);

            INSERT INTO sistema.acao (id_usuario_criacao, dt_criacao, ds_label, ds_module, ds_controller, ds_action, ds_param, id_parent, ds_image, fl_tipo, nr_ordem)
                VALUES (2068, now(), 'Deletar', 'sistema', 'treinamento', 'delete', 'id', (SELECT id FROM sistema.acao WHERE ds_module = 'sistema' AND ds_controller = 'treinamento' AND ds_action = 'index'), 'delete.png', 'L', 1);
            
            INSERT INTO sistema.acao (id_usuario_criacao, dt_criacao, ds_label, ds_module, ds_controller, ds_action, ds_param, id_parent, ds_image, fl_tipo, nr_ordem)
                VALUES (2068, now(), 'Fotos', 'sistema', 'treinamento', 'fotos', 'id', (SELECT id FROM sistema.acao WHERE ds_module = 'sistema' AND ds_controller = 'treinamento' AND ds_action = 'index'), 'fotos.png', 'L', 2);

            INSERT INTO sistema.roles_acao (id_usuario_criacao, dt_criacao, id_role, id_acao)
                VALUES(2068, now(), 16, (SELECT id FROM  sistema.acao WHERE ds_module = 'sistema' AND ds_controller = 'treinamento' AND ds_action = 'index'));

            INSERT INTO sistema.roles_acao (id_usuario_criacao, dt_criacao, id_role, id_acao)
                VALUES(2068, now(), 16, (SELECT id FROM  sistema.acao WHERE ds_module = 'sistema' AND ds_controller = 'treinamento' AND ds_action = 'form'));

            INSERT INTO sistema.roles_acao (id_usuario_criacao, dt_criacao, id_role, id_acao)
                VALUES(2068, now(), 16, (SELECT id FROM  sistema.acao WHERE ds_module = 'sistema' AND ds_controller = 'treinamento' AND ds_action = 'delete'));

            INSERT INTO sistema.roles_acao (id_usuario_criacao, dt_criacao, id_role, id_acao)
                VALUES(2068, now(), 16, (SELECT id FROM  sistema.acao WHERE ds_module = 'sistema' AND ds_controller = 'treinamento' AND ds_action = 'fotos'));

            INSERT INTO sistema.roles_acao (id_usuario_criacao, dt_criacao, id_role, id_acao)
                VALUES(2068, now(), 16, 1932);

            UPDATE sistema.usuarios_acao SET fl_permitido = 't' WHERE id_usuario IN (SELECT id FROM sistema.usuarios WHERE id_role = 16) AND id_acao = 1932;
SQL
        );
    }

    private function downMenu()
    {
        $this->execute(<<<SQL
            DELETE FROM sistema.roles_acao WHERE id_role = 16 AND id_acao = (SELECT id FROM  sistema.acao WHERE ds_module = 'sistema' AND ds_controller = 'treinamento' AND ds_action = 'fotos');
            DELETE FROM sistema.roles_acao WHERE id_role = 16 AND id_acao = (SELECT id FROM  sistema.acao WHERE ds_module = 'sistema' AND ds_controller = 'treinamento' AND ds_action = 'delete');
            DELETE FROM sistema.roles_acao WHERE id_role = 16 AND id_acao = (SELECT id FROM  sistema.acao WHERE ds_module = 'sistema' AND ds_controller = 'treinamento' AND ds_action = 'form');
            DELETE FROM sistema.roles_acao WHERE id_role = 16 AND id_acao = (SELECT id FROM  sistema.acao WHERE ds_module = 'sistema' AND ds_controller = 'treinamento' AND ds_action = 'index');
            DELETE FROM sistema.roles_acao WHERE id_role = 16 AND id_acao = 1932;

            DELETE FROM sistema.acao WHERE ds_module = 'sistema' AND ds_controller = 'treinamento' AND ds_action = 'fotos';
            DELETE FROM sistema.acao WHERE ds_module = 'sistema' AND ds_controller = 'treinamento' AND ds_action = 'delete';
            DELETE FROM sistema.acao WHERE ds_module = 'sistema' AND ds_controller = 'treinamento' AND ds_action = 'form';
            DELETE FROM sistema.acao WHERE ds_module = 'sistema' AND ds_controller = 'treinamento' AND ds_action = 'index';
SQL
        );
    }
}
