package br.com.elotech.saude.scripts;

import br.com.elotech.enuns.TipoRelEnum;
import br.com.elotech.saude.model.filters.estratificacao.*;
import br.com.elotech.util.Util;
import org.apache.commons.lang3.StringUtils;

public abstract class EstratificacaoRiscoScript {

    private static StringBuilder sb;

    //Gestantes e Puérperas
    public static String getSqlGestantesPuerperasSintetico(EstratificacaoGestantesPuerperasFilter filter) {
        sb = new StringBuilder();
        sb.append(" SELECT ")
                .append("     CASE usu.risco_gestacao ")
                .append("         WHEN 'A' THEN 'ALTO' ")
                .append("         WHEN 'M' THEN 'INTERMEDIÁRIO' ")
                .append("         WHEN 'B' THEN 'HABITUAL' ")
                .append("         ELSE 'Não Estratificado' ")
                .append("      END AS risco_gestacao, ")
                .append("     COALESCE(mic_descricao, 'Não informada') AS microarea, ")
                .append("     usr.usr_nome                             AS responsavel, ")
                .append("     COALESCE(eq.no_equipe, 'Não informada')  AS equipe, ")
                .append("     COUNT(ate.ate_codigo) AS qtde_atendimentos_gestacao ")
                .append("   FROM usuario usu ")
                .append("   JOIN (select ")
                .append("         max(ate.ate_codigo) as ate_codigo, ")
                .append("         usu_codigo, ")
                .append("         atp2.tipo_consulta as tipo_consulta ")
                .append("         from atendimento ate inner join atendimento_prenatal atp2 on atp2.ate_codigo = ate.ate_codigo ")
                .append("         group by ate.usu_codigo, atp2.tipo_consulta) AS ultimo_atendimento ")
                .append("     ON usu.usu_codigo = ultimo_atendimento.usu_codigo ")
                .append("   JOIN atendimento ate ON ate.ate_codigo = ultimo_atendimento.ate_codigo ")
                .append("   JOIN atendimento_prenatal atp ON atp.ate_codigo = ate.ate_codigo ")
                .append("   LEFT JOIN microarea mic ON mic.mic_codigo = usu.usu_microarea ")
                .append("   LEFT JOIN usuarios usr ON mic.mic_responsavel = usr.usr_codigo")
                .append("   LEFT JOIN tb_equipe eq ON mic.co_seq_equipe = eq.co_seq_equipe ")
                .append("  WHERE ultimo_atendimento.tipo_consulta = :tipo_consulta")
                .append("   AND usu.usu_mudanca_territorio = 'f'");
        if(filter.getTpDados().getRet() == 1){
              sb.append("   AND usu.usu_esta_gestante IS TRUE");
        }
        if (StringUtils.isNotBlank(filter.getEquipe())) {
            sb.append(" AND eq.nu_ine = :nu_equipe");
        }
        if (filter.getProfissional() != null) {
            sb.append(" AND mic.mic_responsavel = :mic_responsavel");
        }
        if (filter.getRisco() != null) {
            if (filter.getRisco().equals("N")) {
                sb.append(" AND usu.risco_gestacao IS NULL");
            } else {
                sb.append(" AND usu.risco_gestacao = :risco_gestacao");
            }
        }

        sb.append(" GROUP BY 1,2,3,4, usu.risco_gestacao ")
                .append(" ORDER BY CASE usu.risco_gestacao ")
                .append("           WHEN 'A' then 1 ")
                .append("           WHEN 'M' then 2 ")
                .append("           WHEN 'B' then 3 ")
                .append("           WHEN 'N' then 4 END ");
        return sb.toString();
    }

    public static String getSqlGestantesPuerperasAnalitico(EstratificacaoGestantesPuerperasFilter filter) {
        sb = new StringBuilder();
        sb.append(" SELECT ")
                .append("     COALESCE(eq.no_equipe, 'Não informada')        AS equipe")
                .append("     ,COALESCE(mic_descricao, 'Não informada')      AS microarea")
                .append("     ,usr.usr_nome                                  AS responsavel")
                .append("     ,usu.usu_nome                                  AS cidadao")
                .append("     ,usu.usu_datanasc                              AS dt_nascimento")
                .append("     ,EXTRACT(YEAR FROM age(usu.usu_datanasc))      AS idade")
                .append("     ,usu.usu_cartao_sus                            AS cns")
                .append("     ,ultimo_atendimento.ate_codigo                 AS ate_codigo")
                .append("     ,CASE WHEN ultimo_atendimento.tipo_consulta = 1 THEN 'GESTANTE' ELSE 'PUÉRPERA' END AS tipo_consulta")
                .append("     ,max(atp.numero_gestacao)                            AS num_gestacao ")
                .append("     ,COALESCE(idade_gestacional, 0)                AS idade_gestacional")
                .append("     ,atp.data_provavel_parto                       AS dt_provavel_parto")
                .append("     ,CASE usu.risco_gestacao")
                .append("         WHEN 'A' THEN 'ALTO' ")
                .append("         WHEN 'M' THEN 'INTERMEDIÁRIO' ")
                .append("         WHEN 'B' THEN 'HABITUAL' ")
                .append("         ELSE 'Não Estratificado' ")
                .append("      END AS risco_gestacao")
                .append("     ,atp.data_ultimo_parto                         AS dt_ultimo_parto")
                .append("     ,qtd_atendimentos_gestacao                     AS qtde_atendimentos_gestacao")
                .append("   FROM usuario usu")
                .append("   JOIN (")
                .append("         select")
                .append("         max(ate.ate_codigo) as ate_codigo,")
                .append("         usu_codigo")
                .append("         ,atp2.tipo_consulta as tipo_consulta")
                .append("         from atendimento ate")
                .append("         inner join atendimento_prenatal atp2 on atp2.ate_codigo = ate.ate_codigo")
                .append("         group by ate.usu_codigo, atp2.tipo_consulta")
                .append("   ) AS ultimo_atendimento ON usu.usu_codigo = ultimo_atendimento.usu_codigo")
                .append("   LEFT JOIN (")
                .append("         SELECT")
                .append("             ate.usu_codigo        as usu_codigo,")
                .append("             COUNT(ate.ate_codigo) as qtd_atendimentos_gestacao")
                .append("           FROM atendimento ate")
                .append("           JOIN atendimento_prenatal atp on atp.ate_codigo = ate.ate_codigo")
                .append("          WHERE atp.numero_gestacao = atp.numero_gestacao")
                .append("          GROUP BY ate.usu_codigo")
                .append("   ) AS gestacao_atual ON usu.usu_codigo = gestacao_atual.usu_codigo")
                .append("   LEFT JOIN atendimento ate ON ate.ate_codigo = ultimo_atendimento.ate_codigo")
                .append("   LEFT JOIN atendimento_prenatal atp ON atp.ate_codigo = ate.ate_codigo")
                .append("   LEFT JOIN microarea mic ON mic.mic_codigo = usu.usu_microarea")
                .append("   LEFT JOIN usuarios usr ON mic.mic_responsavel = usr.usr_codigo")
                .append("   LEFT JOIN tb_equipe eq ON mic.co_seq_equipe = eq.co_seq_equipe")
                .append("   WHERE ultimo_atendimento.tipo_consulta = :tipo_consulta")
                .append("   AND usu.usu_mudanca_territorio = 'f'");
        if(filter.getTpDados().getRet() == 1){
              sb.append("   AND usu.usu_esta_gestante IS TRUE");
        }

        if (StringUtils.isNotBlank(filter.getEquipe())) {
            sb.append(" AND eq.nu_ine = :nu_equipe");
        }
        if (filter.getProfissional() != null) {
            sb.append(" AND mic.mic_responsavel = :mic_responsavel");
        }
        if (filter.getRisco() != null) {
            if (filter.getRisco().equals("N")) {
                sb.append(" AND usu.risco_gestacao IS NULL");
            } else {
                sb.append(" AND usu.risco_gestacao = :risco");
            }
        }
        sb.append("  GROUP BY (eq.no_equipe, mic_descricao, usr.usr_nome, usu.usu_nome, usu.usu_datanasc, usu.usu_cartao_sus, "
          + " ultimo_atendimento.ate_codigo, ultimo_atendimento.tipo_consulta, idade_gestacional, "
          + " atp.data_provavel_parto, usu.risco_gestacao, atp.data_ultimo_parto, qtd_atendimentos_gestacao)");
        sb.append(" ORDER BY CASE usu.risco_gestacao")
                .append("  WHEN 'A' THEN 1 ")
                .append("  WHEN 'M' THEN 2 ")
                .append("  WHEN 'B' THEN 3 ")
                .append("  WHEN 'N' THEN 4 END, eq.no_equipe, mic_descricao");
        return sb.toString();
    }

    public static String getSqlSaudeBucalSintetico(EstratificacaoSaudeBucalFilter filter) {
        sb = new StringBuilder();
        sb.append(" SELECT ")
                .append("     CASE usu.risco_odonto")
                .append("         WHEN 'A' THEN 'ALTO'")
                .append("         WHEN 'M' THEN 'MÉDIO'")
                .append("         WHEN 'B' THEN 'BAIXO'")
                .append("         ELSE 'NÃO ESTRATIFICADO'")
                .append("     END AS risco")
                .append("    ,COALESCE(eq.no_equipe, 'Não Informada')      AS equipe")
                .append("    ,COALESCE(mic.mic_descricao, 'Não Informada') AS microarea")
                .append("    ,COALESCE(usr.usr_nome, 'Não Informado')      AS responsavel")
                .append("    ,COUNT(usu.usu_codigo) AS quantidade")
                .append("  FROM usuario usu")
                .append("  LEFT JOIN microarea mic ON mic.mic_codigo      = usu.usu_microarea")
                .append("  LEFT JOIN usuarios usr  ON mic.mic_responsavel = usr.usr_codigo")
                .append("  LEFT JOIN tb_equipe eq  ON mic.co_seq_equipe   = eq.co_seq_equipe")
                .append(" WHERE usu.uni_codigo = :uni_codigo AND usu.usu_mudanca_territorio = 'f'");
        if (StringUtils.isNotBlank(filter.getEquipe())) {
            sb.append(" AND eq.nu_ine = :nu_equipe");
        }
        if (filter.getProfissional() != null) {
            sb.append(" AND mic.mic_responsavel = :mic_responsavel");
        }
        if (filter.getRisco() != null) {
            if (filter.getRisco().equals("N")) {
                sb.append(" AND usu.risco_odonto IS NULL");
            } else {
                sb.append(" AND usu.risco_odonto = :risco");
            }
        }
        sb.append(" GROUP BY usu.risco_odonto, eq.no_equipe, mic.mic_descricao, usr.usr_nome")
                .append(" ORDER BY")
                .append("     CASE usu.risco_odonto ")
                .append("         WHEN 'A' THEN 1")
                .append("         WHEN 'M' THEN 2")
                .append("         WHEN 'B' THEN 3")
                .append("         ELSE 4 END ")
                .append("    ,CASE WHEN eq.no_equipe  IS NULL THEN 2 ELSE 1 END ")
                .append("    ,CASE WHEN mic.mic_descricao IS NULL THEN 2 ELSE 1 END");
        return sb.toString();
    }

    public static String getSqlSaudeBucalAnalitico(EstratificacaoSaudeBucalFilter filter) {
        sb = new StringBuilder();
        sb.append(" SELECT ")
                .append("     CASE usu.risco_odonto")
                .append("         WHEN 'A' THEN 'ALTO'")
                .append("         WHEN 'M' THEN 'MÉDIO'")
                .append("         WHEN 'B' THEN 'BAIXO'")
                .append("         ELSE 'NÃO ESTRATIFICADO'")
                .append("     END AS risco")
                .append("     ,COALESCE(eq.no_equipe, 'Não Informada')      AS equipe")
                .append("     ,COALESCE(mic.mic_descricao, 'Não Informada') AS microarea")
                .append("     ,COALESCE(usr.usr_nome, 'Não Informado')      AS responsavel")
                .append("     ,usu.usu_nome                                 AS cidadao")
                .append("     ,usu.usu_datanasc                             AS dt_nascimento")
                .append("     ,usu.usu_cartao_sus                           AS cns")
                .append("     ,EXTRACT(YEAR FROM age(usu.usu_datanasc))     AS idade")
                .append("  FROM usuario usu")
                .append("  LEFT JOIN microarea mic ON mic.mic_codigo = usu.usu_microarea")
                .append("  LEFT JOIN usuarios usr ON mic.mic_responsavel = usr.usr_codigo")
                .append("  LEFT JOIN tb_equipe eq ON mic.co_seq_equipe = eq.co_seq_equipe")
                .append(" WHERE usu.uni_codigo = :uni_codigo AND usu.usu_mudanca_territorio = 'f'");
        if (StringUtils.isNotBlank(filter.getEquipe())) {
            sb.append(" AND eq.nu_ine = :nu_equipe");
        }
        if (filter.getProfissional() != null) {
            sb.append(" AND mic.mic_responsavel = :mic_responsavel");
        }
        if (filter.getRisco() != null) {
            if (filter.getRisco().equals("N")) {
                sb.append(" AND usu.risco_odonto IS NULL");
            } else {
                sb.append(" AND usu.risco_odonto = :risco");
            }
        }
        sb.append(" ORDER BY")
                .append("     CASE usu.risco_odonto ")
                .append("         WHEN 'A' THEN 1")
                .append("         WHEN 'M' THEN 2")
                .append("         WHEN 'B' THEN 3")
                .append("         ELSE 4 END ")
                .append(" ,eq.no_equipe, mic.mic_descricao ");
        return sb.toString();
    }

    public static String getSqlSaudeMentalSintetico(EstratificacaoSaudeMentalFilter filter) {
        sb = new StringBuilder();
        sb.append(" SELECT ")
                .append("     CASE usu.risco_psico")
                .append("         WHEN 'A' THEN 'ALTO'")
                .append("         WHEN 'M' THEN 'MÉDIO'")
                .append("         WHEN 'B' THEN 'BAIXO'")
                .append("         ELSE 'NÃO ESTRATIFICADO'")
                .append("     END AS risco")
                .append("    ,COALESCE(eq.no_equipe, 'Não Informada')      AS equipe")
                .append("    ,COALESCE(mic.mic_descricao, 'Não Informada') AS microarea")
                .append("    ,COALESCE(usr.usr_nome, 'Não Informado')      AS responsavel")
                .append("    ,COUNT(usu.usu_codigo) AS quantidade")
                .append("  FROM usuario usu")
                .append("  LEFT JOIN usuario_info_sociodemo uis ON uis.usu_codigo = usu.usu_codigo")
                .append("  LEFT JOIN microarea mic ON mic.mic_codigo      = usu.usu_microarea")
                .append("  LEFT JOIN usuarios usr  ON mic.mic_responsavel = usr.usr_codigo")
                .append("  LEFT JOIN tb_equipe eq  ON mic.co_seq_equipe   = eq.co_seq_equipe")
                .append(" WHERE usu.uni_codigo = :uni_codigo AND usu.usu_mudanca_territorio = 'f'");
        if (StringUtils.isNotBlank(filter.getEquipe())) {
            sb.append(" AND eq.nu_ine = :nu_equipe");
        }
        if (filter.getProfissional() != null) {
            sb.append(" AND mic.mic_responsavel = :mic_responsavel");
        }
        if (filter.getRisco() != null) {
            if (filter.getRisco().equals("N")) {
                sb.append(" AND usu.risco_psico IS NULL");
            } else {
                sb.append(" AND usu.risco_psico = :risco");
            }
        }
        sb.append(" GROUP BY usu.risco_psico, eq.no_equipe, mic.mic_descricao, usr.usr_nome")
                .append(" ORDER BY")
                .append("     CASE usu.risco_psico ")
                .append("         WHEN 'A' THEN 1")
                .append("         WHEN 'M' THEN 2")
                .append("         WHEN 'B' THEN 3")
                .append("         ELSE 4 END ")
                .append("    ,CASE WHEN eq.no_equipe  IS NULL THEN 2 ELSE 1 END ")
                .append("    ,CASE WHEN mic.mic_descricao IS NULL THEN 2 ELSE 1 END");
        return sb.toString();
    }

    public static String getSqlSaudeMentalAnalitico(EstratificacaoSaudeMentalFilter filter) {
        sb = new StringBuilder();
        sb.append(" SELECT ")
                .append("     CASE usu.risco_psico")
                .append("         WHEN 'A' THEN 'ALTO'")
                .append("         WHEN 'M' THEN 'MÉDIO'")
                .append("         WHEN 'B' THEN 'BAIXO'")
                .append("         ELSE 'NÃO ESTRATIFICADO'")
                .append("     END AS risco")
                .append("     ,COALESCE(eq.no_equipe, 'Não Informada')      AS equipe")
                .append("     ,COALESCE(mic.mic_descricao, 'Não Informada') AS microarea")
                .append("     ,COALESCE(usr.usr_nome, 'Não Informado')      AS responsavel")
                .append("     ,usu.usu_nome                                 AS cidadao")
                .append("     ,usu.usu_datanasc                             AS dt_nascimento")
                .append("     ,usu.usu_cartao_sus                           AS cns")
                .append("     ,EXTRACT(YEAR FROM age(usu.usu_datanasc))     AS idade")
                .append("     ,CASE uis.uis_alcool WHEN 't' THEN 'SIM' WHEN 'f' THEN 'NÃO' ELSE 'Não informado' END AS usa_alcool")
                .append("     ,CASE uis.uis_fumante WHEN 't' THEN 'SIM' WHEN 'f' THEN 'NÃO' ELSE 'Não informado' END AS usa_fumante")
                .append("     ,CASE uis.uis_drogas WHEN 't' THEN 'SIM' WHEN 'f' THEN 'NÃO' ELSE 'Não informado' END AS usa_drogas")
                .append("  FROM usuario usu")
                .append("  LEFT JOIN usuario_info_sociodemo uis ON uis.usu_codigo = usu.usu_codigo")
                .append("  LEFT JOIN microarea mic ON mic.mic_codigo = usu.usu_microarea")
                .append("  LEFT JOIN usuarios usr ON mic.mic_responsavel = usr.usr_codigo")
                .append("  LEFT JOIN tb_equipe eq ON mic.co_seq_equipe = eq.co_seq_equipe")
                .append(" WHERE usu.uni_codigo = :uni_codigo AND usu.usu_mudanca_territorio = 'f' ");
        if (StringUtils.isNotBlank(filter.getEquipe())) {
            sb.append(" AND eq.nu_ine = :nu_equipe");
        }
        if (filter.getProfissional() != null) {
            sb.append(" AND mic.mic_responsavel = :mic_responsavel");
        }
        if (filter.getRisco() != null) {
            if (filter.getRisco().equals("N")) {
                sb.append(" AND usu.risco_psico IS NULL");
            } else {
                sb.append(" AND usu.risco_psico = :risco");
            }
        }
        sb.append(" ORDER BY")
                .append("     CASE usu.risco_psico ")
                .append("         WHEN 'A' THEN 1")
                .append("         WHEN 'M' THEN 2")
                .append("         WHEN 'B' THEN 3")
                .append("         ELSE 4 END ")
                .append(" ,eq.no_equipe, mic.mic_descricao ");
        return sb.toString();
    }

    public static String getSqlEstratificacaoHdi(EstratificacaoHdiFilter filter) {
        StringBuilder compl = new StringBuilder(" WHERE 1=1 AND usu.usu_mudanca_territorio = 'f' AND LOWER(usu.usu_obito) = 'f'");
        compl.append(filter.getUnidade() != null ? " AND usu.uni_codigo = :unidade" : "");
        compl.append(filter.getEquipe() != null ? " AND teq.nu_ine = :equipe" : "");
        compl.append(filter.getProfissional() != null ? " AND mic.mic_responsavel = :profissional" : "");
        if (filter.getHipertenso() != null && filter.getRisco() != null) {
            compl.append(!filter.getRisco().contains("N") ? " AND usu.risco_hipertensao = :risco" : " AND risco_hipertensao IS NULL");
        }
        if (filter.getDiabetico() != null && filter.getRisco() != null) {
            compl.append(!filter.getRisco().contains("N") ? " AND usu.risco_diabetes = :risco" : " AND risco_diabetes IS NULL");
        }
        if (filter.getIdoso() != null && filter.getRisco() != null) {
            compl.append(!filter.getRisco().contains("N") ? " AND usu.risco_idoso = :risco" : " AND risco_idoso IS NULL");
        }
        StringBuilder sbFaixa = new StringBuilder();
        StringBuilder sbCaseFaixa = new StringBuilder();
        if (filter.getFaixaEtaria() != null && !filter.getFaixaEtaria().isEmpty()) {
          sbCaseFaixa.append(", CASE ");
          for (int i = 0; i < filter.getFaixaEtaria().size(); i++) {
            String f = filter.getFaixaEtaria().get(i);
            if (i == 0) {
              sbFaixa.append(" AND (EXTRACT(YEAR FROM age(usu.usu_datanasc)) ".concat(f));
            } else {
              sbFaixa.append(" OR EXTRACT(YEAR FROM age(usu.usu_datanasc)) ".concat(f));
            }
            sbCaseFaixa.append(" WHEN EXTRACT(YEAR FROM age(usu.usu_datanasc)) ")
              .append(f)
              .append(" THEN '")
              .append(Util.getLabelCase(f));
          }

          sbCaseFaixa.append(" ELSE 'Não informado'").append(" END AS faixa ");
          compl.append(sbFaixa).append(" )");
        }
        if (filter.getHipertenso() != null || filter.getDiabetico() != null || filter.getIdoso() != null) {
            Integer aux = 0;
            compl.append(" AND ( ");
            if (filter.getTpRel().equals(TipoRelEnum.ANALITICO)) {
                if (filter.getHipertenso() != null) {
                    compl.append("usu.usu_tem_hipertensao = 't'");
                    aux++;
                }
                if (filter.getDiabetico() != null) {
                    if (aux == 0) {
                        compl.append("usu.usu_tem_diabete = 't'");
                    } else {
                        compl.append(" OR usu.usu_tem_diabete = 't'");
                    }
                    aux++;
                }
            } else {
                if (filter.getHipertenso() != null) {
                    compl.append("usu.hipertenso = '1'");
                    aux++;
                }
                if (filter.getDiabetico() != null) {
                    if (aux == 0) {
                        compl.append("usu.diabetico = '1'");
                    } else {
                        compl.append(" OR usu.diabetico = '1'");
                    }
                    aux++;
                }
            }

            if (filter.getIdoso() != null) {
                if (aux == 0) {

                    compl.append("extract(YEAR FROM age(usu.usu_datanasc)) >= 60");
                } else {
                    compl.append(" OR extract(YEAR FROM age(usu.usu_datanasc)) >= 60");
                }
                aux++;
            }


            compl.append(" )");
        }

        StringBuilder sql = new StringBuilder("SELECT");
        if (filter.getTpRel().equals(TipoRelEnum.ANALITICO)) {
            sql.append(" DISTINCT")
                    .append("   usu.usu_nome AS nome,")
                    .append("  to_char(usu.usu_datanasc, 'DD/MM/YYYY') AS dataNascimento,")
                    .append("  extract(YEAR FROM age(usu.usu_datanasc)) AS idade,")
                    .append("  usu.usu_cartao_sus AS cns,")
                    .append("  teq.nu_ine AS ineEquipe,")
                    .append("  teq.no_equipe AS nomeEquipe,")
                    .append("  mic.mic_descricao AS microArea,")
                    .append("  uni.uni_desc AS unidade,")
                    .append("  usu.usu_tem_hipertensao AS hipertenso,")
                    .append("  usu.usu_tem_diabete AS diabetico,")
                    .append(" CASE ")
                    .append(" WHEN usu.risco_hipertensao = 'A' THEN 'Alto'")
                    .append(" WHEN usu.risco_hipertensao = 'M' THEN 'Médio'")
                    .append(" WHEN usu.risco_hipertensao = 'B' THEN 'Baixo'")
                    .append(" END AS riscohipertensao,")
                    .append(" CASE ")
                    .append(" WHEN usu.risco_diabetes = 'A' THEN 'Alto'")
                    .append(" WHEN usu.risco_diabetes = 'M' THEN 'Médio'")
                    .append(" WHEN usu.risco_diabetes = 'B' THEN 'Baixo'")
                    .append(" END AS riscodiabetes,")
                    .append(" CASE ")
                    .append(" WHEN usu.risco_idoso = 'A' THEN 'Alto'")
                    .append(" WHEN usu.risco_idoso = 'M' THEN 'Médio'")
                    .append(" WHEN usu.risco_idoso = 'B' THEN 'Baixo'")
                    .append(" END AS riscoidoso,")
                    .append(" usr.usr_nome AS responsavel");
            sql.append(sbCaseFaixa);
        } else {
            sql.append("  uni.uni_desc AS unidade,")
                    .append(" teq.no_equipe AS nomeEquipe,")
                    .append(" teq.nu_ine AS ineEquipe,")
                    .append(" mic.mic_descricao AS microArea,")
                    .append(" usr.usr_nome AS responsavel,")
                    .append(" SUM (hipertenso) AS qtde_hipertenso,")
                    .append(" SUM (diabetico) AS qtde_diabetico,")
                    .append(" SUM (idoso) AS qtde_idoso");
            sql.append(sbCaseFaixa);
        }
        if (filter.getTpRel().equals(TipoRelEnum.ANALITICO)) {

            sql.append(" FROM usuario AS usu")
                    .append(" JOIN unidade AS uni ON usu.uni_codigo = uni.uni_codigo")
                    .append(" JOIN microarea AS mic ON usu.usu_microarea = mic.mic_codigo AND mic.ativo IS TRUE")
                    .append(" JOIN tb_equipe AS teq ON mic.co_seq_equipe = teq.co_seq_equipe AND teq.uni_codigo = uni.uni_codigo")
                    .append(" JOIN usuarios AS usr ON mic.mic_responsavel = usr.usr_codigo")
                    .append(compl);
        } else {
            sql.append(" FROM (SELECT")
                    .append(" uni_codigo,")
                    .append(" usu_microarea,")
                    .append(" usu_tem_hipertensao,")
                    .append(" usu_tem_diabete,")
                    .append(" usu_datanasc,")
                    .append(" usu_mudanca_territorio,")
                    .append(" usu_obito,")
                    .append(" risco_hipertensao,")
                    .append(" risco_diabetes,")
                    .append(" risco_idoso,")
                    .append(" CASE WHEN usu.usu_tem_diabete = 't' THEN 1 ELSE 0 END AS diabetico,")
                    .append(" CASE WHEN usu.usu_tem_hipertensao = 't' THEN 1 ELSE 0 END AS hipertenso,")
                    .append(" CASE WHEN extract(YEAR FROM age(usu.usu_datanasc)) >= 60 THEN 1 ELSE 0 END AS idoso")
                    .append(" FROM usuario usu) as usu")
                    .append(" JOIN unidade AS uni ON usu.uni_codigo = uni.uni_codigo")
                    .append(" JOIN microarea AS mic ON usu.usu_microarea = mic.mic_codigo AND mic.ativo IS TRUE")
                    .append(" JOIN tb_equipe AS teq ON mic.co_seq_equipe = teq.co_seq_equipe AND teq.uni_codigo = uni.uni_codigo")
                    .append(" JOIN usuarios as usr ON mic.mic_responsavel = usr.usr_codigo")
                    .append(compl);
        }
        if (filter.getTpRel().equals(TipoRelEnum.ANALITICO)) {
          sql.append(" ORDER BY uni.uni_desc, teq.no_equipe,")
          .append(filter.getFaixaEtaria() != null && !filter.getFaixaEtaria().isEmpty() ? "faixa," : "")
          .append("mic.mic_descricao, usu.usu_nome");
        } else {
          sql.append(" GROUP BY uni.uni_desc, teq.nu_ine, teq.no_equipe, mic.mic_codigo, usr.usr_nome")
            .append(filter.getFaixaEtaria() != null && !filter.getFaixaEtaria().isEmpty() ? ",faixa" : "")
            .append(" ORDER BY uni.uni_desc, teq.no_equipe,")
            .append(filter.getFaixaEtaria() != null && !filter.getFaixaEtaria().isEmpty() ? "faixa," : "")
            .append("mic.mic_descricao");
        }

        return sql.toString();

    }

    //Familiar
    public static String getSqlEstratificacaoFamiliarSintetico(EstratificacaoFamiliarFilter filter) {
        sb = new StringBuilder();
        sb.append("SELECT")
                .append(" uni.uni_desc      AS unidade,")
                .append(" teq.no_equipe     AS nomeEquipe,")
                .append(" teq.nu_ine        AS ineEquipe,")
                .append(" mic.mic_descricao AS microArea,")
                .append(" usr.usr_nome      AS profissional_responsavel,")
                .append(" CASE dom.estrat_risco_familiar")
                .append("   WHEN 'A'")
                .append("     THEN 'Alto'")
                .append("   WHEN 'M'")
                .append("     THEN 'Médio'")
                .append("   WHEN 'B'")
                .append("     THEN 'Baixo'")
                .append("   ELSE 'Não Estratificado'")
                .append("  END               AS estrat_risco_familiar,")
                .append(" COUNT(dom.dom_codigo) AS qtde")
                .append(" FROM domicilio AS dom")
                .append("   JOIN usuario AS usu ON dom.usu_codigo_responsavel = usu.usu_codigo")
                .append("   JOIN unidade AS uni ON usu.uni_codigo = uni.uni_codigo")
                .append("   JOIN microarea AS mic ON usu.usu_microarea = mic.mic_codigo AND mic.ativo IS TRUE")
                .append("   JOIN tb_equipe AS teq ON mic.co_seq_equipe = teq.co_seq_equipe AND teq.uni_codigo = uni.uni_codigo")
                .append("   JOIN usuarios AS usr ON mic.mic_responsavel = usr.usr_codigo")
                .append(" WHERE 1=1 AND usu.usu_mudanca_territorio = 'f'");
        if (filter.getRisco() != null) {
            if (filter.getRisco().equals("N")) {
                sb.append(" AND dom.estrat_risco_familiar IS NULL");
            } else {
                sb.append(" AND dom.estrat_risco_familiar = :riscoFamiliar");
            }
        }
        if (filter.getUnidade() != null) {
            sb.append(" AND uni.uni_codigo = :unidade");
        }
        if (filter.getEquipe() != null) {
            sb.append(" AND teq.nu_ine = :equipe");
        }
        if (filter.getProfissional() != null) {
            sb.append(" AND mic.mic_responsavel = :profissional");
        }
        sb.append(" GROUP BY uni.uni_desc, teq.nu_ine, teq.no_equipe, mic.mic_codigo, usr.usr_nome, estrat_risco_familiar")
                .append(" ORDER BY uni.uni_desc, teq.no_equipe, mic.mic_descricao,")
                .append("   CASE estrat_risco_familiar")
                .append("        WHEN NULL THEN 1")
                .append("        WHEN 'B' THEN 2")
                .append("        WHEN 'M' THEN 3")
                .append("       WHEN 'A' THEN 4")
                .append("    END");

        return sb.toString();
    }

    public static String getSqlEstratificacaoFamiliarAnalitico(EstratificacaoFamiliarFilter filter) {
        sb = new StringBuilder();
        sb.append("SELECT")
                .append(" teq.nu_ine           AS ineEquipe,")
                .append(" teq.no_equipe        AS nomeEquipe,")
                .append(" mic.mic_descricao    AS microArea,")
                .append(" uni.uni_desc         AS unidade,")
                .append(" usr.usr_nome         AS profissional_responsavel,")
                .append(" usu.usu_nome         AS usuario_responsavel,")
                .append(" usu.usu_cartao_sus   AS cns,")
                .append(" log.logra_logradouro AS tipoLog,")
                .append(" rua.rua_nome         AS logradouro,")
                .append(" dom.dom_numero       AS numero,")
                .append(" dom.dom_complemento  AS complemento,")
                .append(" dom.dom_codigo       AS domCodigo,")
                .append(" CASE dom.estrat_risco_familiar")
                .append("   WHEN 'A'")
                .append("     THEN 'Alto'")
                .append("   WHEN 'M'")
                .append("     THEN 'Médio'")
                .append("   WHEN 'B'")
                .append("     THEN 'Baixo'")
                .append("   ELSE 'Não Estratificado'")
                .append("   END               AS estrat_risco_familiar")
                .append(" FROM domicilio AS dom")
                .append("   JOIN usuario AS usu ON dom.usu_codigo_responsavel = usu.usu_codigo")
                .append("   JOIN unidade AS uni ON usu.uni_codigo = uni.uni_codigo")
                .append("   JOIN microarea AS mic ON usu.usu_microarea = mic.mic_codigo AND mic.ativo IS TRUE")
                .append("   JOIN tb_equipe AS teq ON mic.co_seq_equipe = teq.co_seq_equipe AND teq.uni_codigo = uni.uni_codigo")
                .append("   JOIN usuarios AS usr ON mic.mic_responsavel = usr.usr_codigo")
                .append("   JOIN rua as rua ON dom.rua_codigo = rua.rua_codigo")
                .append("   JOIN logradouro as log ON rua.co_tipo_logradouro = log.logra_cod")
                .append(" WHERE 1=1 AND usu.usu_mudanca_territorio = 'f'");
        if (filter.getRisco() != null) {
            if (filter.getRisco().equals("N")) {
                sb.append(" AND dom.estrat_risco_familiar IS NULL");
            } else {
                sb.append(" AND dom.estrat_risco_familiar = :riscoFamiliar");
            }
        }
        if (filter.getUnidade() != null) {
            sb.append(" AND uni.uni_codigo = :unidade");
        }
        if (filter.getEquipe() != null) {
            sb.append(" AND teq.nu_ine = :equipe");
        }
        if (filter.getProfissional() != null) {
            sb.append(" AND mic.mic_responsavel = :profissional");
        }
        sb.append(" ORDER BY uni.uni_desc, teq.no_equipe, mic.mic_descricao,")
                .append("   CASE estrat_risco_familiar")
                .append("        WHEN NULL THEN 1")
                .append("        WHEN 'B' THEN 2")
                .append("        WHEN 'M' THEN 3")
                .append("       WHEN 'A' THEN 4")
                .append("    END,")
                .append(" usu.usu_nome");
        return sb.toString();
    }

    public static String getSqlEstratificacaoCriancaSintetico(EstratificacaoCriancaFilter filter) {
        sb = new StringBuilder();
        sb.append("SELECT")
                .append(" uni.uni_desc      AS unidade,")
                .append(" teq.no_equipe     AS nomeEquipe,")
                .append(" teq.nu_ine        AS ineEquipe,")
                .append(" mic.mic_descricao AS microArea,")
                .append(" usr.usr_nome      AS profissional_responsavel,")
                .append(" extract(YEAR FROM age(usu.usu_datanasc)) AS idade,")
                .append("  CASE extract(YEAR FROM age(usu.usu_datanasc))")
                .append("  WHEN '0' THEN '0 à 1 ano incompleto'")
                .append("  WHEN '1' THEN '1 à 2 anos incompletos'")
                .append("  WHEN '2' THEN '2 à 3 anos incompletos'")
                .append("  WHEN '3' THEN '3 à 4 anos incompletos'")
                .append("  WHEN '4' THEN '4 à 5 anos incompletos'")
                .append("  WHEN '5' THEN '5 à 6 anos incompletos'")
                .append("  WHEN '6' THEN '6 à 7 anos incompletos'")
                .append("  WHEN '7' THEN '7 à 8 anos incompletos'")
                .append("  WHEN '8' THEN '8 à 9 anos incompletos'")
                .append("  WHEN '9' THEN '9 à 10 anos incompletos'")
                .append("  WHEN '10' THEN '10 à 11 anos incompletos'")
                .append("  WHEN '11' THEN '11 à 12 anos incompletos'")
                .append("  END  AS faixaEtaria,")
                .append(" CASE usu.risco_crianca")
                .append("   WHEN 'A'")
                .append("     THEN 'Alto'")
                .append("   WHEN 'M'")
                .append("     THEN 'Intermediário'")
                .append("   WHEN 'B'")
                .append("     THEN 'Habitual'")
                .append("   ELSE 'Não Estratificado'")
                .append("  END               AS risco,")
                .append(" COUNT(usu.usu_codigo) AS qtde")
                .append(" FROM usuario  AS usu")
                .append("   JOIN unidade AS uni ON usu.uni_codigo = uni.uni_codigo")
                .append("   JOIN microarea AS mic ON usu.usu_microarea = mic.mic_codigo AND mic.ativo IS TRUE")
                .append("   JOIN tb_equipe AS teq ON mic.co_seq_equipe = teq.co_seq_equipe AND teq.uni_codigo = uni.uni_codigo")
                .append("   JOIN usuarios AS usr ON mic.mic_responsavel = usr.usr_codigo")
                .append(" WHERE 1=1 AND usu.usu_mudanca_territorio = 'f'");
        if (filter.getRisco() != null) {
            if (filter.getRisco().contains("N")) {
                sb.append(" AND usu.risco_crianca IS NULL");
            } else {
                sb.append(" AND usu.risco_crianca = :riscoCrianca");
            }
        }
        if (filter.getUnidade() != null) {
            sb.append(" AND uni.uni_codigo = :unidade");
        }
        if (filter.getEquipe() != null) {
            sb.append(" AND teq.nu_ine = :equipe");
        }
        if (filter.getProfissional() != null) {
            sb.append(" AND mic.mic_responsavel = :profissional");
        }
        if (filter.getFaixaEtaria() != null) {
            String[] array = StringUtils.split(filter.getFaixaEtaria(), "|");
          if(array.length>0){
            sb.append(" AND (extract(year from age(usu.usu_datanasc)) > 99999 ");
            for (String s : array) {
              switch (s) {
                case "1":
                  sb.append(" OR extract(year from age(usu.usu_datanasc)) = 0");
                  break;
                case "2":
                  sb.append(" OR extract(year from age(usu.usu_datanasc)) = 1");
                  break;
                case "3":
                  sb.append(" OR extract(year from age(usu.usu_datanasc)) = 2");
                  break;
                case "4":
                  sb.append(" OR extract(year from age(usu.usu_datanasc)) = 3");
                  break;
                case "5":
                  sb.append(" OR extract(year from age(usu.usu_datanasc)) = 4");
                  break;
                case "6":
                  sb.append(" OR extract(year from age(usu.usu_datanasc)) = 5");
                  break;
                case "7":
                  sb.append(" OR extract(year from age(usu.usu_datanasc)) = 6");
                  break;
                case "8":
                  sb.append(" OR extract(year from age(usu.usu_datanasc)) = 7");
                  break;
                case "9":
                  sb.append(" OR extract(year from age(usu.usu_datanasc)) = 8");
                  break;
                case "10":
                  sb.append(" OR extract(year from age(usu.usu_datanasc)) = 9");
                  break;
                case "11":
                  sb.append(" OR extract(year from age(usu.usu_datanasc)) = 10");
                  break;
                case "12":
                  sb.append(" OR extract(year from age(usu.usu_datanasc)) = 11");
                  break;
              }
            }
            sb.append(")");
          }
          sb.append(" AND (extract(year from age(usu.usu_datanasc)) <= 11)");
        }else{
            sb.append(" AND (extract(year from age(usu.usu_datanasc)) <= 11)");
        }
        sb.append(" AND usu.usu_datanasc <= current_date");


        sb.append(" GROUP BY uni.uni_desc, teq.nu_ine, teq.no_equipe, mic.mic_codigo, usr.usr_nome, risco_crianca, idade, faixaEtaria")
                .append(" ORDER BY uni.uni_desc, teq.no_equipe, mic.mic_descricao, idade, ")
                .append("   CASE risco_crianca")
                .append("        WHEN NULL THEN 1")
                .append("        WHEN 'B' THEN 2")
                .append("        WHEN 'M' THEN 3")
                .append("       WHEN 'A' THEN 4")
                .append("    END");

        return sb.toString();
    }

    public static String getSqlEstratificacaoCriancaAnalitico(EstratificacaoCriancaFilter filter) {
        sb = new StringBuilder();
        sb.append("SELECT")
                .append(" uni.uni_desc      AS unidade,")
                .append(" teq.no_equipe     AS nomeEquipe,")
                .append(" teq.nu_ine        AS ineEquipe,")
                .append(" mic.mic_descricao AS microArea,")
                .append(" usr.usr_nome      AS profissional_responsavel,")
                .append(" usu.usu_nome      AS nome,")
                .append(" usu.usu_cartao_sus AS cns,")
                .append(" to_char(usu.usu_datanasc, 'DD/MM/YYYY') AS dataNascimento,")
                .append(" extract(YEAR FROM age(usu.usu_datanasc)) AS idade,")
                .append("  CASE extract(YEAR FROM age(usu.usu_datanasc))")
                .append("  WHEN '0' THEN '0 à 1 ano incompleto'")
                .append("  WHEN '1' THEN '1 à 2 anos incompletos'")
                .append("  WHEN '2' THEN '2 à 3 anos incompletos'")
                .append("  WHEN '3' THEN '3 à 4 anos incompletos'")
                .append("  WHEN '4' THEN '4 à 5 anos incompletos'")
                .append("  WHEN '5' THEN '5 à 6 anos incompletos'")
                .append("  WHEN '6' THEN '6 à 7 anos incompletos'")
                .append("  WHEN '7' THEN '7 à 8 anos incompletos'")
                .append("  WHEN '8' THEN '8 à 9 anos incompletos'")
                .append("  WHEN '9' THEN '9 à 10 anos incompletos'")
                .append("  WHEN '10' THEN '10 à 11 anos incompletos'")
                .append("  WHEN '11' THEN '11 à 12 anos incompletos'")
                .append("  END  AS faixaEtaria,")
                .append(" CASE usu.risco_crianca")
                .append("   WHEN 'A'")
                .append("     THEN 'Alto'")
                .append("   WHEN 'M'")
                .append("     THEN 'Intermediário'")
                .append("   WHEN 'B'")
                .append("     THEN 'Habitual'")
                .append("   ELSE 'Não Estratificado'")
                .append("  END               AS risco")
                .append(" FROM usuario  AS usu")
                .append("   JOIN unidade AS uni ON usu.uni_codigo = uni.uni_codigo")
                .append("   JOIN microarea AS mic ON usu.usu_microarea = mic.mic_codigo AND mic.ativo IS TRUE")
                .append("   JOIN tb_equipe AS teq ON mic.co_seq_equipe = teq.co_seq_equipe AND teq.uni_codigo = uni.uni_codigo")
                .append("   JOIN usuarios AS usr ON mic.mic_responsavel = usr.usr_codigo")
                .append(" WHERE 1=1 AND usu.usu_mudanca_territorio = 'f'");
        if (filter.getRisco() != null) {
            if (filter.getRisco().contains("N")) {
                sb.append(" AND usu.risco_crianca IS NULL");
            } else {
                sb.append(" AND usu.risco_crianca = :riscoCrianca");
            }
        }
        if (filter.getUnidade() != null) {
            sb.append(" AND uni.uni_codigo = :unidade");
        }
        if (filter.getEquipe() != null) {
            sb.append(" AND teq.nu_ine = :equipe");
        }
        if (filter.getProfissional() != null) {
            sb.append(" AND mic.mic_responsavel = :profissional");
        }
        if (filter.getFaixaEtaria() != null) {
            String[] array = StringUtils.split(filter.getFaixaEtaria(), "|");
          if(array.length>0){
            sb.append(" AND (extract(year from age(usu.usu_datanasc)) > 99999 ");
            for (String s : array) {
                switch (s) {
                    case "1":
                        sb.append(" OR extract(year from age(usu.usu_datanasc)) < 1");
                        break;
                    case "2":
                        sb.append(" OR extract(year from age(usu.usu_datanasc)) = 1");
                        break;
                    case "3":
                        sb.append(" OR extract(year from age(usu.usu_datanasc)) = 2");
                        break;
                    case "4":
                        sb.append(" OR extract(year from age(usu.usu_datanasc)) = 3");
                        break;
                    case "5":
                        sb.append(" OR extract(year from age(usu.usu_datanasc)) = 4");
                        break;
                    case "6":
                        sb.append(" OR extract(year from age(usu.usu_datanasc)) = 5");
                        break;
                    case "7":
                        sb.append(" OR extract(year from age(usu.usu_datanasc)) = 6");
                        break;
                    case "8":
                        sb.append(" OR extract(year from age(usu.usu_datanasc)) = 7");
                        break;
                    case "9":
                        sb.append(" OR extract(year from age(usu.usu_datanasc)) = 8");
                        break;
                    case "10":
                        sb.append(" OR extract(year from age(usu.usu_datanasc)) = 9");
                        break;
                    case "11":
                        sb.append(" OR extract(year from age(usu.usu_datanasc)) = 10");
                        break;
                    case "12":
                        sb.append(" OR extract(year from age(usu.usu_datanasc)) = 11");
                        break;
                }
            }
            sb.append(")");
        }
            sb.append(" AND (extract(year from age(usu.usu_datanasc)) <= 11)");
        }else{
            sb.append(" AND (extract(year from age(usu.usu_datanasc)) <= 11)");
        }

        sb.append(" AND usu.usu_datanasc <= current_date")
          .append(" ORDER BY uni.uni_desc, teq.no_equipe, mic.mic_descricao,")
          .append("   CASE risco_crianca")
          .append("        WHEN NULL THEN 1")
          .append("        WHEN 'B' THEN 2")
          .append("        WHEN 'M' THEN 3")
          .append("       WHEN 'A' THEN 4")
          .append("    END, ")
          .append(" idade, nome");

        return sb.toString();


    }
}
