require 'csv'

class Licitacao::ArquivoBllDoProcesso < ApplicationRecord
  has_paper_trail

  attr_default :processado, false

  belongs_to :processo, class_name: "Licitacao::Processo"

  validates_presence_of :processo_id, :tipo_de_arquivo

  has_attached_file :file

  validates_attachment :file, presence: true, file_name: {matches: [/csv\Z/]}, message: "Formato inválido. O Arquivo deve ter o formato CSV."
  # validates_attachment :file, content_type: { content_type: ["text/csv", "text/x-csv", "text/plain", "application/vnd.ms-excel"] }, message: "Formato inválido. O Arquivo deve ter o formato CSV."

  validate :validar_headers_por_tipo_de_arquivo

  enum tipo_de_arquivo: { relacao_de_vencedores: 1, participantes: 2 } # lotes_mal_sucedidos: 3, participantes_desclassificados: 4, propostas: 5


  def validar_headers_por_tipo_de_arquivo
    csv_text = Paperclip.io_adapters.for(self.file).read.force_encoding(Encoding::UTF_8)
    csv = CSV.parse(csv_text, :headers => true)
    valido = false
    case self.tipo_de_arquivo
    when "relacao_de_vencedores"
      valido = csv.headers.eql?(["Razão Social", "CPF/CNPJ", "Lote", "Status", "Item", "Descrição", "Unidade", "Marca", "Modelo", "Quantidade", "Vl. Unit.", "Vl. Total"])
    when "participantes"
      valido = csv.headers.eql?(["Participante", "Documento", "UF", "Cidade", "Endereço", "Bairro", "CEP", "Telefone", "Email", "Representante", "CPF", "RG", "Email", "Telefone"])
    when "lotes_mal_sucedidos"
      valido = true
    when "participantes_desclassificados"
      valido = true
    when "propostas"
      valido = true
    end

    if valido == false
      errors.add(:base, "Estrutura do arquivo não condiz com o tipo de arquivo selecionado.")
    end
  end

  def processar_arquivo
    case self.tipo_de_arquivo
    when "relacao_de_vencedores"
      self.grava_relacao_de_vencedores
    when "participantes"
      self.grava_participantes
    when "lotes_mal_sucedidos"
      valido = true
    when "participantes_desclassificados"
      valido = true
    when "propostas"
      valido = true
    end
  end

  def grava_relacao_de_vencedores
    csv_text = Paperclip.io_adapters.for(self.file).read.force_encoding(Encoding::UTF_8)
    csv = CSV.parse(csv_text, :headers => true)
    licitantes = self.processo.pessoas_do_projeto.map { |a| a.pessoa.cpf_ou_cnpj_sem_pontos }

    if (csv["CPF/CNPJ"] - licitantes).empty?
      csv.each do |row|
        lote = self.processo.lotes.where(numero: row["Lote"].to_s).first
        item_lote = lote.itens_do_lote.where("sequencia = ? or (sequencia = 0 and ? = 1)", row["Item"].to_i, row["Item"].to_i).first
        pessoa = self.processo.pessoas.select { |pessoa| pessoa.cpf_ou_cnpj_sem_pontos == row["CPF/CNPJ"] }.first
        pessoa_do_projeto = self.processo.pessoas_do_projeto.where(pessoa_id: pessoa.id).first

        unless pessoa_do_projeto.itens_do_projeto_por_pessoa.iniciais.where(item_do_lote_id: item_lote.id).any?
          item_do_projeto_por_pessoa_inicial = pessoa_do_projeto.itens_do_projeto_por_pessoa.new(
            item_do_lote_id: item_lote.id,
            preco: row["Vl. Unit."].gsub(",", ".").to_f,
            marca: row["Marca"],
            valido: true,
            final: false
          )

          item_do_projeto_por_pessoa_inicial.save
        end

        unless pessoa_do_projeto.itens_do_projeto_por_pessoa.finais.where(item_do_lote_id: item_lote.id).any?
          itens_do_projeto_por_pessoa_final = pessoa_do_projeto.itens_do_projeto_por_pessoa.new(
            item_do_lote_id: item_lote.id,
            preco: row["Vl. Unit."].gsub(",", ".").to_f,
            marca: row["Marca"],
            valido: true,
            final: true
          )

          itens_do_projeto_por_pessoa_final.save
        end

        if self.processo.pregao_presencial? || self.processo.pregao_eletronico?
          valores_lote = csv.select { |a| a["Lote"] == lote.numero.to_s }
          soma_lote = valores_lote.map { |a| a["Vl. Total"].gsub(",", ".").to_f }.sum.to_f

          rodada = Licitacao::Rodada.where(lote_id: lote.id).first rescue nil

          unless rodada.present?
            if lote.lances_abertos == false
              lote.lances_abertos = true
              lote.save(validate: false)
            end

            rodada = Licitacao::Rodada.new(
              lote_id: lote.id,
              numero: 0,
              desempate: true,
              arquivo_bll: true
            )
          end

          lance = rodada.lances.first rescue nil

          unless lance.present?
            rodada.lances.new(
              pessoa_do_projeto_id: pessoa_do_projeto.id,
              valor: soma_lote,
              desistir: false
            )
          end

          rodada.save(validate: false)
        end

        pessoa_do_projeto_do_lote = pessoa_do_projeto.pessoas_do_projeto_do_lote.where(lote_id: lote.id).first rescue nil

        unless pessoa_do_projeto_do_lote.present?
          pessoa_do_projeto_do_lote = Licitacao::PessoaDoProjetoDoLote.new(
            lote_id: lote.id,
            pessoa_do_projeto_id: pessoa_do_projeto.id,
            habilitado: true
          )

          pessoa_do_projeto_do_lote.save(validate: false)
        end

        lote.lances_abertos = false
        lote.ganhador_id = pessoa_do_projeto.id
        lote.save(validate: false)
      end
      self.processado = true
      self.save
    else
      raise StandardError.new "Arquivo possui licitantes que não foram adicionados no processo."
    end
  end

  def grava_participantes
    csv_text = Paperclip.io_adapters.for(self.file).read.force_encoding(Encoding::UTF_8)
    csv = CSV.parse(csv_text, :headers => true)
    csv.each do |row|

      pessoa = Base::Pessoa.where("TRIM(cpf) = ? or TRIM(cnpj) = ?", row["Documento"], row["Documento"]).first rescue nil

      unless pessoa.present?
        cpf = row["Documento"] if row["Documento"].size == 11
        cnpj = row["Documento"] if row["Documento"].size == 14
        estado = Base::Estado.where("uf = ?", row["UF"]).first
        cidade = Base::Cidade.where("TRIM(UPPER(nome)) = ? and estado_id = ?", row["Cidade"].try(:upcase), estado.id).first

        pessoa = Base::Pessoa.new(
          nome: row["Participante"],
          tipo_de_pessoa_id: row["Documento"].size == 14 ? 2 : 1,
          cpf: cpf,
          cnpj: cnpj,
          cep: row["CEP"],
          logradouro: row["Endereço"].split(",")[0],
          numero: row["Endereço"].split(",")[1],
          bairro: row["Bairro"],
          cidade_id: cidade.id,
          telefone: row["Telefone"],
          email: row["Email", 0],
          data_do_cadastro: Date.today
        )

        pessoa.save(validate: false)
      end

      pessoa_do_projeto = self.processo.pessoas_do_projeto.where(pessoa_id: pessoa.id).first rescue nil

      unless pessoa_do_projeto.present?
        self.processo.pessoas_do_projeto.new(
          pessoa_id: pessoa.id,
          cpf_do_responsavel: row["CPF"],
          nome_do_responsavel: row["Representante"],
          credenciado: true
        ).save(validate: false)
      end

    end
    self.processado = true
    self.save
  end

  def desfaz_processamento_de_arquivo
    case self.tipo_de_arquivo
    when "relacao_de_vencedores"
      self.apaga_relacao_de_vencedores
    when "participantes"
      self.apaga_participantes
    when "lotes_mal_sucedidos"
      valido = true
    when "participantes_desclassificados"
      valido = true
    when "propostas"
      valido = true
    end
  end

  def apaga_relacao_de_vencedores
    csv_text = Paperclip.io_adapters.for(self.file).read.force_encoding(Encoding::UTF_8)
    csv = CSV.parse(csv_text, :headers => true)

    csv.each do |row|
      lote = self.processo.lotes.where(numero: row["Lote"].to_s).first
      item_lote = lote.itens_do_lote.where("sequencia = ? or (sequencia = 0 and ? = 1)", row["Item"].to_i, row["Item"].to_i).first
      pessoa = self.processo.pessoas.select { |pessoa| pessoa.cpf_ou_cnpj_sem_pontos == row["CPF/CNPJ"] }.first
      pessoa_do_projeto = self.processo.pessoas_do_projeto.where(pessoa_id: pessoa.id).first rescue nil

      item_do_projeto_por_pessoa_final = pessoa_do_projeto.itens_do_projeto_por_pessoa.finais.where(item_do_lote_id: item_lote.id).first rescue nil
      item_do_projeto_por_pessoa_final.destroy if item_do_projeto_por_pessoa_final.present?

      lote.lances_abertos = true
      lote.ganhador_id = nil
      lote.save(validate: false)
    end
    self.processado = false
    self.save
  end

  def apaga_participantes
    csv_text = Paperclip.io_adapters.for(self.file).read.force_encoding(Encoding::UTF_8)
    csv = CSV.parse(csv_text, :headers => true)
    csv.each do |row|

      pessoa = Base::Pessoa.where("TRIM(cpf) = ? or TRIM(cnpj) = ?", row["Documento"], row["Documento"]).first rescue nil
      pessoa_do_projeto = self.processo.pessoas_do_projeto.where(pessoa_id: pessoa.id).first rescue nil

      unless pessoa_do_projeto.pessoas_do_projeto_do_lote.any? && pessoa_do_projeto.itens_do_projeto_por_pessoa.any?
        pessoa_do_projeto.destroy
      end
    end
    self.processado = false
    self.save
  end

end
