const fs = require('fs');
const path = require('path');
const mysql = require('mysql2');
const axios = require('axios');
const https = require('https');
const dotenv = require('dotenv');
const envData = fs.readFileSync('conecta.env', 'utf8');
const envVariables = dotenv.parse(envData);
dotenv.config();

const certFilePath = path.join(__dirname, 'certificado.pem');
const keyFilePath = path.join(__dirname, 'chave.pem');
const passphrase = 'LCMag1302';
const tokenFilePath = path.join(__dirname, 'token.txt');

let quantidadeEnviada = 0;
let quantidadeErro = 0;
const {
  DB_MYSQL_SERVER,
  DB_MYSQL_USERNAME,
  DB_MYSQL_PASSWORD,
  DB_MYSQL_NAME,
} = envVariables;

function getToken() {
  try {
    const data = fs.readFileSync(tokenFilePath, 'utf8');
    const match = data.match(/TOKEN:\s*(.+)/);
    if (match && match[1]) {
      return match[1].trim();
    } else {
      throw new Error('Token não encontrado no arquivo.');
    }
  } catch (err) {
    console.error('Erro ao ler o token:', err.message);
    return null;
  }
}

const connection = mysql.createConnection({
  host: DB_MYSQL_SERVER,
  user: DB_MYSQL_USERNAME,
  password: DB_MYSQL_PASSWORD,
  database: DB_MYSQL_NAME,
});

function fetchData() {
  return new Promise((resolve, reject) => {
    const query = `SELECT  
  t4.identifier_enviornds_pendente AS identifier_local,
  t4.id_retornornds_pendente,
  t4.numero_procotolo,
  t1.id_agendamento,
  t1.id_solicitacao,
  t2.cns_paciente,
  t2.cpf_paciente,
  CONCAT(
    DATE_FORMAT(t1.datahora_agendamento,'%Y-%m-%dT%H:%i:%s'), 
    '-03:00'
  ) AS created_data_registro,
  CASE 
    WHEN (t1.data_atendimento='' OR t1.data_atendimento IS NULL)
    THEN CONCAT(DATE_FORMAT(DATE_ADD(datahora_agendamento, INTERVAL 1 DAY), '%Y-%m-%dT%H:%i'), ':00-03:00')
    ELSE CONCAT(DATE_FORMAT(CONCAT(t1.data_atendimento,' ',t1.horario_atendimento), '%Y-%m-%dT%H:%i'), ':00-03:00')
    END
   AS start_data_atendimento,  
  CASE 
    WHEN (t1.data_atendimento='' OR t1.data_atendimento IS NULL)
    THEN CONCAT(DATE_FORMAT(DATE_ADD(DATE_ADD(datahora_agendamento, INTERVAL 1 DAY),INTERVAL 30 MINUTE), '%Y-%m-%dT%H:%i'), ':00-03:00')
    ELSE CONCAT(DATE_FORMAT(CONCAT(t1.data_atendimento,' ',t1.horario_atendimento), '%Y-%m-%dT%H:%i'), ':00-03:00')
    END
  AS and_data_atendimento,
  CONCAT(DATE_FORMAT(t4.datahora_cadastro, '%Y-%m-%dT%H:%i:%s'), '-03:00') authoredon_data_solicitacao,
  "routine" AS id_rnds_prioridade,
  t7.codigo_cbo,
  t8.cnes_estabelecimento,
  CASE
    WHEN (t4.cid_solicitacao IS NULL OR t4.cid_solicitacao = '' OR t4.cid_solicitacao = 'R09') THEN 'R69'
    WHEN (t4.cid_solicitacao IS NULL OR t4.cid_solicitacao = '' OR t4.cid_solicitacao = 'R069') THEN 'R69'
    WHEN (t4.cid_solicitacao = 'ZOO') THEN 'Z00'
    WHEN (t4.cid_solicitacao != 'ZOO' AND t4.cid_solicitacao != 'R09' AND t4.cid_solicitacao IS NOT NULL AND t4.cid_solicitacao != '') THEN t4.cid_solicitacao
    END AS CID,
  IFNULL(
    CASE 
      WHEN REPLACE(t1.observacao_agendamento, '<br>', '') = '' THEN 'Sem observações'
      ELSE t1.observacao_agendamento
    END, 
    'Sem observações'
  ) AS observacao_agendamento,
  t3.codigo_sus, 
  CASE
    WHEN t1.status_agendamento = 'A' THEN 'AGENDADO'
    WHEN t1.status_agendamento = 'E' THEN 'AGENDADO'
    WHEN t1.status_agendamento = 'R' THEN 'AGENDADO'
  END AS status_agendamento,
  RIGHT(t4.id_unidade_cadastrou,7) AS cnes_unidadesolicitante,
  UCASE(t4.observacoes_solicitacao) AS observacaoAgendamento
  FROM reg_tb_agendamentos t1
  LEFT JOIN tb_paciente t2 ON t2.id_paciente = t1.id_paciente 
  LEFT JOIN reg_tb_procedimento t3 ON t3.id_procedimento = t1.id_procedimento 
  LEFT JOIN reg_tb_solicitacoes t4 ON t4.id_solicitacao = t1.id_solicitacao 
  LEFT JOIN reg_tb_agenda t6 ON t6.id_agenda = t1.id_agenda 
  LEFT JOIN tb_profissional_vinculo t7 ON t7.codigoprofissional_cnes = t6.codigoprofissional_cnes
  LEFT JOIN tb_estabelecimento t8 ON t8.codigoestabelecimento_cnes = t6.codigoestabelecimento_cnes 
  WHERE (t4.enviado_rnds_pendente='S' AND t4.enviado_rnds_cancelado='N')
  AND (t4.id_grupo_procedimento!=14)
  AND (t1.enviado_rnds_agendado='N' OR t1.enviado_rnds_agendado IS NULL)
  AND (t1.status_agendamento='A' OR t1.status_agendamento='E' OR t1.status_agendamento='R')
  LIMIT 100;`;
    /*AND (t1.status_agendamento = 'A' OR t1.status_agendamento = 'E')
    AND (t1.enviado_rnds_agendado = 'N' OR t1.enviado_rnds_agendado IS NULL)
    AND (t1.id_solicitacao IS NOT NULL)
    AND (t9.cns_profissional != '00000000001')
    AND (t9.cns_profissional != '00000000002')
    AND (t9.cns_profissional != '00000000003')
    AND (t7.status_vinculos_profissional = 'A')
    AND (t1.id_procedimento != '350')*/
    connection.query(query, (error, results) => {
      if (error) {
        reject(error);
      } else {
        resolve(results);
      }
    });
  });
}

// BUNDLE
function buildBundle(item) {
  return {
    "resourceType": "Bundle",
    "identifier": {
      "system": "http://www.saude.gov.br/fhir/r4/NamingSystem/BRRNDS-41484",
      "value": String(item.identifier_local)
    },
    "meta": {
      "lastUpdated": new Date().toISOString()
    },
    "type": "document",
    "timestamp": new Date().toISOString(),
    "entry": [
      {
        "fullUrl": "urn:uuid:transient-0",
        "resource": {
          "resourceType": "Composition",
          "status": "final",
          "relatesTo": [
            {
              "code": "replaces",
              "targetReference": {
                "reference": "Composition/" + String(item.id_retornornds_pendente)
              }
            }
          ],
          "title": "Registro de Informações da Regulação Assistencial",
          "meta": {
            "lastUpdated": new Date().toISOString(),
            "profile": [
              "http://www.saude.gov.br/fhir/r4/StructureDefinition/BRRegulacaoAssistencial"
            ]
          },
          "date": new Date().toISOString(),
          "type": {
            "coding": [
              {
                "system": "http://www.saude.gov.br/fhir/r4/CodeSystem/BRTipoDocumento",
                "code": "RA"
              }
            ]
          },
          "category": [
            {
              "coding": [
                {
                  "system": "http://www.saude.gov.br/fhir/r4/CodeSystem/BRModalidadeAssistencial",
                  "code": "09"
                }
              ]
            }
          ],
          "subject": {
            "identifier": {
              "system": "http://www.saude.gov.br/fhir/r4/StructureDefinition/BRIndividuo-1.0",
              "value": String(item.cpf_paciente || item.cns_paciente)
            }
          },
          "author": [
            {
              "identifier": {
                "system": "http://www.saude.gov.br/fhir/r4/StructureDefinition/BREstabelecimentoSaude-1.0",
                "value": String(item.cnes_estabelecimento || '6479286')
              }
            }
          ],
          "event": [
            {
              "code": [
                {
                  "coding": [
                    {
                      "system": "http://www.saude.gov.br/fhir/r4/CodeSystem/BRStatusRegulacaoAssistencial",
                      "code": "booked"
                    }
                  ]
                }
              ],
              "period": {
                "start": String(item.data_registro_criado),
                "end": String(item.data_registro_fim)
              },
              "detail": [
                {
                  "identifier": {
                    "system": "http://www.saude.gov.br/fhir/r4/StructureDefinition/BREstabelecimentoSaude-1.0",
                    "value": String(item.cnes_estabelecimento || '6479286')
                  }
                },
                {
                  "reference": "urn:uuid:transient-1"
                }
              ]
            }
          ],
          "section": [
            {
              "entry": [
                {
                  "reference": "urn:uuid:transient-1"
                }
              ]
            }
          ]
        }
      },
      {
        "fullUrl": "urn:uuid:transient-1",
        "resource": {
          "resourceType": "Appointment",
          "meta": {
            "lastUpdated": new Date().toISOString(),
            "profile": [
              "http://www.saude.gov.br/fhir/r4/StructureDefinition/BRAgendamentoRegulacaoAssistencial"
            ]
          },
          "status": "booked",
          "serviceCategory": [
            {
              "coding": [
                {
                  "system": "http://www.saude.gov.br/fhir/r4/CodeSystem/BRModalidadeAssistencial",
                  "code": "09"
                }
              ]
            }
          ],
          "serviceType": [
            {
              "coding": [
                {
                  "system": "http://www.saude.gov.br/fhir/r4/CodeSystem/BRTabelaSUS",
                  "code": String(item.codigo_sus)
                }
              ]
            }
          ],
          "specialty": [
            {
              "coding": [
                {
                  "system": "http://www.saude.gov.br/fhir/r4/CodeSystem/BRCBO",
                  "code": String(item.codigo_cbo || '225125')
                }
              ]
            }
          ],
          "appointmentType": {
            "coding": [
              {
                "system": "http://hl7.org/fhir/request-priority",
                "code": String(item.id_rnds_prioridade)
              }
            ]
          },
          "reasonReference": [
            {
              "reference": "urn:uuid:transient-3"
            }
          ],
          "start": String(item.start_data_atendimento),
          "end": String(item.and_data_atendimento),
          "created": String(item.created_data_registro),
          "basedOn": [
            {
              "reference": "urn:uuid:transient-2"
            }
          ],
          "participant": [
            {
              "type": [
                {
                  "coding": [
                    {
                      "system": "http://www.saude.gov.br/fhir/r4/CodeSystem/BRTipoParticipante",
                      "code": "PCT"
                    }
                  ]
                }
              ],
              "actor": {
                "identifier": {
                  "system": "http://www.saude.gov.br/fhir/r4/StructureDefinition/BRIndividuo-1.0",
                  "value": String(item.cpf_paciente || item.cns_paciente)
                }
              },
              "status": "accepted"
            }
          ]
        }
      },
      {
        "fullUrl": "urn:uuid:transient-2",
        "resource": {
          "resourceType": "ServiceRequest",
          "status": "active",
          "meta": {
            "lastUpdated": new Date().toISOString(),
            "profile": [
              "http://www.saude.gov.br/fhir/r4/StructureDefinition/BRRequisicaoRegulacaoAssistencial"
            ]
          },
          "intent": "order",
          "category": [
            {
              "coding": [
                {
                  "system": "http://www.saude.gov.br/fhir/r4/CodeSystem/BRModalidadeAssistencial",
                  "code": "09"
                }
              ]
            }
          ],
          "priority": String(item.id_rnds_prioridade),
          "code": {
            "coding": [
              {
                "system": "http://www.saude.gov.br/fhir/r4/CodeSystem/BRTabelaSUS",
                "code": String(item.codigo_sus)
              }
            ]
          },
          "subject": {
            "identifier": {
              "system": "http://www.saude.gov.br/fhir/r4/StructureDefinition/BRIndividuo-1.0",
              "value": String(item.cpf_paciente || item.cns_paciente)
            }
          },
          "authoredOn": String(item.authoredon_data_solicitacao),
          "requester": {
            "identifier": {
              "system": "http://www.saude.gov.br/fhir/r4/StructureDefinition/BREstabelecimentoSaude-1.0",
              "value": String(item.codigoestabelecimento_cnes || '6479286')
            }
          },
          "performerType": {
            "coding": [
              {
                "system": "http://www.saude.gov.br/fhir/r4/CodeSystem/BRCBO",
                "code": String(item.codigo_cbo || '225120')
              }
            ]
          },
          "reasonReference": [
            {
              "reference": "urn:uuid:transient-3"
            }
          ]
        }
      },
      {
        "fullUrl": "urn:uuid:transient-3",
        "resource": {
          "resourceType": "Condition",
          "meta": {
            "lastUpdated": new Date().toISOString(),
            "profile": [
              "http://www.saude.gov.br/fhir/r4/StructureDefinition/BRCID10Avaliado-1.0"
            ]
          },
          "code": {
            "coding": [
              {
                "system": "http://www.saude.gov.br/fhir/r4/CodeSystem/BRCID10",
                "code": String(item.CID)
              }
            ]
          },
          "subject": {
            "identifier": {
              "system": "http://www.saude.gov.br/fhir/r4/StructureDefinition/BRIndividuo-1.0",
              "value": String(item.cpf_paciente || item.cns_paciente)
            }
          },
          "note": [
            {
              "text": String(item.observacoes_solicitacao)
            }
          ]
        }
      }
    ]
  }
};
async function sendBundle(item) {
  const token = getToken();
  if (!token) {
    console.error('Token não disponível. Não é possível enviar o bundle.');
    return;
  }

  try {
    const httpsAgent = new https.Agent({
      cert: fs.readFileSync(certFilePath),
      key: fs.readFileSync(keyFilePath),
      passphrase: passphrase,
      rejectUnauthorized: true
    });

    const response = await axios.post(
      'https://ba-ehr-services.saude.gov.br/api/fhir/r4/Bundle',
      buildBundle(item),
      {
        headers: {
          'Content-Type': 'application/json',
          'X-Authorization-Server': `Bearer ${token}`,
          'Authorization': "700506440995960"
        },
        httpsAgent: httpsAgent
      }
    );
    console.log('SUCESSO:', response.data);
    quantidadeEnviada++;


    const locationHeader = response.headers.location || null;
    let extractedLocation = null;
    if (locationHeader) {
      extractedLocation = locationHeader.replace('https://ba-ehr-services.saude.gov.br/1.15/api/fhir/r4/Bundle/', '');
    }

    connection.query(
      `UPDATE reg_tb_agendamentos SET enviado_rnds_agendado='S', id_retornornds_agendado=? WHERE id_agendamento=?`,
      [extractedLocation, item.id_agendamento],
      (error) => {
        if (error) {
          console.error('Erro ao atualizar enviado_rnds_cancelado:', error.message);
        }
      }
    );

    const queryInsertSuccess = `
            INSERT INTO reg_tb_enviornds (json_retornosucesso, tipo_envio, protocolo_envio)
            VALUES (?, 'AGENDADO', ?)
        `;

    connection.query(queryInsertSuccess, [extractedLocation, item.numero_procotolo + ' | ' + item.identifier_local], (error) => {
      if (error) {
        console.error('Erro ao inserir no reg_tb_enviornds (sucesso):', error.message);
      } else {
        console.log('Resposta de sucesso salva no banco.');
      }
    });
  } catch (error) {
    if (error.response) {
      const diagnosticsData = (error.response.data.issue && error.response.data.issue.length > 0)
        ? error.response.data.issue[0].diagnostics
        : null;

      let extractedDiagnostics = null;
      if (diagnosticsData) {
        extractedDiagnostics = diagnosticsData;
      }

      if (diagnosticsData && diagnosticsData.includes('EDS-MSG010')) {
        console.log('Identifier duplicado:', diagnosticsData);
        quantidadeEnviada++;

        connection.query(
          `UPDATE reg_tb_agendamentos SET enviado_rnds_agendado='S', id_retornornds_agendado=? WHERE id_agendamento=?`,
          [extractedLocation, item.id_agendamento],
          (error) => {
            if (error) {
              console.error('Erro ao atualizar enviado_rnds_cancelado:', error.message);
            }
          }
        );

        const queryInsertSuccess = `
        INSERT INTO reg_tb_enviornds (json_retornosucesso, tipo_envio, protocolo_envio)VALUES(?, 'AGENDADO', ?)`;
        connection.query(queryInsertSuccess, [extractedDiagnostics, item.numero_procotolo + ' | ' + item.identifier_local], (error) => {
          if (error) {
            console.error('Erro ao inserir no reg_tb_enviornds (sucesso):', error.message);
          } else {
            console.log('Resposta de sucesso salva no banco.');
          }
        });

      } else {
        quantidadeErro++;
        console.error('Request failed:', error.response.status);
        console.error('Response:', error.response.data);

        connection.query(
          `UPDATE reg_tb_agendamentos SET enviado_rnds_agendado = 'N' WHERE id_solicitacao = ?`,
          [item.id_solicitacao],
          (error) => {
            if (error) {
              console.error('Erro ao atualizar enviado_rnds_agendado:', error.message);
            }
          }
        );

        const queryInsertError = `INSERT INTO reg_tb_enviornds (json_retornoerro, tipo_envio, protocolo_envio)VALUES (?, 'AGENDADO', ?)`;
        connection.query(queryInsertError, [extractedDiagnostics, item.numero_procotolo + ' | ' + item.identifier_local], (dbError) => {
          if (dbError) {
            console.error('Erro ao inserir no reg_tb_enviornds (erro):', dbError.message);
          } else {
            console.log('Resposta de erro salva no banco.');
          }
        });
      }

    } else {
      console.error('Request failed:', error.message);
    }
  }
}

async function process() {

  try {
    const data = await fetchData();
    for (const item of data) {
      await sendBundle(item);
    }

    const queryInsert = `INSERT INTO reg_tb_enviado_rnds (tipo_envio, data_envio, quantidade_enviada, quantidade_erro)VALUES('AGENDADO', NOW(), ?, ?)`;
    connection.query(queryInsert, [quantidadeEnviada, quantidadeErro], (error) => {
      if (error) {
        console.error('Erro ao inserir na tabela reg_tb_enviado_rnds:', error.message);
      } else {
        console.log('Consolidação de envios inserida com sucesso.');
      }
    });

  } catch (err) {
    console.error('Erro ao processar dados:', err.message);
  } finally {
    connection.end();
  }
}

process();
