class AjustaLogDeMovimentacoes < ActiveRecord::Migration[5.2]
  def up
    add_column :log_movimentacoes_pcasp, :lista_de_erros, :string
    add_column :log_movimentacoes_pcasp, :data_de_lancamento, :date
    add_column :log_movimentacoes_pcasp, :status, :string

    execute <<-SQL
      DROP TRIGGER IF EXISTS trg_log_empenhos_pcasp ON contabilidade_empenhos;
      DROP TRIGGER IF EXISTS trg_remover_log_empenhos_pcasp ON contabilidade_empenhos;
      DROP TRIGGER IF EXISTS trg_log_empenhos_pcasp ON contabilidade_liquidacoes;
      DROP TRIGGER IF EXISTS trg_remover_log_empenhos_pcasp ON contabilidade_liquidacoes;
      DROP TRIGGER IF EXISTS trg_log_anulacoes_do_empenho_pcasp ON contabilidade_anulacoes_do_empenho;
      DROP TRIGGER IF EXISTS trg_remover_log_anulacoes_do_empenho_pcasp ON contabilidade_anulacoes_do_empenho;
      DROP TRIGGER IF EXISTS trg_log_anulacoes_dos_taloes_de_receita_pcasp ON contabilidade_anulacoes_dos_taloes_de_receita;
      DROP TRIGGER IF EXISTS trg_remover_log_anulacoes_dos_taloes_de_receita_pcasp ON contabilidade_anulacoes_dos_taloes_de_receita;
      DROP TRIGGER IF EXISTS trg_log_bloqueios_de_dotacao_pcasp ON contabilidade_bloqueio_de_dotacoes;
      DROP TRIGGER IF EXISTS trg_remover_log_bloqueios_de_dotacao_pcasp ON contabilidade_bloqueio_de_dotacoes;
      DROP TRIGGER IF EXISTS trg_log_cancelamento_de_restos_a_pagar_pcasp ON contabilidade_cancelamentos_de_restos_a_pagar;
      DROP TRIGGER IF EXISTS trg_remover_log_cancelamento_de_restos_a_pagar_pcasp ON contabilidade_cancelamentos_de_restos_a_pagar;
      DROP TRIGGER IF EXISTS trg_log_despesas_extra_orcamentarias_pcasp ON contabilidade_despesas_extra_orcamentarias;
      DROP TRIGGER IF EXISTS trg_remover_log_despesas_extra_orcamentarias_pcasp ON contabilidade_despesas_extra_orcamentarias;
      DROP TRIGGER IF EXISTS trg_log_estornos_de_despesas_extra_orcamentarias_pcasp ON contabilidade_estorno_de_despesas_extra_orcamentarias;
      DROP TRIGGER IF EXISTS trg_remover_log_estornos_de_despesas_extra_orcamentarias_pcasp ON contabilidade_estorno_de_despesas_extra_orcamentarias;
      DROP TRIGGER IF EXISTS trg_log_estornos_de_liquidacoes_pcasp ON contabilidade_estornos_de_liquidacao;
      DROP TRIGGER IF EXISTS trg_remover_log_estornos_de_liquidacoes_pcasp ON contabilidade_estornos_de_liquidacao;
      DROP TRIGGER IF EXISTS trg_log_estornos_de_pagamentos_pcasp ON contabilidade_estornos_de_pagamento;
      DROP TRIGGER IF EXISTS trg_remover_log_estornos_de_pagamentos_pcasp ON contabilidade_estornos_de_pagamento;
      DROP TRIGGER IF EXISTS trg_log_pagamentos_pcasp ON contabilidade_pagamentos;
      DROP TRIGGER IF EXISTS trg_remover_log_pagamentos_pcasp ON contabilidade_pagamentos;
      DROP TRIGGER IF EXISTS trg_log_solicitacoes_de_alteracao_orcamentaria_pcasp ON contabilidade_solicitacao_de_alteracao_orcamentarias;
      DROP TRIGGER IF EXISTS trg_remover_log_solicitacoes_de_alteracao_orcamentaria_pcasp ON contabilidade_solicitacao_de_alteracao_orcamentarias;
      DROP TRIGGER IF EXISTS trg_log_taloes_de_receita_pcasp ON contabilidade_taloes_de_receita;
      DROP TRIGGER IF EXISTS trg_remover_log_taloes_de_receita_pcasp ON contabilidade_taloes_de_receita;
      DROP TRIGGER IF EXISTS trg_log_transferencias_financeiras_pcasp ON contabilidade_transferencias_financeiras;
      DROP TRIGGER IF EXISTS trg_remover_log_transferencias_financeiras_pcasp ON contabilidade_transferencias_financeiras;
      DROP TRIGGER IF EXISTS trg_log_orcamentos_da_despesa_pcasp ON loa_orcamentos_da_despesa;
      DROP TRIGGER IF EXISTS trg_remover_log_orcamentos_da_despesa_pcasp ON loa_orcamentos_da_despesa;
      DROP TRIGGER IF EXISTS trg_log_orcamentos_da_receita_pcasp ON loa_orcamentos_da_receita;
      DROP TRIGGER IF EXISTS trg_remover_log_orcamentos_da_receita_pcasp ON loa_orcamentos_da_receita;

      DROP FUNCTION IF EXISTS log_movimentacao_pcasp() CASCADE;
      DROP FUNCTION IF EXISTS remover_log_movimentacao_pcasp() CASCADE;

      TRUNCATE log_movimentacoes_pcasp;
    SQL
  end

  def down
    remove_column :log_movimentacoes_pcasp, :lista_de_erros
    remove_column :log_movimentacoes_pcasp, :data_de_lancamento
    remove_column :log_movimentacoes_pcasp, :status

    execute <<-SQL
      -- Função para Inserir ou Atualizar Registros na Tabela de Log
      CREATE OR REPLACE FUNCTION log_movimentacao_pcasp()
      RETURNS TRIGGER AS $$
      DECLARE
          qtd_movimentacoes_orcamentaria INTEGER;
          qtd_movimentacoes_patrimonial INTEGER;
          qtd_movimentacoes_controle INTEGER;
          nome_do_modelo VARCHAR(255);
          identificador BIGINT;
      BEGIN
          if TG_TABLE_NAME = 'contabilidade_empenhos' THEN
              nome_do_modelo = 'Contabilidade::Empenho';
          elsif TG_TABLE_NAME = 'contabilidade_liquidacoes' THEN
              nome_do_modelo = 'Contabilidade::Liquidacao';
          elsif TG_TABLE_NAME = 'contabilidade_pagamentos' THEN
              nome_do_modelo = 'Contabilidade::Pagamento';
          elsif TG_TABLE_NAME = 'contabilidade_taloes_de_receita' THEN
              nome_do_modelo = 'Contabilidade::TalaoDeReceita';
          elsif TG_TABLE_NAME = 'contabilidade_anulacoes_do_empenho' THEN
              nome_do_modelo = 'Contabilidade::AnulacaoDoEmpenho';
          elsif TG_TABLE_NAME = 'contabilidade_anulacoes_dos_taloes_de_receita' THEN
              nome_do_modelo = 'Contabilidade::AnulacaoDoTalaoDeReceita';
          elsif TG_TABLE_NAME = 'contabilidade_bloqueio_de_dotacoes' THEN
              nome_do_modelo = 'Contabilidade::BloqueioDeDotacao';
          elsif TG_TABLE_NAME = 'contabilidade_cancelamentos_de_restos_a_pagar' THEN
              nome_do_modelo = 'Contabilidade::CancelamentoDeRestoAPagar';
          elsif TG_TABLE_NAME = 'contabilidade_despesas_extra_orcamentarias' THEN
              nome_do_modelo = 'Contabilidade::DespesaExtraOrcamentaria';
          elsif TG_TABLE_NAME = 'contabilidade_estorno_de_despesas_extra_orcamentarias' THEN
              nome_do_modelo = 'Contabilidade::EstornoDeDespesaExtraOrcamentaria';
          elsif TG_TABLE_NAME = 'contabilidade_estornos_de_liquidacao' THEN 
              nome_do_modelo = 'Contabilidade::EstornoDeLiquidacao';
          elsif TG_TABLE_NAME = 'contabilidade_estornos_de_pagamento' THEN  
              nome_do_modelo = 'Contabilidade::EstornoDePagamento';
          elsif TG_TABLE_NAME = 'contabilidade_solicitacao_de_alteracao_orcamentarias' THEN
              nome_do_modelo = 'Contabilidade::SolicitacaoDeAlteracaoOrcamentaria';
          elsif TG_TABLE_NAME = 'contabilidade_transferencias_financeiras' THEN
              nome_do_modelo = 'Contabilidade::TransferenciaFinanceira';
          --elsif TG_TABLE_NAME = 'base_contas_bancarias' THEN
          --    nome_do_modelo = 'Base::ContaBancaria';
          elsif TG_TABLE_NAME = 'loa_orcamentos_da_receita' THEN
              nome_do_modelo = 'Loa::OrcamentoDaReceita';
          elsif TG_TABLE_NAME = 'loa_orcamentos_da_despesa' THEN
              nome_do_modelo = 'Loa::OrcamentoDaDespesa';
          end if;

          -- Deleta registros existentes na tabela de log para o par gerador_id e nome_da_tabela
          DELETE FROM log_movimentacoes_pcasp
          WHERE gerador_id = NEW.id AND nome_da_tabela = TG_TABLE_NAME;
          
          -- Conta a quantidade de movimentações para o registro atual na tabela de movimentações
          SELECT COUNT(*)
          INTO qtd_movimentacoes_orcamentaria
          FROM contabilidade_movimentacoes_do_plano_de_contas as t1
          LEFT JOIN contabilidade_contas_por_eventos_contabeis as t2 on t2.id = t1.conta_por_evento_contabil_id
          LEFT JOIN contabilidade_contas as t3 on t3.id = t2.conta_id
          LEFT JOIN contabilidade_grupo_de_contas as t4 on t4.id = t3.grupo_de_conta_id
          WHERE t4.nome = 'Orçamentária' AND gerador_id = NEW.id AND gerador_type = nome_do_modelo;

          SELECT COUNT(*)
          INTO qtd_movimentacoes_patrimonial
          FROM contabilidade_movimentacoes_do_plano_de_contas as t1
          LEFT JOIN contabilidade_contas_por_eventos_contabeis as t2 on t2.id = t1.conta_por_evento_contabil_id
          LEFT JOIN contabilidade_contas as t3 on t3.id = t2.conta_id
          LEFT JOIN contabilidade_grupo_de_contas as t4 on t4.id = t3.grupo_de_conta_id
          WHERE t4.nome = 'Patrimonial' AND gerador_id = NEW.id AND gerador_type = nome_do_modelo;

          SELECT COUNT(*)
          INTO qtd_movimentacoes_controle
          FROM contabilidade_movimentacoes_do_plano_de_contas as t1
          LEFT JOIN contabilidade_contas_por_eventos_contabeis as t2 on t2.id = t1.conta_por_evento_contabil_id
          LEFT JOIN contabilidade_contas as t3 on t3.id = t2.conta_id
          LEFT JOIN contabilidade_grupo_de_contas as t4 on t4.id = t3.grupo_de_conta_id
          WHERE t4.nome = 'Controle' AND gerador_id = NEW.id AND gerador_type = nome_do_modelo;
          
          -- Insere o novo registro na tabela de log
          INSERT INTO log_movimentacoes_pcasp (gerador_id, gerador_type, nome_da_tabela, qtd_movimentacoes_orcamentaria, qtd_movimentacoes_patrimonial, qtd_movimentacoes_controle, qtd_total, created_at, updated_at)
          VALUES (NEW.id, nome_do_modelo, TG_TABLE_NAME, qtd_movimentacoes_orcamentaria, qtd_movimentacoes_patrimonial, qtd_movimentacoes_controle, (qtd_movimentacoes_orcamentaria + qtd_movimentacoes_patrimonial + qtd_movimentacoes_controle), NEW.created_at, NEW.updated_at);
          
          RETURN NEW;
      END;
      $$ LANGUAGE plpgsql;

      -- Função para Remover Registros da Tabela de Log
      CREATE OR REPLACE FUNCTION remover_log_movimentacao_pcasp()
      RETURNS TRIGGER AS $$
      BEGIN
          DELETE FROM log_movimentacoes_pcasp
          WHERE gerador_id = OLD.id AND nome_da_tabela = TG_TABLE_NAME;
          RETURN OLD;
      END;
      $$ LANGUAGE plpgsql;

      -- Trigger para Inserção e Atualização na Tabela contabilidade_empenhos
      CREATE TRIGGER trg_log_empenhos_pcasp
      AFTER INSERT OR UPDATE ON contabilidade_empenhos
      FOR EACH ROW
      EXECUTE FUNCTION log_movimentacao_pcasp();

      -- Trigger para Deleção na Tabela contabilidade_empenhos
      CREATE TRIGGER trg_remover_log_empenhos_pcasp
      AFTER DELETE ON contabilidade_empenhos
      FOR EACH ROW
      EXECUTE FUNCTION remover_log_movimentacao_pcasp();

      -- Trigger para Inserção e Atualização na Tabela contabilidade_liquidacoes
      CREATE TRIGGER trg_log_empenhos_pcasp
      AFTER INSERT OR UPDATE ON contabilidade_liquidacoes
      FOR EACH ROW
      EXECUTE FUNCTION log_movimentacao_pcasp();

      -- Trigger para Deleção na Tabela contabilidade_liquidacoes
      CREATE TRIGGER trg_remover_log_empenhos_pcasp
      AFTER DELETE ON contabilidade_liquidacoes
      FOR EACH ROW
      EXECUTE FUNCTION remover_log_movimentacao_pcasp();

      -- Trigger para Inserção e Atualização na Tabela contabilidade_anulacoes_do_empenho
      CREATE TRIGGER trg_log_anulacoes_do_empenho_pcasp
      AFTER INSERT OR UPDATE ON contabilidade_anulacoes_do_empenho
      FOR EACH ROW
      EXECUTE FUNCTION log_movimentacao_pcasp();

      -- Trigger para Deleção na Tabela contabilidade_anulacoes_do_empenho
      CREATE TRIGGER trg_remover_log_anulacoes_do_empenho_pcasp
      AFTER DELETE ON contabilidade_anulacoes_do_empenho
      FOR EACH ROW
      EXECUTE FUNCTION remover_log_movimentacao_pcasp();

      -- Trigger para Inserção e Atualização na Tabela contabilidade_anulacoes_dos_taloes_de_receita
      CREATE TRIGGER trg_log_anulacoes_dos_taloes_de_receita_pcasp
      AFTER INSERT OR UPDATE ON contabilidade_anulacoes_dos_taloes_de_receita
      FOR EACH ROW
      EXECUTE FUNCTION log_movimentacao_pcasp();

      -- Trigger para Deleção na Tabela contabilidade_anulacoes_dos_taloes_de_receita
      CREATE TRIGGER trg_remover_log_anulacoes_dos_taloes_de_receita_pcasp
      AFTER DELETE ON contabilidade_anulacoes_dos_taloes_de_receita
      FOR EACH ROW
      EXECUTE FUNCTION remover_log_movimentacao_pcasp();

      -- Trigger para Inserção e Atualização na Tabela contabilidade_bloqueio_de_dotacoes
      CREATE TRIGGER trg_log_bloqueios_de_dotacao_pcasp
      AFTER INSERT OR UPDATE ON contabilidade_bloqueio_de_dotacoes
      FOR EACH ROW
      EXECUTE FUNCTION log_movimentacao_pcasp();

      -- Trigger para Deleção na Tabela contabilidade_bloqueio_de_dotacoes
      CREATE TRIGGER trg_remover_log_bloqueios_de_dotacao_pcasp
      AFTER DELETE ON contabilidade_bloqueio_de_dotacoes
      FOR EACH ROW
      EXECUTE FUNCTION remover_log_movimentacao_pcasp();

      -- Trigger para Inserção e Atualização na Tabela contabilidade_cancelamentos_de_restos_a_pagar
      CREATE TRIGGER trg_log_cancelamento_de_restos_a_pagar_pcasp
      AFTER INSERT OR UPDATE ON contabilidade_cancelamentos_de_restos_a_pagar
      FOR EACH ROW
      EXECUTE FUNCTION log_movimentacao_pcasp();

      -- Trigger para Deleção na Tabela contabilidade_cancelamentos_de_restos_a_pagar
      CREATE TRIGGER trg_remover_log_cancelamento_de_restos_a_pagar_pcasp
      AFTER DELETE ON contabilidade_cancelamentos_de_restos_a_pagar
      FOR EACH ROW
      EXECUTE FUNCTION remover_log_movimentacao_pcasp();

      -- Trigger para Inserção e Atualização na Tabela base_contas_bancarias
      -- CREATE TRIGGER trg_log_base_contas_bancarias_pcasp
      -- AFTER INSERT OR UPDATE ON base_contas_bancarias
      -- FOR EACH ROW
      -- EXECUTE FUNCTION log_movimentacao_pcasp();

      -- Trigger para Deleção na Tabela base_contas_bancarias
      -- CREATE TRIGGER trg_remover_log_base_contas_bancarias_pcasp
      -- AFTER DELETE ON base_contas_bancarias
      -- FOR EACH ROW
      -- EXECUTE FUNCTION remover_log_movimentacao_pcasp();

      -- Trigger para Inserção e Atualização na Tabela contabilidade_despesas_extra_orcamentarias
      CREATE TRIGGER trg_log_despesas_extra_orcamentarias_pcasp
      AFTER INSERT OR UPDATE ON contabilidade_despesas_extra_orcamentarias
      FOR EACH ROW
      EXECUTE FUNCTION log_movimentacao_pcasp();

      -- Trigger para Deleção na Tabela contabilidade_despesas_extra_orcamentarias
      CREATE TRIGGER trg_remover_log_despesas_extra_orcamentarias_pcasp
      AFTER DELETE ON contabilidade_despesas_extra_orcamentarias
      FOR EACH ROW
      EXECUTE FUNCTION remover_log_movimentacao_pcasp();

      -- Trigger para Inserção e Atualização na Tabela contabilidade_estorno_de_despesas_extra_orcamentarias
      CREATE TRIGGER trg_log_estornos_de_despesas_extra_orcamentarias_pcasp
      AFTER INSERT OR UPDATE ON contabilidade_estorno_de_despesas_extra_orcamentarias
      FOR EACH ROW
      EXECUTE FUNCTION log_movimentacao_pcasp();

      -- Trigger para Deleção na Tabela contabilidade_estorno_de_despesas_extra_orcamentarias
      CREATE TRIGGER trg_remover_log_estornos_de_despesas_extra_orcamentarias_pcasp
      AFTER DELETE ON contabilidade_estorno_de_despesas_extra_orcamentarias
      FOR EACH ROW
      EXECUTE FUNCTION remover_log_movimentacao_pcasp();

      -- Trigger para Inserção e Atualização na Tabela contabilidade_estornos_de_liquidacao
      CREATE TRIGGER trg_log_estornos_de_liquidacoes_pcasp
      AFTER INSERT OR UPDATE ON contabilidade_estornos_de_liquidacao
      FOR EACH ROW
      EXECUTE FUNCTION log_movimentacao_pcasp();

      -- Trigger para Deleção na Tabela contabilidade_estornos_de_liquidacao
      CREATE TRIGGER trg_remover_log_estornos_de_liquidacoes_pcasp
      AFTER DELETE ON contabilidade_estornos_de_liquidacao
      FOR EACH ROW
      EXECUTE FUNCTION remover_log_movimentacao_pcasp();

      -- Trigger para Inserção e Atualização na Tabela contabilidade_estornos_de_pagamento
      CREATE TRIGGER trg_log_estornos_de_pagamentos_pcasp
      AFTER INSERT OR UPDATE ON contabilidade_estornos_de_pagamento
      FOR EACH ROW
      EXECUTE FUNCTION log_movimentacao_pcasp();

      -- Trigger para Deleção na Tabela contabilidade_estornos_de_pagamento
      CREATE TRIGGER trg_remover_log_estornos_de_pagamentos_pcasp
      AFTER DELETE ON contabilidade_estornos_de_pagamento
      FOR EACH ROW
      EXECUTE FUNCTION remover_log_movimentacao_pcasp();

      -- Trigger para Inserção e Atualização na Tabela contabilidade_pagamentos
      CREATE TRIGGER trg_log_pagamentos_pcasp
      AFTER INSERT OR UPDATE ON contabilidade_pagamentos
      FOR EACH ROW
      EXECUTE FUNCTION log_movimentacao_pcasp();

      -- Trigger para Deleção na Tabela contabilidade_pagamentos
      CREATE TRIGGER trg_remover_log_pagamentos_pcasp
      AFTER DELETE ON contabilidade_pagamentos
      FOR EACH ROW
      EXECUTE FUNCTION remover_log_movimentacao_pcasp();

      -- Trigger para Inserção e Atualização na Tabela contabilidade_solicitacao_de_alteracao_orcamentarias
      CREATE TRIGGER trg_log_solicitacoes_de_alteracao_orcamentaria_pcasp
      AFTER INSERT OR UPDATE ON contabilidade_solicitacao_de_alteracao_orcamentarias
      FOR EACH ROW
      EXECUTE FUNCTION log_movimentacao_pcasp();

      -- Trigger para Deleção na Tabela contabilidade_solicitacao_de_alteracao_orcamentarias
      CREATE TRIGGER trg_remover_log_solicitacoes_de_alteracao_orcamentaria_pcasp
      AFTER DELETE ON contabilidade_solicitacao_de_alteracao_orcamentarias
      FOR EACH ROW
      EXECUTE FUNCTION remover_log_movimentacao_pcasp();

      -- Trigger para Inserção e Atualização na Tabela contabilidade_taloes_de_receita
      CREATE TRIGGER trg_log_taloes_de_receita_pcasp
      AFTER INSERT OR UPDATE ON contabilidade_taloes_de_receita
      FOR EACH ROW
      EXECUTE FUNCTION log_movimentacao_pcasp();

      -- Trigger para Deleção na Tabela contabilidade_taloes_de_receita
      CREATE TRIGGER trg_remover_log_taloes_de_receita_pcasp
      AFTER DELETE ON contabilidade_taloes_de_receita
      FOR EACH ROW
      EXECUTE FUNCTION remover_log_movimentacao_pcasp();

      -- Trigger para Inserção e Atualização na Tabela contabilidade_transferencias_financeiras
      CREATE TRIGGER trg_log_transferencias_financeiras_pcasp
      AFTER INSERT OR UPDATE ON contabilidade_transferencias_financeiras
      FOR EACH ROW
      EXECUTE FUNCTION log_movimentacao_pcasp();

      -- Trigger para Deleção na Tabela contabilidade_transferencias_financeiras
      CREATE TRIGGER trg_remover_log_transferencias_financeiras_pcasp
      AFTER DELETE ON contabilidade_transferencias_financeiras
      FOR EACH ROW
      EXECUTE FUNCTION remover_log_movimentacao_pcasp();

      -- Trigger para Inserção e Atualização na Tabela loa_orcamentos_da_despesa
      CREATE TRIGGER trg_log_orcamentos_da_despesa_pcasp
      AFTER INSERT OR UPDATE ON loa_orcamentos_da_despesa
      FOR EACH ROW
      EXECUTE FUNCTION log_movimentacao_pcasp();

      -- Trigger para Deleção na Tabela loa_orcamentos_da_despesa
      CREATE TRIGGER trg_remover_log_orcamentos_da_despesa_pcasp
      AFTER DELETE ON loa_orcamentos_da_despesa
      FOR EACH ROW
      EXECUTE FUNCTION remover_log_movimentacao_pcasp();

      -- Trigger para Inserção e Atualização na Tabela loa_orcamentos_da_receita
      CREATE TRIGGER trg_log_orcamentos_da_receita_pcasp
      AFTER INSERT OR UPDATE ON loa_orcamentos_da_receita
      FOR EACH ROW
      EXECUTE FUNCTION log_movimentacao_pcasp();

      -- Trigger para Deleção na Tabela loa_orcamentos_da_receita
      CREATE TRIGGER trg_remover_log_orcamentos_da_receita_pcasp
      AFTER DELETE ON loa_orcamentos_da_receita
      FOR EACH ROW
      EXECUTE FUNCTION remover_log_movimentacao_pcasp();

    SQL
  end
end
