package br.com.elotech.websaude.integracao.esus.controller;

import br.com.elotech.websaude.integracao.esus.model.BD;
import br.com.elotech.websaude.integracao.esus.model.BancoCadastroDomiciliar;
import br.com.elotech.websaude.integracao.esus.model.EsusHistoricoItens;
import br.com.elotech.websaude.integracao.esus.model.enums.TipoDadoSerializado;
import br.com.elotech.websaude.integracao.esus.util.Compactador;
import br.com.elotech.websaude.integracao.esus.util.DataConvert;
import br.com.elotech.websaude.integracao.esus.util.Util;
import br.ufsc.esus.cadastrodomiciliar.CadastroDomiciliarTransport;
import br.ufsc.esus.condicaomoradia.CondicaoMoradiaTransport;
import br.ufsc.esus.dadoinstalacao.DadoInstalacaoTransport;
import br.ufsc.esus.dadotransporte.DadoTransporteTransportCadastroDomiciliarXml;
import br.ufsc.esus.enderecolocalpermanencia.EnderecoLocalPermanenciaTransport;
import br.ufsc.esus.familiarow.FamiliaRowTransport;
import br.ufsc.esus.instituicaopermanencia.InstituicaoPermanencia;
import br.ufsc.esus.unicalotacaoheader.UnicaLotacaoHeaderTransport;
import br.ufsc.esus.versao.VersaoTransport;
import org.apache.commons.lang3.StringUtils;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.Date;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class CadastroDomiciliar extends BD {

  public void executeMain(int eehCodigo, DadoInstalacaoTransport remetenteOriginadora)
    throws SQLException, JAXBException, IOException {
    BancoCadastroDomiciliar bdCadastroDomiciliar = new BancoCadastroDomiciliar();
    EsusHistoricoItens bdEsusHistoricoItens = new EsusHistoricoItens();
    List<HashMap> dadosCadastroDomiciliar = bdCadastroDomiciliar.getDadosCadastroDomiciliar();

    for (HashMap hash : dadosCadastroDomiciliar) {
      CadastroDomiciliar cadastroDomiciliar = new CadastroDomiciliar();
      String uuid = cadastroDomiciliar.getGUID();
      CadastroDomiciliarTransport fichaMaster = cadastroDomiciliarThrift(uuid, hash);
      DadoTransporteTransportCadastroDomiciliarXml arrayEnvio = montaArrayEnvioDto(fichaMaster, uuid, hash,
        eehCodigo, remetenteOriginadora);

      zipWriter(arrayEnvio, uuid);
      bdEsusHistoricoItens.registratHistoricoItens(eehCodigo, uuid, 2);
      int coCdsCadDomiciliar = Long.valueOf(hash.get("co_cds_cad_domiciliar").toString()).intValue();
      bdCadastroDomiciliar.atualizaStatus(uuid, coCdsCadDomiciliar);
    }

  }

  public void zipWriter(DadoTransporteTransportCadastroDomiciliarXml xmlText, String uuid)
    throws JAXBException, IOException {
    // Define nome do arquivo
    String arquivo = uuid + ".esus.xml";
    br.ufsc.esus.dadotransporte.ObjectFactoryCadastroDomiciliar factoryCadastroIndividual = new br.ufsc.esus.dadotransporte.ObjectFactoryCadastroDomiciliar();

    JAXBContext context;
    context = JAXBContext.newInstance(br.ufsc.esus.dadotransporte.ObjectFactoryCadastroDomiciliar.class);
    JAXBElement<DadoTransporteTransportCadastroDomiciliarXml> element
      = factoryCadastroIndividual.createDadoTransporteTransportCadastroDomiciliarXml(xmlText);
    Marshaller marshaller = context.createMarshaller();
    marshaller.setProperty("jaxb.formatted.output", Boolean.TRUE);
    marshaller.marshal(element, new FileWriter("arqs/" + arquivo));
    Compactador.ARQUIVOS.add(arquivo);

  }

  private CadastroDomiciliarTransport cadastroDomiciliarThrift(String uuid, HashMap row) throws SQLException {
    CadastroDomiciliarTransport arrayCad = new CadastroDomiciliarTransport();
    arrayCad.setHeaderTransport(headerCdsCadastroThrift(row));
    arrayCad.setUuid(uuid);
    arrayCad.setUuidFichaOriginadora(uuid);
    long tipoImovel = Long.parseLong(Util.verificaNulo(row.get("tipo_imovel")));
    arrayCad.setEnderecoLocalPermanencia(enderecoLocalPermanenciaThrift(row));
    arrayCad.setFichaAtualizada(Boolean.TRUE);
    arrayCad.setTpCdsOrigem(3);
    arrayCad.setTipoDeImovel(tipoImovel);
    if (tipoImovel != 0 && (tipoImovel < 2 || tipoImovel > 6) &&
      tipoImovel != 12 && tipoImovel != 99 && row.get("localizacao") != null) {
      arrayCad.setCondicaoMoradia(condicaoMoradiaThrift(row));
    }
    if (tipoImovel == 1) {
      BancoCadastroDomiciliar bdCadastroIndividual = new BancoCadastroDomiciliar();
      ResultSet dadosAnimais = bdCadastroIndividual
        .getAnimaisNoDomicilio(Integer.valueOf(Util.verificaNulo(row.get("co_cds_cad_domiciliar"))));
      List<Long> arrayAnimais = new ArrayList<>();
      if (row.get("animais_domicilio") != null && "1".equals(row.get("animais_domicilio").toString())) {
        arrayCad.setStAnimaisNoDomicilio(true);

        if (!"0".equals(row.get("quantidade_animais_domicilio"))) {
          arrayCad.setQuantosAnimaisNoDomicilio((String) row.get("quantidade_animais_domicilio"));
        }
        while (dadosAnimais.next()) {
          arrayAnimais.add(dadosAnimais.getLong("co_pergunta_detalhe"));
        }
        arrayCad.getAnimaisNoDomicilio().addAll(arrayAnimais);
        dadosAnimais.close();
      } else {
        arrayCad.setStAnimaisNoDomicilio(false);
      }
      arrayCad.getFamilias().add(familiaRowThrift(row));
    }
    if (row.get("ipe_resp_nome") != null && (tipoImovel > 6 && tipoImovel < 12)) {
      arrayCad.setInstituicaoPermanencia(instituicaoPermanencia(row));
    }
    if (row.get("usu_recusa") != null) {
      arrayCad.setStatusTermoRecusa("t".equals(row.get("usu_recusa").toString()));
      if ("t".equals(row.get("usu_recusa").toString())) {
        arrayCad.setCondicaoMoradia(null);
        arrayCad.setStAnimaisNoDomicilio(null);
        arrayCad.setQuantosAnimaisNoDomicilio(null);
        arrayCad.setInstituicaoPermanencia(null);
        arrayCad.getAnimaisNoDomicilio().clear();
        arrayCad.getFamilias().clear();
      }
      return arrayCad;
    }
    return arrayCad;
  }

  public InstituicaoPermanencia instituicaoPermanencia(HashMap row) {
    InstituicaoPermanencia instituicaoPermanencia = new InstituicaoPermanencia();
    if (row.get("ipe_nome") != null && !row.get("ipe_nome").equals("")) {
      instituicaoPermanencia.setNomeInstituicaoPermanencia((String) row.get("ipe_nome"));
    }
    if (row.get("ipe_st_outros") != null && !row.get("ipe_st_outros").equals("")) {
      instituicaoPermanencia
        .setStOutrosProfissionaisVinculados(Boolean.valueOf(Util.verificaNulo(row.get("ipe_st_outros"))));
    }
    instituicaoPermanencia.setNomeResponsavelTecnico((String) row.get("ipe_resp_nome"));
    if (row.get("ipe_resp_cns") != null && !row.get("ipe_resp_cns").equals("")) {
      instituicaoPermanencia.setCnsResponsavelTecnico((String) row.get("ipe_resp_cns"));
    }
    if (row.get("ipe_resp_cargo") != null && !row.get("ipe_resp_cargo").equals("")) {
      instituicaoPermanencia.setCargoInstituicao((String) row.get("ipe_resp_cargo"));
    }
    if (row.get("ipe_resp_telefone") != null && !row.get("ipe_resp_telefone").equals("")) {
      String telefoneCelular = ((String) row.get("ipe_resp_telefone")).replaceAll("\\D", "");
      instituicaoPermanencia.setTelefoneResponsavelTecnico(telefoneCelular);
    }
    return instituicaoPermanencia;
  }

  public FamiliaRowTransport familiaRowThrift(HashMap row) throws SQLException {
    BancoCadastroDomiciliar bdCadastroDomiciliar = new BancoCadastroDomiciliar();
    ResultSet array = bdCadastroDomiciliar.getDadosFamilia((Integer) row.get("co_cds_cad_domiciliar"));
    FamiliaRowTransport dadosFamilia = new FamiliaRowTransport();

    if (array.next()) {
      dadosFamilia.setDataNascimentoResponsavel(DataConvert.dateToEpoch(array.getDate("usu_datanasc")));
      dadosFamilia.setNumeroCnsResponsavel(
        (validaCnsBanco(array.getString("usu_cartao_sus")) ? array.getString("usu_cartao_sus") : null));
      if (dadosFamilia.getNumeroCnsResponsavel() == null && validaCpf(array.getString("usu_cpf"))) {
        dadosFamilia.setCpfResponsavel(array.getString("usu_cpf"));
      }
      dadosFamilia.setNumeroProntuario(array.getString("usu_prontuario"));
    }
    array.close();
    return dadosFamilia;
  }

  public CondicaoMoradiaTransport condicaoMoradiaThrift(HashMap item) {
    CondicaoMoradiaTransport condicaoMoradia = new CondicaoMoradiaTransport();
    long tipoImovel = Long.parseLong(item.get("tipo_imovel").toString());

    if (item.get("situacao_moradia") != null && (tipoImovel < 7 || tipoImovel > 11)) {
      condicaoMoradia.setSituacaoMoradiaPosseTerra(Long.valueOf(item.get("situacao_moradia").toString()));
    }
    if (item.get("localizacao") != null) {
      condicaoMoradia.setLocalizacao(Long.valueOf(item.get("localizacao").toString()));
    }
    if (item.get("tipo_domicilio") != null) {
      condicaoMoradia.setTipoDomicilio(Long.valueOf(item.get("tipo_domicilio").toString()));
    }
    condicaoMoradia.setNuMoradores((String) item.get("numero_moradores"));
    condicaoMoradia.setNuComodos((String) item.get("numero_comodos"));
    if (item.get("tipo_acesso") != null) {
      condicaoMoradia.setTipoAcessoDomicilio(Long.valueOf(item.get("tipo_acesso").toString()));
    }
    if (item.get("energia_eletrica") != null) {
      condicaoMoradia.setStDisponibilidadeEnergiaEletrica("1".equals(item.get("energia_eletrica").toString()));
    }
    if (item.get("destino_lixo") != null) {
      condicaoMoradia.setDestinoLixo(Long.valueOf(item.get("destino_lixo").toString()));
    }
    if (item.get("tratamento_agua") != null) {
      condicaoMoradia.setAguaConsumoDomicilio(Long.valueOf(item.get("tratamento_agua").toString()));
    }
    if (item.get("posse_terra") != null) {
      condicaoMoradia.setAreaProducaoRural(Long.valueOf(item.get("posse_terra").toString()));
    }
    if (item.get("material_domicilio") != null) {
      condicaoMoradia
        .setMaterialPredominanteParedesExtDomicilio(Long.valueOf(item.get("material_domicilio").toString()));
    }
    if (item.get("abastecimento_agua") != null) {
      condicaoMoradia.setAbastecimentoAgua(Long.valueOf(item.get("abastecimento_agua").toString()));
    }
    if (item.get("escoamento_sanitario") != null) {
      condicaoMoradia.setFormaEscoamentoBanheiro(Long.valueOf(item.get("escoamento_sanitario").toString()));
    }
    return condicaoMoradia;
  }

  public UnicaLotacaoHeaderTransport headerCdsCadastroThrift(HashMap item) throws SQLException {
    UnicaLotacaoHeaderTransport headerCadDomiciliar = new UnicaLotacaoHeaderTransport();
    String cnsProfissional = Util.verificaNulo(item.get("cns_profissional"));
    headerCadDomiciliar.setProfissionalCNS((validaCnsBanco(cnsProfissional) ? cnsProfissional : null));
    headerCadDomiciliar.setCboCodigo2002(getCbo(item));
    headerCadDomiciliar.setCnes(Util.verificaNulo(item.get("cnes_unidade")));
    if (headerCadDomiciliar.getCnes() != null) {
      headerCadDomiciliar.setCnes(StringUtils.leftPad(headerCadDomiciliar.getCnes(), 7, "0"));
    }
    headerCadDomiciliar.setIne(Util.verificaNulo(item.get("nu_ine")));
    headerCadDomiciliar
      .setDataAtendimento(DataConvert.dateToEpoch(Date.valueOf(Util.verificaNulo(item.get("data_atendimento")))));
    headerCadDomiciliar.setCodigoIbgeMunicipio(Util.verificaNulo(item.get("codigo_ibge_municipio")));

    return headerCadDomiciliar;
  }

  public String getCbo(HashMap row) throws SQLException {
    BancoCadastroDomiciliar bdCadastroDomiciliar = new BancoCadastroDomiciliar();
    ResultSet retorno = bdCadastroDomiciliar.getCbo(Integer.valueOf(Util.verificaNulo(row.get("usr_codigo"))));
    if (retorno.next()) {
      return retorno.getString(1);
    }
    return null;
  }

  public EnderecoLocalPermanenciaTransport enderecoLocalPermanenciaThrift(HashMap item) {
    EnderecoLocalPermanenciaTransport enderecoLocalPermanencia = new EnderecoLocalPermanenciaTransport();
    enderecoLocalPermanencia.setBairro(Util.verificaNulo(item.get("bairro")));
    enderecoLocalPermanencia.setCep(Util.verificaNulo(item.get("cep")));
    enderecoLocalPermanencia.setCodigoIbgeMunicipio(Util.verificaNulo(item.get("cid_codigo_ibge")));
    enderecoLocalPermanencia.setNomeLogradouro(Util.verificaNulo(item.get("nome_logradouro")));
    enderecoLocalPermanencia.setNumero(Util.verificaNulo(item.get("numero")));
    enderecoLocalPermanencia.setNumeroDneUf(Util.verificaNulo(item.get("estado")));
    enderecoLocalPermanencia.setTipoLogradouroNumeroDne(Util.verificaNulo(item.get("tipo_logradouro_numero_dne")));
    enderecoLocalPermanencia.setComplemento(Util.verificaNulo(item.get("complemento")));
    enderecoLocalPermanencia.setPontoReferencia(Util.verificaNulo(item.get("dom_ponto_referencia")));
    if (item.get("dom_telefone") != null) {
      String telefoneCelular = item.get("dom_telefone").toString().replaceAll("\\D", "");
      enderecoLocalPermanencia.setTelefoneResidencia(telefoneCelular);
    }

    enderecoLocalPermanencia.setStForaArea(false);
    if (item.get("dom_microarea_fa") != null) {
      if (!(item.get("dom_microarea_fa").toString().contains("t"))) {
        enderecoLocalPermanencia.setMicroArea(Util.verificaNulo(item.get("dom_microarea")));
        enderecoLocalPermanencia.setStForaArea(false);
      } else {
        enderecoLocalPermanencia.setStForaArea(true);
      }
    } else {
      enderecoLocalPermanencia.setMicroArea(Util.verificaNulo(item.get("dom_microarea")));
    }

    return enderecoLocalPermanencia;
  }

  private DadoTransporteTransportCadastroDomiciliarXml montaArrayEnvioDto(
    CadastroDomiciliarTransport fichaMasterSerializado, String uuid, HashMap row, int eehCodigo,
    DadoInstalacaoTransport remetenteOriginadora) {

    remetenteOriginadora.setUuidInstalacao(uuid);

    VersaoTransport arrayVersao = new VersaoTransport();
    arrayVersao.setMajor(3);
    arrayVersao.setMinor(2);
    arrayVersao.setRevision(4);

    DadoTransporteTransportCadastroDomiciliarXml dadoTransporteTransportXml = new DadoTransporteTransportCadastroDomiciliarXml();
    dadoTransporteTransportXml.setUuidDadoSerializado(uuid);
    dadoTransporteTransportXml.setTipoDadoSerializado(TipoDadoSerializado.CADASTRODOMICILIAR.getValue());
    dadoTransporteTransportXml
      .setCnesDadoSerializado((row.get("cnes_unidade") != null ? StringUtils.leftPad(row.get("cnes_unidade").toString(), 7, "0") : null));
    dadoTransporteTransportXml
      .setCodIbge((row.get("codigo_ibge_municipio") != null ? row.get("codigo_ibge_municipio").toString() : null));
    dadoTransporteTransportXml.setIneDadoSerializado((row.get("nu_ine") != null ? row.get("nu_ine").toString() : null));
    dadoTransporteTransportXml.setNumLote(eehCodigo);
    dadoTransporteTransportXml.setRemetente(remetenteOriginadora);
    dadoTransporteTransportXml.setOriginadora(remetenteOriginadora);
    dadoTransporteTransportXml.setVersao(arrayVersao);
    dadoTransporteTransportXml.setCadastroDomiciliarTransport(fichaMasterSerializado);

    return dadoTransporteTransportXml;
  }

}
