class AgendamentoManager {
constructor() {
this.config = {
isProd: !window.location.pathname.includes("agendamento-h"),
fields: {
all: [
"#email",
"#matricula",
"#nome",
"#cpf",
"#telefone",
".documentos",
],
required: ["#email", "#matricula", "#nome", "#cpf", "#telefone"],
},
serviceIds: {
prod: {
"Revisão de consumo": 36,
"Alteração de titularidade": 35,
Parcelamento: 37,
},
dev: {
"Revisão de consumo": 9,
"Alteração de titularidade": 10,
Parcelamento: 8,
},
},
};
this.state = {
updateEmail: false,
selectedScheduleTime: null,
selectedCalendarTime: null,
selectedDay: null,
selectedMonth: null,
selectedYear: null,
userId: null,
isNewUser: false,
isUpdatingData: false,
userWithoutEmail: false,
userData: null,
updateButton: false,
serviceError: false,
scheduledDates: null,
scheduleId: 1,
};
this.initializeApp();
}
initializeApp() {
this.setupMasks();
this.setupEventListeners();
}
setupMasks() {
this.applyMask(document.querySelector("#telefone"), "(99) 99999-9999");
this.applyMask(document.querySelector("#cpf"), "999.999.999-99");
}
applyMask(element, mask) {
if (!element) return;
element.addEventListener("input", (e) => {
let value = e.target.value.replace(/\D/g, "");
let maskedValue = "";
let valueIndex = 0;
for (let i = 0; i < mask.length && valueIndex < value.length; i++) {
if (mask[i] === "9") {
maskedValue += value[valueIndex];
valueIndex++;
} else {
maskedValue += mask[i];
}
}
e.target.value = maskedValue;
});
}
setupEventListeners() {
const formFields = [
"#email",
"#nome",
"#cpf",
"#telefone",
"#matricula",
"#servico",
];
formFields.forEach((field) => {
const element = document.querySelector(field);
if (element) {
element.addEventListener("change", () => {
this.validateFormFields();
});
}
});
const emailField = document.querySelector("#email");
if (emailField) {
emailField.addEventListener("change", async () => {
await this.handleEmailChange();
});
}
const emailConfField = document.querySelector("#emailConf");
if (emailConfField) {
emailConfField.addEventListener("change", () => {
if (document.querySelector("#email").value !== "") {
document.querySelector("#btn-continuar").style.display = "block";
}
});
}
const serviceField = document.querySelector("#servico");
if (serviceField) {
serviceField.options[0].disabled = true;
serviceField.addEventListener("change", (e) => {
this.handleServiceChange(e.target.value);
});
}
const correctDataBtn = document.querySelector("#btn-corrigeDados");
if (correctDataBtn) {
correctDataBtn.addEventListener("click", async () => {
await this.handleCorrectData();
});
}
const continueBtn = document.querySelector("#btn-continuar");
if (continueBtn) {
continueBtn.addEventListener("click", async () => {
this.state.isUpdatingData = false;
await this.handleContinue();
this.checkScheduledServices(this.state.userId);
});
}
const cpfField = document.querySelector("#cpf");
if (cpfField) {
cpfField.addEventListener("blur", async (e) => {
await this.validateCPF(e.target);
});
}
const phoneField = document.querySelector("#telefone");
if (phoneField) {
phoneField.addEventListener("blur", (e) => {
this.validatePhone(e.target);
});
}
}
validateFormFields() {
const email = document.querySelector("#email").value;
const nome = document.querySelector("#nome").value;
const cpf = document.querySelector("#cpf").value;
const telefone = document.querySelector("#telefone").value;
const matricula = document.querySelector("#matricula").value;
const allFieldsFilled = email && nome && cpf && telefone && matricula;
const canShowButton =
allFieldsFilled &&
!this.state.updateEmail &&
!this.state.userWithoutEmail &&
!this.state.serviceError;
document.querySelector("#btn-continuar").style.display = canShowButton
? "block"
: "none";
}
async checkScheduledServices(userId) {
if (!userId) return;
try {
const response = await fetch(`/agendamentos-pessoa?id=${userId}`);
const appointments = await response.json();
if (!appointments.length) return;
this.scheduledDates = appointments;
const agora = new Date();
const offset = -3;
const dataGTM3 = new Date(agora.getTime() + offset * 60 * 60 * 1000);
const dataAtualISO = dataGTM3.toISOString().replace("Z", "-03:00");
const selectedService = document.querySelector("#servico").value;
const existingAppointment = appointments.find(
(item) =>
item.tituloAgendamento.toLowerCase() ===
selectedService.toLowerCase() && item.dataFimEvento >= dataAtualISO,
);
if (existingAppointment) {
this.state.serviceError = true;
this.showAlert(
"Já existe um agendamento ativo para o serviço e CPF informado",
);
document.querySelector("#btn-continuar").style.display = "none";
this.resetCPFRules();
return;
} else {
this.state.serviceError = false;
document.querySelector("#btn-continuar").style.display = "block";
}
} catch (error) {
console.error("Erro ao verificar serviços agendados:", error);
}
}
async handleEmailChange() {
const email = this.validateAndClearEmail("email");
if (email === null || email === "") {
this.showAlert("Digite um email!");
return;
}
if (
document.querySelector("#email").value === "" ||
this.state.updateButton
) {
try {
const response = await fetch("/api/v1/get-usuario", {
method: "POST",
headers: {
"Content-Type": "application/json",
prod: Boolean(this.config.isProd),
},
body: JSON.stringify({ email }),
});
if (response.ok) {
const data = await response.json();
if (Object.keys(data).length > 0) {
document.querySelector("#email").value = "";
this.showAlert(
"E-mail já cadastrado para outro usuário, favor insira um e-mail diferente.",
);
document.querySelector("#btn-continuar").style.display = "none";
} else {
if (this.state.userWithoutEmail) {
document.querySelector("#btn-continuar").style.display = "none";
} else {
document.querySelector("#btn-continuar").style.display = "block";
}
}
}
} catch (error) {
console.error("Erro ao verificar email:", error);
}
}
if (document.querySelector("#emailConf").value !== "") {
document.querySelector("#btn-continuar").style.display = "block";
}
}
async handleCorrectData() {
this.state.updateEmail = true;
if (!this.state.userWithoutEmail) {
document.querySelector("#email").value = "";
}
this.state.isUpdatingData = true;
this.state.updateButton = true;
document.querySelector("#btn-corrigeDados").style.display = "none";
document.querySelector("#btn-continuar").style.display = "none";
document.querySelector("#emailConfirm").classList.remove("hide");
document.querySelector("#email").removeAttribute("readonly");
document.querySelector("#email").style.backgroundColor = "#fff";
}
async handleContinue() {
const emptyFields = this.config.fields.required.filter(
(field) => document.querySelector(field).value === "",
);
if (emptyFields.length > 0) {
const fieldLabel = document
.querySelector(emptyFields[0])
.parentElement.querySelector("label")
.textContent.split(":")[0];
this.showAlert(`Preencha o campo: ${fieldLabel}`);
return;
}
const phoneData = this.buildPhoneData();
if (!this.state.isUpdatingData && !this.state.isNewUser) {
await this.updateContact(phoneData);
this.showSuccessModal();
}
if (this.state.isUpdatingData || this.state.updateEmail) {
await this.handleDataUpdate(phoneData);
}
if (this.state.isNewUser) {
await this.handleNewUserRegistration();
}
}
buildPhoneData() {
const phoneValue = document.querySelector("#telefone").value;
return {
idUsuario: this.state.userId,
telefone: [
{
tipo: "CELULAR",
ddd: phoneValue.substring(1, 3),
numero: phoneValue.substring(5).replace(/\D/g, ""),
sms: true,
preferencial: false,
},
],
};
}
async updateContact(phoneData) {
try {
const response = await fetch("/api/v1/atualiza-contato", {
method: "POST",
headers: {
"Content-Type": "application/json",
prod: Boolean(this.config.isProd),
},
body: JSON.stringify({ dadosPessoaCadastro: phoneData }),
});
if (response.ok) {
let data = await response.json();
this.state.userId = data.id;
}
} catch (error) {
console.error("Erro ao atualizar contato:", error);
}
}
async handleDataUpdate(phoneData) {
const newEmailConfirmation = document
.querySelector("#emailConf")
.value.trim();
const typedEmail = document.querySelector("#email").value.trim();
if (!newEmailConfirmation || !typedEmail) {
this.showAlert("Preencha os dois campos de email para prosseguir!");
return;
}
if (typedEmail !== newEmailConfirmation) {
this.showAlert("Os e-mails não são iguais. Favor informar novamente.");
return;
}
const updateData = {
...phoneData,
cpf: document.querySelector("#cpf").value,
nome: document.querySelector("#nome").value,
email: newEmailConfirmation,
method: "PUT",
};
try {
const response = await fetch("/api/v1/cadastro-usuario", {
method: "POST",
headers: {
"Content-Type": "application/json",
prod: Boolean(this.config.isProd),
},
body: JSON.stringify({ dadosPessoaCadastro: updateData }),
});
if (response.ok) {
this.state.userId = updateData.idUsuario;
this.showSuccessModal();
}
} catch (error) {
console.error("Erro ao atualizar dados:", error);
}
}
async handleNewUserRegistration() {
const newEmailConfirmation = document
.querySelector("#emailConf")
.value.trim();
const typedEmail = document.querySelector("#email").value.trim();
if (newEmailConfirmation !== typedEmail) {
this.showAlert("Os e-mails não são iguais. Favor informar novamente.");
return;
}
const newUserData = {
cpf: document.querySelector("#cpf").value,
nome: document.querySelector("#nome").value,
email: document.querySelector("#email").value,
telefone: document.querySelector("#telefone").value,
method: "POST",
};
try {
const response = await fetch("/api/v1/cadastro-usuario", {
method: "POST",
headers: {
"Content-Type": "application/json",
prod: Boolean(this.config.isProd),
},
body: JSON.stringify({ dadosPessoaCadastro: newUserData }),
});
if (response.ok) {
this.state.userId = await response.json();
this.showSuccessModal();
}
} catch (error) {
console.error("Erro ao cadastrar usuário:", error);
}
}
showFields() {
this.config.fields.all.forEach((field) => {
const element = document.querySelector(field);
if (element) {
element.classList.remove("hide");
element.parentElement?.classList.remove("hide");
element.parentElement?.parentElement?.classList.remove("hide");
}
});
}
hideFields() {
this.config.fields.all.forEach((field) => {
const element = document.querySelector(field);
if (element) {
element.classList.add("hide");
element.parentElement?.classList.add("hide");
element.parentElement?.parentElement?.classList.add("hide");
}
});
const servicoElement = document.querySelector("#servico");
if (servicoElement) {
servicoElement.parentElement.parentElement.parentElement.classList.remove(
"hide",
);
servicoElement.parentElement.parentElement.classList.remove("hide");
}
}
handleServiceChange(serviceValue) {
if (!serviceValue) return;
this.config.fields.all.forEach((field) => {
const element = document.querySelector(field);
if (element) {
element.value = "";
}
});
this.hideFields();
document.querySelector("#btn-corrigeDados").style.display = "none";
this.showFields();
this.setDocumentationLinks(serviceValue);
const cpfInput = document.querySelector("input#cpf");
if (typeof this.state.userId === "object") {
if (this.state.userId == null) return;
if (!this.state.userId.id) return;
this.state.userId = this.state.userId.id;
}
cpfInput.value ? this.checkScheduledServices(this.state.userId) : null;
}
setDocumentationLinks(service) {
const links = {
"Revisão de consumo":
"https://atendimentovirtual.embasa.ba.gov.br/carta-verificar-consumo",
Parcelamento:
"https://atendimentovirtual.embasa.ba.gov.br/carta-simular-parcelamento",
"Alteração de titularidade":
"https://atendimentovirtual.embasa.ba.gov.br/carta-de-servico-alteracao-de-titularidade",
};
const anchor = document.querySelector("#documentos-button-anchor");
if (anchor && links[service]) {
anchor.href = links[service];
}
}
showSchedulingModal() {
setTimeout(() => {
this.setupDateChangeHandler();
this.setupDateBlurHandler();
}, 2000);
const phone = document.querySelector("#telefone").value
? document.querySelector("#telefone").value
: "";
Swal.fire({
title: "Conclua o seu agendamento:",
html: this.getSchedulingModalHTML(),
confirmButtonColor: "rgb(14, 67, 241)",
showCancelButton: true,
confirmButtonText:
'',
cancelButtonText: "Cancelar",
}).then((result) => {
if (result.isConfirmed) {
this.showConfirmationModal();
setTimeout(() => {
this.makeAppointment(
this.state.selectedDay,
this.state.selectedMonth,
this.state.selectedYear,
this.state.selectedScheduleTime,
phone,
);
//window.location.reload();
}, 5000);
}
});
this.setMinMaxDates();
this.setupTimeCheckHandler();
const confirmBtns = document.querySelectorAll(".swal2-confirm");
confirmBtns.forEach((btn) => (btn.style.display = "none"));
}
getSchedulingModalHTML() {
return `

Em breve você receberá um e-mail de confirmação.
O link e a senha de acesso serão enviados 15 minutos antes do horário, ou se preferir,
acesse diretamente essas informações na opção: Consultar Agendamento.
