// Funktion, die die aktive Seite anzeigt und alle anderen ausblendet
// (void = kein Rückgabetyp)
function showPage(pageId: string): void {
  // Alle Seiten ausblenden: wählt alle DOM-Elemente aus, die die CSS-Klasse .page haben
  const pages: NodeListOf<HTMLDivElement> = document.querySelectorAll('.page');
  // Schleife, die über jedes Element in der page-Liste iteriert für jedes der gefundenen Seiten-Elemente wird die CSS-Klasse 'active' entfernt.
  // Dies sorgt dafür, dass alle Seiten zunächst "unsichtbar" oder inaktiv sind, da nur die Seite mit der Klasse 'active' sichtbar ist.
  pages.forEach((page: HTMLDivElement) => {
    page.classList.remove('active');
  });


  // Die ausgewählte Seite anzeigen
  //Diese Methode sucht nach einem DOM-Element mit der ID, die in pageId übergeben wurde. pageId ist eine Zeichenkette, die die ID des Elements
  // darstellt, das angezeigt werden soll.HTMLElement | null: Der Rückgabewert von getElementById ist entweder ein HTMLElement
  // (wenn das Element gefunden wurde) oder null (wenn kein Element mit dieser ID existiert).
  const activePage: HTMLElement | null = document.getElementById(pageId);
  if (activePage) {
    activePage.classList.add('active');
  } else {
    console.error(`Seite mit der ID "${pageId}" wurde nicht gefunden.`);
  }
}

// Event-Listener für die Initialisierung beim Laden der Seite eim Laden der Seite wird die Funktion showPage('startseite') aufgerufen,
// um die Standardseite (startseite) anzuzeigen.


interface User {
  user_id: number;
  firstName: string;
  lastName: string;
  eMail: string;
  adress: string;
  role: string;
}

// Ein Modal-Objekt von Bootstrap wird hier deklariert, aber initialisiert erst später im DOMContentLoaded Event.
let modalEl: bootstrap.Modal
let modalTest: bootstrap.Modal
let modalAdmin: bootstrap.Modal
let modalAdminDelete: bootstrap.Modal


document.addEventListener("DOMContentLoaded", (): void => {
  showPage('startseite');
  modalEl = new bootstrap.Modal("#updateModal");
  modalTest = new bootstrap.Modal("#deleteModal");
  modalAdmin = new bootstrap.Modal("#updateAdminModal");
  modalAdminDelete = new bootstrap.Modal("#deleteModalAdmin");


  //--- check, if user is already logged in (e.g. after refresh) -------------------------------------------------------
  checkLogin();
  // --- Initialisierung der Benutzeranzeige ---
  readUsers();

  // --- Registrierungsformular Eventhandler ---
  //Registrierung des Event-Listeners
  document.getElementById("add-user-form")!.addEventListener("submit", async (event: SubmitEvent): Promise<void> => {
    //Verhindern des Standartverhaltens
    event.preventDefault();

    //Eingabefelder durch ihre IDs (grün) auslesen
    const firstNameEl: HTMLInputElement = document.getElementById("add-user-first-name") as HTMLInputElement;
    const lastNameEl: HTMLInputElement = document.getElementById("add-user-last-name") as HTMLInputElement;
    const eMailEl: HTMLInputElement = document.getElementById("add-user-email") as HTMLInputElement;
    const passwordEl: HTMLInputElement = document.getElementById("add-user-password") as HTMLInputElement;
    const repeatPasswordEl: HTMLInputElement = document.getElementById("add-user-repeatPassword") as HTMLInputElement;

//Die Werte der Eingabefelder werden in Variablen gespeichert
    const firstName: string = firstNameEl.value;
    const lastName: string = lastNameEl.value;
    const eMail: string = eMailEl.value;
    const password: string = passwordEl.value;
    const repeatPassword: string = repeatPasswordEl.value;

    // Validieren der Eingaben
    if (!firstName || !lastName || !eMail || !password || !repeatPassword) {
      addMessage("Bitte alle Felder ausfüllen!");
      showPage('registrieren');
      return;
    }

    // Validierung der Passwörter
    if (password !== repeatPassword) {
      addMessage("Passwörter stimmen nicht überein!");
      showPage('registrieren')
      return;
    }

    // Sende User Daten an Server - asynchrone HTTP-POST-Anfrage - await sorgt dafür, dass die Ausführung wartet, bis die Anfrage abgeschlossen
    // ist und eine Antwort vom Server erhalten wurde
    const res: Response = await fetch('/user', {
      method: 'POST',
      headers: {
        "Content-type": "application/json",
      },
      body: JSON.stringify({firstName, lastName, eMail, password, repeatPassword}),
    });

    //Antwort vom Server verarbeiten
    const data: any = await res.json();

    addMessage(data.message);

//Verarbeiten des Antwortstatus
    if (res.status === 201) {
      addMessage(data.message);
      showLoggedInStatus(data.user);
      userDataInProfile(data.user);
    } else {
      addMessage(data.message);
      showPage('registrieren');
    }


    // Zurücksetzen der Eingabefelder, sodass Vorlage wieder leer ist
    firstNameEl.value = "";
    lastNameEl.value = "";
    eMailEl.value = "";
    passwordEl.value = "";
    repeatPasswordEl.value = "";


  });
  const modalDeleteButton = document.getElementById("saveButtonDelete") as HTMLButtonElement;
  modalDeleteButton.addEventListener("click", async () => {
    deleteUser()
  })
  const modalDeleteButtonAdmin = document.getElementById("deleteButtonAdmin") as HTMLButtonElement;
  modalDeleteButtonAdmin.addEventListener("click", async () => {
    deleteUser()
  })

//Bearbeiten des Users als User
  document.getElementById("edit-profile-form")!.addEventListener("submit", async (event: SubmitEvent): Promise<void> => {
    event.preventDefault();
    const firstNameEl = document.getElementById("edit-user-first-name") as HTMLInputElement;
    const lastNameEl = document.getElementById("edit-user-last-name") as HTMLInputElement;
    const eMailEl = document.getElementById("edit-user-email") as HTMLInputElement;
    const adressEl = document.getElementById("edit-user-adress") as HTMLInputElement;
    const passwordEl = document.getElementById("modal-password") as HTMLInputElement;

    const firstName = firstNameEl.value;
    const lastName = lastNameEl.value;
    const eMail = eMailEl.value;
    const adress = adressEl.value;
    const password = passwordEl.value;
    //Daten an den Server senden - Put anfrage um daten zu aktualisieren
    const res: Response = await fetch(`/user`, {
      method: 'put',
      headers: {
        "Content-type": "application/json"
      },
      body: JSON.stringify({firstName, lastName, eMail, adress, password}),
    });

    //Antwort vom Server verarbeiten
    try {
      const data: any = await res.json();
      if (res.ok) {
        modalEl.hide();
        showPage('profil')// Modal schließen
        addMessage(data.message || "Profil wurde erfolgreich aktualisiert.");
        userDataInProfile(data.user);
      } else {
        console.error ("Fehler beim Aktualisieren des Profils.");
      }
    } catch (error) {
      console.error("Fehler beim Senden der Anfrage:", error);
    }

    // Update the html
    readUsers();
  });

  // edit admin
  document.getElementById("edit-user-admin-form")!.addEventListener("submit", async (event: SubmitEvent): Promise<void> => {
    event.preventDefault();
    let idEl: HTMLInputElement = document.getElementById("edit-user-admin-id") as HTMLInputElement;
    let firstNameEl: HTMLInputElement = document.getElementById("edit-user-admin-first-name") as HTMLInputElement;
    let lastNameEl: HTMLInputElement = document.getElementById("edit-user-admin-last-name") as HTMLInputElement;
    let eMailEl: HTMLInputElement = document.getElementById("edit-user-admin-email") as HTMLInputElement;
    let adressEl: HTMLInputElement = document.getElementById("edit-user-admin-adress") as HTMLInputElement;
    let roleEl: HTMLInputElement = document.getElementById("edit-user-admin-role") as HTMLInputElement;

    // Read the user's id from the hidden field.
    let userId: number = parseInt(idEl.value);
    let firstName: string = firstNameEl.value;
    let lastName: string = lastNameEl.value;
    let eMail: string = eMailEl.value;
    let adress: string = adressEl.value;
    let role: string = roleEl.value;

    const res: Response = await fetch('/user/' + userId, {
      method: 'put',
      headers: {
        "Content-type": "application/json"
      },
      body: JSON.stringify({firstName, lastName, eMail, adress, role}),
    });
    const data: any = await res.json();
    addMessage(data.message);

    // Hide the modal window
    modalAdmin.hide();

    // Update the html
    readUsers();
  });

  //Login
  document.getElementById("dropdown-anmelden")!.addEventListener("submit", async (event: SubmitEvent): Promise<void> => {
    event.preventDefault();

    //Abrufen der Formulardaten (document.getElementById('exampleDropdownFormEmail2'): Holt das HTML-Element mit der ID exampleDropdownFormEmail2,
    // das das Eingabefeld für die E-Mail-Adresse ist.
    const eMailInput: HTMLInputElement = document.getElementById('exampleDropdownFormEmail2') as HTMLInputElement;
    const passwordInput: HTMLInputElement = document.getElementById('exampleDropdownFormPassword2') as HTMLInputElement;

    //Werte, die der Benutzer in die E-Mail- und Passwortfelder eingegeben hat, extrahiert und in den Variablen gespeichert
    const eMail: string = eMailInput.value;
    const password: string = passwordInput.value;

    // Senden der Login-Daten an den Server
    const response: Response = await fetch('http://localhost:8080/login', {
        method: "POST",
        headers: {
          "Content-type": "application/json"
        },
        body: JSON.stringify({eMail, password}),
      }
    );

    //Der Code überprüft die HTTP-Antwort vom Server und reagiert je nach Statuscode:
    if (response.status === 400) {
      const data: any = await response.json();
      addMessage(data.message);
    } else if (response.status === 401) {
      const data: any = await response.json();
      addMessage(data.message);
      showPage('startseite')
    } else if (response.status === 200) {
      const data: any = await response.json();
      addMessage(data.message);
      console.log(data.user.role);
      if (data.user.role == 'admin') {
        console.log("admin");
        showPage('nutzerliste');
        showLoggedInStatus(data.user);
      }
      showLoggedInStatus(data.user);
      userDataInProfile(data.user);
    } else {
      console.warn(`Unhandled response code (${response.status}).`)
    }
  });


  //Logout durch POST-Anfrage an http://localhost:8080/logout, um den Benutzer abzumelden.
  document.getElementById("logout-form")!.addEventListener("submit", async (event: SubmitEvent): Promise<void> => {
    event.preventDefault();
    await fetch('http://localhost:8080/logout', {
        method: "POST",
      }
    );
    /*showLoggedOutStatus()*/
  });
});
/**
 * Checks if user might be logged
 */
//schaut ob der User eingeloggt ist, wenn ja schickt er die Daten vom User zurück
async function checkLogin(): Promise<void> {
  const response: Response = await fetch('/login', {
        method: "GET"
      }
  );
  if (response.status === 200) {
    const data: any = await response.json();
    showLoggedInStatus(data.user);
    userDataInProfile(data.user);
  }
}

/**
 * Gets and displays all users
 */
async function readUsers(): Promise<void> {
  const res: Response = await fetch('/users', {
      method: "GET"
    }
  );
  const data: any = await res.json();
  renderList(data.userList);
}

/**
 * Displays the logged in username
 */
function showLoggedInStatus(user: User): void {
  const firstName: HTMLElement = document.getElementById('current-user-firstName')!;
  firstName.innerHTML = `Hallo, ${user.firstName}!`; //firstName.innerHTML: Die innerHTML-Eigenschaft eines HTML-Elements enthält den HTML-Inhalt
  // des Elements. Hier wird der Inhalt des firstName-Elements (wahrscheinlich ein Textfeld oder ein div) auf den Text "Hallo, {user.firstName}!" gesetzt.

  const contentArea: HTMLElement = document.getElementById('user-list-container')!;
  contentArea.classList.remove("d-none"); // show content area

  readUsers();
}

//Funktion für get
function userDataInProfile (user: User): void {
  const firstNameEl: HTMLInputElement = document.getElementById('edit-user-first-name') as HTMLInputElement;
  const lastNameEl: HTMLInputElement = document.getElementById('edit-user-last-name') as HTMLInputElement;
  const eMailEl: HTMLInputElement = document.getElementById('edit-user-email') as HTMLInputElement;

  firstNameEl.value = user.firstName;
  lastNameEl.value = user.lastName;
  eMailEl.value = user.eMail;
}

//Delete
async function deleteUser(): Promise<void> {
  console.log("Enter delete function")

  //Daten an den Server senden - delete anfrage, um daten zu aktualisieren
  const res: Response = await fetch(`/user`, {
    method: 'delete',
    headers: {
      "Content-type": "application/json"
    },
  });

  //Antwort vom Server verarbeiten
  try {
    //modalEl.hide(); // Modal schließen
    const data: any = await res.json();
    if (res.ok) {
      modalTest.hide();// Modal schließen
      showPage('startseite')
      addMessage(data.message || "Profil wurde erfolgreich gelöscht.");
    } else {
      addMessage(data.message || "Fehler beim Löschen des Profils.");
    }
  } catch (error) {
    console.error("Fehler beim Senden der Löschen-Anfrage:", error);
  }

}
/**
function showLoggedOutStatus(): void {
  const eMail: HTMLElement = document.getElementById('current-user-email')!;
  eMail.innerHTML = ``;

  const addUserForm: HTMLElement = document.getElementById('add-user-container')!;
  addUserForm.classList.add("d-none"); // hide content area

  const contentArea: HTMLElement = document.getElementById('user-list-container')!;
  contentArea.classList.add("d-none"); // hide content area

  const login: HTMLElement = document.getElementById('login-container')!;
  login.classList.remove("d-none"); // show login

  (document.getElementById('add-user-form') as HTMLFormElement).reset();
}
*/
/// für ADMIN wieder relevant
/**
 * 1) Clears the user table.
 * 2) Adds all users to the table.
 */

//**
function renderList(userList: User[]): void {
  let userListEl: HTMLElement = document.getElementById("user-list")!;

  // Remove all entries from the table
  userListEl.replaceChildren();

  for (let user of userList) {
    // The new table row
    let tr: HTMLTableRowElement = document.createElement("tr");

    // ID cell
    let tdId: HTMLTableCellElement = document.createElement("td");
    tdId.textContent = user.user_id.toString();

    // Given name cell
    let tdFirstName: HTMLTableCellElement = document.createElement("td");
    tdFirstName.textContent = user.firstName;

    // Family name cell
    let tdLastName: HTMLTableCellElement = document.createElement("td");
    tdLastName.textContent = user.lastName;

    // email cell
    let tdEMail: HTMLTableCellElement = document.createElement("td");
    tdEMail.textContent = user.eMail;

    // address cell
    let tdAdress: HTMLTableCellElement = document.createElement("td");
    tdAdress.textContent = user.adress;

    // role cell
    let tdRole: HTMLTableCellElement = document.createElement("td");
    tdRole.textContent = user.role;

    // Buttons cell
    let tdButtons: HTMLTableCellElement = document.createElement("td");

    // Delete button
    let deleteButton: HTMLButtonElement = document.createElement("button");
    deleteButton.className = "btn delete-admin";
    deleteButton.addEventListener("click", async () => {
      const res: Response = await fetch('/user/' + user.user_id, {
        method: 'DELETE'
      });
      const data: any = await res.json();
      addMessage(data.message);
      readUsers();
    });

    // Delete button icon
    let deleteButtonIcon: HTMLElement = document.createElement("i");
    deleteButtonIcon.className = "fa-solid fa-trash-can deleteButton";
    deleteButton.append(deleteButtonIcon);

    // Edit button
    let editAdminButton: HTMLButtonElement = document.createElement("button");
    editAdminButton.className = "editButton";
    editAdminButton.addEventListener("click", () => {
      showEditModal(user);
    });

    // Edit button icon
    let editButtonIcon: HTMLElement = document.createElement("i");
    editButtonIcon.className = "fa-solid fa-pen updateButton";
    editAdminButton.append(editButtonIcon);

    // Adds the buttons to the button cell
    tdButtons.append(deleteButton, editAdminButton);

    // Add the cells to the table row
    tr.append(tdId, tdFirstName, tdLastName, tdEMail,tdAdress, tdRole, tdButtons);

    // Add the table row to the table
    userListEl.append(tr);
  }
}
/**
 * 1) Fills the modal window with the given user's data.
 * 2) Opens the modal window.
 */
function showEditModal(user: User): void {
  let idEl: HTMLInputElement = document.getElementById("edit-user-admin-id") as HTMLInputElement;
  let firstNameEl: HTMLInputElement = document.getElementById("edit-user-admin-first-name") as HTMLInputElement;
  let lastNameEl: HTMLInputElement = document.getElementById("edit-user-admin-last-name") as HTMLInputElement;
  let eMailEl: HTMLInputElement = document.getElementById("edit-user-admin-email") as HTMLInputElement;
  let adressEl: HTMLInputElement = document.getElementById("edit-user-admin-adress") as HTMLInputElement;
  let roleEl: HTMLInputElement = document.getElementById("edit-user-admin-role") as HTMLInputElement;

  // Write the user's id into the hidden field.
  idEl.value = user.user_id.toString();

  // Write the user's data into the text fields.
  firstNameEl.value = user.firstName;
  lastNameEl.value = user.lastName;
  eMailEl.value = user.eMail;
  adressEl.value = user.adress;
  roleEl.value = user.role;

  // Show the modal window.
  modalAdmin.show();
}


/**
 * Creates a new alert message.
 */
function addMessage(message: string): void {
  const messagesEl: HTMLElement = document.getElementById('messages')!;

  // The alert element
  let alertEl: HTMLElement = document.createElement('div');
  alertEl.classList.add('alert', 'alert-warning', 'alert-dismissible', 'fade', 'show');
  alertEl.setAttribute('role', 'alert');
  alertEl.textContent = message;

  // Close button
  let buttonEl: HTMLElement = document.createElement("button");
  // btn-close changes the button into an 'X' icon.
  buttonEl.className = "btn-close";
  // data-bs-dismiss enables the button to automatically close the alert on click.
  buttonEl.setAttribute("data-bs-dismiss", "alert");

  // Add the close button to the alert.
  alertEl.appendChild(buttonEl);

  // Convert to Bootstrap Alert type
  const alert: bootstrap.Alert = new bootstrap.Alert(alertEl);

  // Add message to DOM
  messagesEl.appendChild(alertEl);

  // Auto-remove message after 5 seconds (5000ms)
  setTimeout(() => {
    alert.close();
  }, 5000);
}