import { deleteUser, downloadBackup, getPatients, getSession, getUnreadMessageCount, getUnreadNotifications, getUsers, login, logout, markNotificationRead, saveUser, sendNotification, uploadBackup } from "./api.js";

const DEFAULT_PATIENT_PHOTO = "assets/default-patient.jpg";

const loginSection = document.getElementById("loginSection");
const dashboardSection = document.getElementById("dashboardSection");
const loginForm = document.getElementById("loginForm");
const usernameInput = document.getElementById("username");
const passwordInput = document.getElementById("password");
const loginError = document.getElementById("loginError");
const logoutBtn = document.getElementById("logoutBtn");
const welcomeMessage = document.getElementById("welcomeMessage");
const patientsSection = document.getElementById("patientsSection");
const addPatientBtn = document.getElementById("addPatientBtn");
const patientList = document.getElementById("patientList");
const searchInput = document.getElementById("searchInput");
const resultsInfo = document.getElementById("resultsInfo");
const sortMenuBtn = document.getElementById("sortMenuBtn");
const sortMenuLabel = document.getElementById("sortMenuLabel");
const sortMenuPopup = document.getElementById("sortMenuPopup");
const sortNewestBtn = document.getElementById("sortNewestBtn");
const sortAdmissionBtn = document.getElementById("sortAdmissionBtn");
const sortAlphabeticalBtn = document.getElementById("sortAlphabeticalBtn");
const adminPageNav = document.getElementById("adminPageNav");
const mainPageBtn = document.getElementById("mainPageBtn");
const archivePageBtn = document.getElementById("archivePageBtn");
const messagesPageBtn = document.getElementById("messagesPageBtn");
const adminPageBtn = document.getElementById("adminPageBtn");
const projectPageBtn = document.getElementById("projectPageBtn");
const logsPageBtn = document.getElementById("logsPageBtn");
const mobilePageNavToggle = document.getElementById("mobilePageNavToggle");
const userAdminSection = document.getElementById("userAdminSection");
const notificationForm = document.getElementById("notificationForm");
const notificationUserId = document.getElementById("notificationUserId");
const notificationMessage = document.getElementById("notificationMessage");
const notificationMessageBox = document.getElementById("notificationMessageBox");
const downloadBackupBtn = document.getElementById("downloadBackupBtn");
const backupUploadForm = document.getElementById("backupUploadForm");
const backupFileInput = document.getElementById("backupFileInput");
const backupMessage = document.getElementById("backupMessage");
const userForm = document.getElementById("userForm");
const userIdInput = document.getElementById("userId");
const managedUsernameInput = document.getElementById("managedUsername");
const managedPasswordInput = document.getElementById("managedPassword");
const managedRoleInput = document.getElementById("managedRole");
const userFormMessage = document.getElementById("userFormMessage");
const userList = document.getElementById("userList");
const notificationModal = document.getElementById("notificationModal");
const notificationModalSender = document.getElementById("notificationModalSender");
const notificationModalMessage = document.getElementById("notificationModalMessage");
const notificationCloseBtn = document.getElementById("notificationCloseBtn");
const notificationOkBtn = document.getElementById("notificationOkBtn");

let allPatients = [];
let allUsers = [];
let currentUser = null;
let currentSort = "newest";
let currentPage = "main";
let mobileNavOpen = false;
let unreadNotifications = [];

function syncPageFromLocation() {
  const hash = String(window.location.hash || "").toLocaleLowerCase("tr");
  if (hash === "#archive") {
    currentPage = "archive";
    return;
  }

  if (hash === "#admin" && currentUser?.role === "admin") {
    currentPage = "admin";
    return;
  }

  currentPage = "main";
}

function syncUnreadMessagesBadge(count) {
  if (!messagesPageBtn) return;
}

function getMissingPatientFields(patient) {
  const checks = [
    { key: "identityNumber", label: "Kimlik Numarası" },
    { key: "birthDate", label: "Doğum Tarihi" },
    { key: "status", label: "Durum" },
    { key: "roomNumber", label: "Oda" }
  ];

  return checks.filter(({ key }) => !String(patient?.[key] ?? "").trim());
}

function formatDisplayDate(value) {
  const text = String(value ?? "").trim();
  if (!text) return "-";

  const datePart = text.includes(" ") ? text.split(" ")[0] : text;
  const match = datePart.match(/^(\d{4})-(\d{2})-(\d{2})$/);
  if (match) {
    const [, year, month, day] = match;
    return `${day} / ${month} / ${year}`;
  }

  const date = new Date(text);
  if (Number.isNaN(date.getTime())) {
    return text;
  }

  return date.toLocaleDateString("tr-TR").replaceAll(".", " / ");
}

function formatDisplayDateTime(value) {
  const text = String(value ?? "").trim();
  if (!text) return "-";

  const date = new Date(text.replace(" ", "T"));
  if (Number.isNaN(date.getTime())) {
    return text;
  }

  const datePart = date.toLocaleDateString("tr-TR").replaceAll(".", " / ");
  const timePart = date.toLocaleTimeString("tr-TR", {
    hour: "2-digit",
    minute: "2-digit"
  });

  return `${datePart} ${timePart}`;
}

function formatArchiveDuration(value) {
  const text = String(value ?? "").trim();
  if (!text) return "";

  const archivedDate = new Date(text.replace(" ", "T"));
  if (Number.isNaN(archivedDate.getTime())) return "";

  const now = new Date();
  const diffMs = Math.max(0, now.getTime() - archivedDate.getTime());
  const totalDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));
  const years = Math.floor(totalDays / 365);
  const days = totalDays % 365;

  if (years > 0) {
    return `${years} yıl${days > 0 ? ` ${days} gün` : ""}`;
  }

  return `${totalDays} gün`;
}

function syncDashboardHeader() {
  const normalizedUsername = String(currentUser?.username ?? "").toLocaleLowerCase("tr");
  const canOpenProject = normalizedUsername === "emir" || normalizedUsername === "ece";

  welcomeMessage.textContent = currentUser ? `Hoş geldin ${currentUser.username}` : "Hoş geldin";

  if (currentUser) {
    addPatientBtn.classList.remove("hidden");
  } else {
    addPatientBtn.classList.add("hidden");
  }

  if (currentUser) {
    adminPageNav.classList.remove("hidden");
    mobilePageNavToggle.classList.remove("hidden");
  } else {
    adminPageNav.classList.add("hidden");
    mobilePageNavToggle.classList.add("hidden");
  }

  if (currentUser?.role !== "admin") {
    adminPageBtn.classList.add("hidden");
    if (currentPage === "admin") currentPage = "main";
  } else {
    adminPageBtn.classList.remove("hidden");
  }

  projectPageBtn.classList.toggle("hidden", !canOpenProject);
  logsPageBtn.classList.toggle("hidden", normalizedUsername !== "emir");

  syncPageView();
  syncMobilePageNav();
}

function showDashboard() {
  document.body.classList.remove("login-screen");
  loginSection.classList.add("hidden");
  dashboardSection.classList.remove("hidden");
  syncPageFromLocation();
  syncDashboardHeader();
}

function showLogin() {
  document.body.classList.add("login-screen");
  dashboardSection.classList.add("hidden");
  loginSection.classList.remove("hidden");
  mobileNavOpen = false;
}

function syncPageView() {
  const isAdminPage = currentPage === "admin" && currentUser?.role === "admin";
  patientsSection.classList.toggle("hidden", isAdminPage);
  userAdminSection.classList.toggle("hidden", !isAdminPage);

  mainPageBtn.classList.toggle("active", currentPage === "main");
  archivePageBtn.classList.toggle("active", currentPage === "archive");
  adminPageBtn.classList.toggle("active", isAdminPage);
  addPatientBtn.classList.toggle("hidden", !currentUser || currentPage === "archive" || isAdminPage);
}

function isMobileViewport() {
  return window.matchMedia("(max-width: 640px)").matches;
}

function syncMobilePageNav() {
  if (!currentUser || !isMobileViewport()) {
    mobileNavOpen = false;
    mobilePageNavToggle.setAttribute("aria-expanded", "false");
    adminPageNav.classList.remove("page-nav-mobile-open");
    return;
  }

  adminPageNav.classList.toggle("page-nav-mobile-open", mobileNavOpen);
  mobilePageNavToggle.setAttribute("aria-expanded", mobileNavOpen ? "true" : "false");
}

function sortPatients(patients) {
  const sorted = [...patients];

  if (currentSort === "alphabetical") {
    return sorted.sort((a, b) => a.fullName.localeCompare(b.fullName, "tr"));
  }

  if (currentSort === "admission") {
    const now = Date.now();
    return sorted.sort((a, b) => {
      const left = a.admissionDate ? Math.abs(new Date(a.admissionDate).getTime() - now) : Number.MAX_SAFE_INTEGER;
      const right = b.admissionDate ? Math.abs(new Date(b.admissionDate).getTime() - now) : Number.MAX_SAFE_INTEGER;
      return left - right;
    });
  }

  return sorted.sort((a, b) => {
    const left = new Date(b.createdAt || b.updatedAt).getTime();
    const right = new Date(a.createdAt || a.updatedAt).getTime();
    return left - right;
  });
}

function syncSortButtons() {
  const isNewest = currentSort === "newest";
  const isAdmission = currentSort === "admission";
  sortNewestBtn.classList.toggle("active", isNewest);
  sortAdmissionBtn.classList.toggle("active", isAdmission);
  sortAlphabeticalBtn.classList.toggle("active", currentSort === "alphabetical");
  sortMenuLabel.textContent =
    isNewest ? "En Son Eklenen" : isAdmission ? "Giriş Tarihine En Yakın" : "A-Z";
}

function closeSortMenu() {
  sortMenuPopup.classList.add("hidden");
  sortMenuBtn.setAttribute("aria-expanded", "false");
}

function toggleSortMenu() {
  const willOpen = sortMenuPopup.classList.contains("hidden");
  sortMenuPopup.classList.toggle("hidden", !willOpen);
  sortMenuBtn.setAttribute("aria-expanded", willOpen ? "true" : "false");
}

function renderPatients(patients) {
  resultsInfo.textContent = `${patients.length} hasta`;
  patientList.innerHTML = "";

  if (!patients.length) {
    patientList.innerHTML = '<p class="empty-state">Aramanıza uygun hasta bulunamadı.</p>';
    return;
  }

  patients.forEach((patient) => {
    const card = document.createElement("article");
    const missingFields = getMissingPatientFields(patient);
    card.className = `patient-card${missingFields.length ? " patient-card-missing-data" : ""}`;
    card.tabIndex = 0;
    card.setAttribute("role", "link");
    card.setAttribute("aria-label", `${patient.fullName} detayini ac`);
    if (missingFields.length) {
      card.setAttribute(
        "title",
        `Eksik bilgiler: ${missingFields.map((field) => field.label).join(", ")}`
      );
    }
    const photoMarkup = `<img class="patient-avatar" src="${patient.photoUrl || DEFAULT_PATIENT_PHOTO}" alt="${patient.fullName} fotografi" />`;
    const expiredMedicationCount = Number(patient.expiredPrescribedMedicationsCount || 0);
    const archiveDuration = patient.archivedAt ? formatArchiveDuration(patient.archivedAt) : "";
    const normalizedName = String(patient.fullName || "").trim();
    const longestNameWordLength = normalizedName
      .split(/\s+/)
      .reduce((maxLength, word) => Math.max(maxLength, word.length), 0);
    const nameClass = longestNameWordLength >= 16 || normalizedName.length >= 26
      ? "patient-name-very-long"
      : longestNameWordLength >= 12 || normalizedName.length >= 20
        ? "patient-name-long"
        : "";
    card.innerHTML = `
      <div class="patient-card-top">
        <div class="patient-card-heading">
          ${photoMarkup}
          <div>
          <h3 class="${nameClass}">${patient.fullName}</h3>
          <span class="status-badge">${patient.status}</span>
          </div>
        </div>
        <span class="room-badge">${patient.roomNumber}</span>
      </div>
      ${expiredMedicationCount > 0 ? `<span class="patient-alert-badge">İlaç ${expiredMedicationCount}</span>` : ""}
      <p class="patient-meta">${formatDisplayDate(patient.birthDate)} • ${patient.identityNumber || "-"}</p>
      <p class="patient-diagnosis">${patient.diagnosis}</p>
      ${patient.archivedAt ? `<p class="patient-archive-duration">Arşivde: ${archiveDuration}</p>` : ""}
    `;
    const openDetail = () => {
      window.location.href = `detail.php?slug=${encodeURIComponent(patient.slug)}`;
    };
    card.addEventListener("click", openDetail);
    card.addEventListener("keydown", (event) => {
      if (event.key === "Enter" || event.key === " ") {
        event.preventDefault();
        openDetail();
      }
    });
    patientList.appendChild(card);
  });
}

function filterPatients() {
  const query = searchInput.value.trim().toLocaleLowerCase("tr");
  const filtered = allPatients.filter((patient) =>
    patient.fullName.toLocaleLowerCase("tr").includes(query)
    && (currentPage === "archive" ? Boolean(patient.archivedAt) : !patient.archivedAt)
  );
  renderPatients(sortPatients(filtered));
}

async function loadPatients() {
  allPatients = await getPatients();
  filterPatients();
}

async function loadUnreadMessageCount() {
  if (!currentUser) {
    syncUnreadMessagesBadge(0);
    return;
  }

  try {
    const count = await getUnreadMessageCount();
    syncUnreadMessagesBadge(count);
  } catch {
    syncUnreadMessagesBadge(0);
  }
}

function renderUsers() {
  userList.innerHTML = "";
  notificationUserId.innerHTML = '<option value="">Kullanıcı seçin</option><option value="all">Herkes</option>';

  if (!allUsers.length) {
    userList.innerHTML = '<p class="empty-state">Hemşire kullanıcısı bulunamadı.</p>';
    return;
  }

  allUsers.forEach((user) => {
    notificationUserId.insertAdjacentHTML("beforeend", `<option value="${user.id}">${user.username}</option>`);
    const canEdit = user.username !== "emir" || currentUser?.username === "emir";
    const canDelete = user.username !== "emir";
    const item = document.createElement("article");
    item.className = "user-item";
    item.innerHTML = `
      <div>
        <strong>${user.username}</strong>
        <p class="patient-meta">Rol: ${user.role} • Son aktif: ${formatDisplayDateTime(user.last_active_at)}</p>
      </div>
      <div class="user-actions">
        ${canEdit ? `<button class="btn btn-secondary user-edit-btn" type="button" data-id="${user.id}">Düzenle</button>` : ""}
        ${canDelete ? `<button class="btn btn-secondary user-delete-btn" type="button" data-id="${user.id}">Sil</button>` : ""}
      </div>
    `;
    userList.appendChild(item);
  });

  userList.querySelectorAll(".user-edit-btn").forEach((button) => {
    button.addEventListener("click", () => {
      const selected = allUsers.find((user) => String(user.id) === button.dataset.id);
      if (!selected) return;

      userIdInput.value = selected.id;
      managedUsernameInput.value = selected.username;
      managedPasswordInput.value = "";
      managedRoleInput.value = selected.role;
      userFormMessage.textContent = `"${selected.username}" kullanıcısı düzenleniyor.`;
      userFormMessage.className = "helper-text";
    });
  });

  userList.querySelectorAll(".user-delete-btn").forEach((button) => {
    button.addEventListener("click", async () => {
      const selected = allUsers.find((user) => String(user.id) === button.dataset.id);
      if (!selected) return;

      const confirmed = window.confirm(`${selected.username} kullanıcısını silmek istiyor musunuz?`);
      if (!confirmed) return;

      try {
        const response = await deleteUser(Number(selected.id));
        userFormMessage.textContent = response.message;
        userFormMessage.className = "helper-text";
        await loadUsers();
      } catch (error) {
        userFormMessage.textContent = error.message;
        userFormMessage.className = "error-text";
      }
    });
  });
}

async function loadUsers() {
  if (currentUser?.role !== "admin") {
    userAdminSection.classList.add("hidden");
    return;
  }

  allUsers = await getUsers();
  renderUsers();
  syncPageView();
}

function resetUserForm() {
  userForm.reset();
  userIdInput.value = "";
  managedRoleInput.value = "hemsire";
  userFormMessage.textContent = "";
  userFormMessage.className = "helper-text hidden";
}

function showBackupMessage(message, isError = false) {
  backupMessage.textContent = message;
  backupMessage.className = isError ? "error-text" : "helper-text";
}

function showNotificationMessage(message, isError = false) {
  notificationMessageBox.textContent = message;
  notificationMessageBox.className = isError ? "error-text" : "helper-text";
}

function openNotificationModal(notification) {
  notificationModalSender.textContent = notification.senderUsername ? `Gönderen: ${notification.senderUsername}` : "Bildirim";
  notificationModalMessage.textContent = notification.message || "-";
  notificationModal.classList.remove("hidden");
  notificationModal.setAttribute("aria-hidden", "false");
}

function closeNotificationModal() {
  notificationModal.classList.add("hidden");
  notificationModal.setAttribute("aria-hidden", "true");
}

async function showNextNotification() {
  if (!unreadNotifications.length) {
    closeNotificationModal();
    return;
  }

  openNotificationModal(unreadNotifications[0]);
}

async function markCurrentNotificationRead() {
  const currentNotification = unreadNotifications[0];
  if (!currentNotification) {
    closeNotificationModal();
    return;
  }

  try {
    await markNotificationRead(Number(currentNotification.id));
  } catch {
  }

  unreadNotifications.shift();
  await showNextNotification();
}

async function loadUnreadNotifications() {
  unreadNotifications = await getUnreadNotifications();
  await showNextNotification();
}

function bindEvents() {
  loginForm.addEventListener("submit", async (event) => {
    event.preventDefault();
    loginError.classList.add("hidden");

    try {
      const response = await login(usernameInput.value.trim(), passwordInput.value);
      currentUser = response.user;
      showDashboard();
      await loadPatients();
      await loadUsers();
      await loadUnreadMessageCount();
      await loadUnreadNotifications();
      loginForm.reset();
    } catch (error) {
      loginError.textContent = error.message;
      loginError.classList.remove("hidden");
    }
  });

  logoutBtn.addEventListener("click", async () => {
    await logout();
    showLogin();
    currentUser = null;
    syncDashboardHeader();
    patientList.innerHTML = "";
    resultsInfo.textContent = "";
    userAdminSection.classList.add("hidden");
    userList.innerHTML = "";
    unreadNotifications = [];
    syncUnreadMessagesBadge(0);
    closeNotificationModal();
  });

  searchInput.addEventListener("input", filterPatients);
  sortMenuBtn.addEventListener("click", toggleSortMenu);
  sortNewestBtn.addEventListener("click", () => {
    currentSort = "newest";
    syncSortButtons();
    filterPatients();
    closeSortMenu();
  });
  sortAdmissionBtn.addEventListener("click", () => {
    currentSort = "admission";
    syncSortButtons();
    filterPatients();
    closeSortMenu();
  });
  sortAlphabeticalBtn.addEventListener("click", () => {
    currentSort = "alphabetical";
    syncSortButtons();
    filterPatients();
    closeSortMenu();
  });
  mainPageBtn.addEventListener("click", () => {
    currentPage = "main";
    window.location.hash = "";
    mobileNavOpen = false;
    syncPageView();
    syncMobilePageNav();
    filterPatients();
  });
  archivePageBtn.addEventListener("click", () => {
    currentPage = "archive";
    window.location.hash = "archive";
    mobileNavOpen = false;
    syncPageView();
    syncMobilePageNav();
    filterPatients();
  });
  adminPageBtn.addEventListener("click", () => {
    currentPage = "admin";
    window.location.hash = "admin";
    mobileNavOpen = false;
    syncPageView();
    syncMobilePageNav();
  });
  mobilePageNavToggle.addEventListener("click", () => {
    mobileNavOpen = !mobileNavOpen;
    syncMobilePageNav();
  });
  document.addEventListener("click", (event) => {
    if (!sortMenuPopup.contains(event.target) && !sortMenuBtn.contains(event.target)) {
      closeSortMenu();
    }
    if (
      isMobileViewport()
      && mobileNavOpen
      && !adminPageNav.contains(event.target)
      && !mobilePageNavToggle.contains(event.target)
    ) {
      mobileNavOpen = false;
      syncMobilePageNav();
    }
  });
  window.addEventListener("resize", syncMobilePageNav);
  window.addEventListener("hashchange", () => {
    syncPageFromLocation();
    syncPageView();
    syncMobilePageNav();
    filterPatients();
  });
  notificationCloseBtn.addEventListener("click", markCurrentNotificationRead);
  notificationOkBtn.addEventListener("click", markCurrentNotificationRead);

  downloadBackupBtn.addEventListener("click", () => {
    showBackupMessage("Yedek hazırlanıyor...");
    downloadBackup();
    window.setTimeout(() => {
      showBackupMessage("Yedek indirme başlatıldı.");
    }, 300);
  });

  backupUploadForm.addEventListener("submit", async (event) => {
    event.preventDefault();

    const file = backupFileInput.files?.[0];
    if (!file) {
      showBackupMessage("Lütfen bir SQL yedek dosyası seçin.", true);
      return;
    }

    const confirmed = window.confirm("Bu işlem mevcut veritabanını değiştirebilir. Devam etmek istiyor musunuz?");
    if (!confirmed) return;

    const formData = new FormData();
    formData.set("backup", file);

    try {
      const response = await uploadBackup(formData);
      showBackupMessage(response.message);
      backupUploadForm.reset();
      await loadPatients();
      await loadUsers();
      await loadUnreadMessageCount();
    } catch (error) {
      showBackupMessage(error.message, true);
    }
  });

  notificationForm.addEventListener("submit", async (event) => {
    event.preventDefault();

    const userId = notificationUserId.value || "";
    const message = notificationMessage.value.trim();

    if (!userId) {
      showNotificationMessage("Lütfen kullanıcı seçin.", true);
      return;
    }

    if (!message) {
      showNotificationMessage("Bildirim mesajı boş olamaz.", true);
      return;
    }

    try {
      const response = await sendNotification(userId, message);
      showNotificationMessage(response.message);
      notificationForm.reset();
    } catch (error) {
      showNotificationMessage(error.message, true);
    }
  });

  userForm.addEventListener("submit", async (event) => {
    event.preventDefault();

    try {
      const response = await saveUser({
        id: userIdInput.value ? Number(userIdInput.value) : 0,
        username: managedUsernameInput.value.trim(),
        password: managedPasswordInput.value,
        role: managedRoleInput.value.trim()
      });

      userFormMessage.textContent = response.message;
      userFormMessage.className = "helper-text";
      await loadUsers();
      resetUserForm();
    } catch (error) {
      userFormMessage.textContent = error.message;
      userFormMessage.className = "error-text";
    }
  });

}

async function init() {
  bindEvents();
  syncSortButtons();
  window.setInterval(() => {
    if (currentUser) {
      loadUnreadMessageCount().catch(() => {});
    }
  }, 15000);

  try {
    const session = await getSession();

    if (session.authenticated) {
      currentUser = session.user;
      showDashboard();
      await loadPatients();
      await loadUsers();
      await loadUnreadMessageCount();
      await loadUnreadNotifications();
      return;
    }
  } catch {
    loginError.textContent = "Sunucu bağlantısı kurulamadı.";
    loginError.classList.remove("hidden");
  }

  showLogin();
}

init();
