class Contabilidade::GeradorDeLoteBancario
    include ActiveModel::Model
    include ActiveModel::Validations

    attr_accessor :tipo
    attr_accessor :pagamentos_ids
    attr_accessor :envios_ao_banco

    validates_presence_of :tipo

    def lotes_individuais?
      self.tipo.to_i == 1 ? true : false
    end

    def agrupado_por_banco_e_agencia?
      self.tipo.to_i == 2 ? true : false
    end

    def pagamentos_pendentes(orcamento_id)
      Contabilidade::Pagamento.where("estornado is not true and status = 3 and orcamento_id = ?", orcamento_id).all.map { |p| p unless p.esta_em_um_lote_bancario? }.compact
    end

    validates_presence_of :tipo

    validate :valida_pagamentos_selecionados, :valida_tipos_de_envio

    def valida_tipos_de_envio
      if self.agrupado_por_banco_e_agencia?
        lista = self.envios_ao_banco.map { |i| i.split("_") }.to_h if self.pagamentos_ids.present?
        if self.agrupado_por_banco_e_agencia?
          contas_bancarias_por_pagamento = Base::ContaBancariaPorPagamento.joins([:conta_bancaria, :pagamento]).where("contabilidade_pagamentos.id in (?)", self.pagamentos_ids.map{ |k| k.to_i }).group_by{ |c| c.conta_bancaria.agencia }.each do |objeto|
            if lista.select { |k, v| self.pagamentos_ids.include? k  }.values.compact.uniq.size > 1
              errors.add(:base, "O tipo de envio deve ser igual para todos os pagamentos da mesma conta bancária")
            end
          end
        end
      end
    end

    def valida_pagamentos_selecionados
      errors.add(:base, 'Nenhum pagamento selecionado.') if self.pagamentos_ids.nil?
    end

    def gerar_lotes
      begin
        envios_ao_banco = self.envios_ao_banco.map { |i| i.split("_") }.to_h
        if self.lotes_individuais?
          pagamentos = Contabilidade::Pagamento.where("id in (?)", self.pagamentos_ids.map{ |k| k.to_i }).all
          pagamentos.each do |pagamento|
            pagamento.contas_bancarias_por_pagamento.each do |conta_bancaria_por_pagamento|
              lote_bancario = Contabilidade::LoteBancario.new(
                envio_ao_banco: envios_ao_banco["#{conta_bancaria_por_pagamento.id}"].to_i,
                banco_id: conta_bancaria_por_pagamento.try(:conta_bancaria).try(:agencia).try(:banco_id),
                agencia_id: conta_bancaria_por_pagamento.try(:conta_bancaria).try(:agencia_id),
              )
              if lote_bancario.save
                numero = 0
                conta_bancaria_por_pagamento.pagamento.pagamentos_das_retencoes.each do |pagamento_da_retencao|
                  pagamento_do_lote_bancario = lote_bancario.pagamentos_do_lote_bancario.create(pagamento_da_retencao: pagamento_da_retencao, numero: numero)
                  numero = pagamento_do_lote_bancario.numero + 1
                end
                pagamento_do_lote_bancario = lote_bancario.pagamentos_do_lote_bancario.create(conta_bancaria_por_pagamento: conta_bancaria_por_pagamento, numero: numero)
                numero = pagamento_do_lote_bancario.numero + 1
              end
            end
          end
          return true
        elsif self.agrupado_por_banco_e_agencia?
          contas_bancarias_por_pagamento = Base::ContaBancariaPorPagamento.joins([:pagamento, :conta_bancaria]).where("contabilidade_pagamentos.id in (?)", self.pagamentos_ids.map{ |k| k.to_i }).group_by{ |c| c.conta_bancaria.agencia }.each do |objeto|
            tipos_de_envio = envios_ao_banco.map { |k| k[1] if objeto.last.map(&:id).include? k[0].to_i }.compact.flatten

            lote_bancario = Contabilidade::LoteBancario.new(
              envio_ao_banco: tipos_de_envio.uniq.first.to_i,
              banco_id: objeto[0].try(:banco_id),
              agencia_id: objeto[0].try(:id),
            )
            if lote_bancario.save
              numero = 0
              objeto[1].each do |conta_bancaria_por_pagamento|
                conta_bancaria_por_pagamento.pagamento.pagamentos_das_retencoes.each do |pagamento_da_retencao|
                  pagamento_do_lote_bancario = lote_bancario.pagamentos_do_lote_bancario.create(pagamento_da_retencao: pagamento_da_retencao, numero: numero)
                  numero = pagamento_do_lote_bancario.numero + 1
                end
                pagamento_do_lote_bancario = lote_bancario.pagamentos_do_lote_bancario.create(conta_bancaria_por_pagamento: conta_bancaria_por_pagamento, numero: numero)
                numero = pagamento_do_lote_bancario.numero + 1
              end
            end
          end
          return true
        end
      rescue
        raise ActiveRecord::Rollback
        return false
      end
      false
    end

end
