import { archivePatient, deletePatient, getOrdersBySlug, getPatientBySlug, getSession, saveOrders, unarchivePatient, updatePatient } from "./api.js";

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

const params = new URLSearchParams(window.location.search);
const slug = params.get("slug");

const patientName = document.getElementById("patientName");
const patientAge = document.getElementById("patientAge");
const editPatientNameBtn = document.getElementById("editPatientNameBtn");
const detailContent = document.getElementById("detailContent");
const deletePatientBtn = document.getElementById("deletePatientBtn");
const archivePatientBtn = document.getElementById("archivePatientBtn");
const archivePatientBtnLabel = document.getElementById("archivePatientBtnLabel");
const patientFilesBtn = document.getElementById("patientFilesBtn");
const patientFilesBadge = document.getElementById("patientFilesBadge");
const photoEditBtn = document.getElementById("photoEditBtn");
const photoEditInput = document.getElementById("photoEditInput");
let detailHeaderPhoto = document.getElementById("detailHeaderPhoto");

const rowFields = [
  { key: "identityNumber", label: "Kimlik Numarası", type: "text", section: "Temel Bilgiler" },
  { key: "birthDate", label: "Doğum Tarihi", type: "date", section: "Temel Bilgiler" },
  { key: "admissionDate", label: "Giriş Tarihi", type: "date", section: "Temel Bilgiler" },
  { key: "diagnosis", label: "Kronik Rahatsızlıkları", type: "textarea", section: "Temel Bilgiler" },
  { key: "status", label: "Durum", type: "text", section: "Temel Bilgiler" },
  { key: "carePlan", label: "Alerjiler", type: "textarea", section: "Temel Bilgiler" },
  { key: "emergencyContact", label: "Acil Durumda Aranacaklar", type: "textarea", section: "Temel Bilgiler" },
  { key: "heightWeight", label: "Boy - Kilo", type: "textarea", section: "Sağlık" },
  { key: "prescribedMedications", label: "Raporlu İlaçlar", type: "medications", section: "Sağlık" },
  { key: "roomNumber", label: "Oda", type: "text", section: "Sağlık" },
  { key: "medicationHours", label: "Durdurulan İlaçlar", type: "text", section: "Sağlık" },
  { key: "notes", label: "Narkotik İlaç Kullanımı", type: "textarea", section: "Sağlık" }
];

let activePatient = null;
let currentUser = null;
let editingField = null;
let orderForms = [];

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 escapeHtml(value) {
  return String(value ?? "")
    .replaceAll("&", "&amp;")
    .replaceAll("<", "&lt;")
    .replaceAll(">", "&gt;")
    .replaceAll('"', "&quot;");
}

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

  const date = new Date(text);
  if (Number.isNaN(date.getTime())) return "-";

  const now = new Date();
  let age = now.getFullYear() - date.getFullYear();
  const monthDiff = now.getMonth() - date.getMonth();

  if (monthDiff < 0 || (monthDiff === 0 && now.getDate() < date.getDate())) {
    age--;
  }

  return age >= 0 ? `${age} yaşında` : "-";
}

function getFieldConfig(fieldKey) {
  return rowFields.find((field) => field.key === fieldKey);
}

function getFieldValue(patient, fieldKey) {
  if (fieldKey === "carePlan") {
    return Array.isArray(patient.carePlan) ? patient.carePlan.join(", ") : "";
  }

  if (fieldKey === "birthDate" || fieldKey === "admissionDate") {
    return formatDisplayDate(patient[fieldKey]);
  }

  return patient[fieldKey] ?? "";
}

function formatMedicationExpiryDate(value) {
  return formatDisplayDate(value);
}

function buildPatientFormData(overrides = {}, photoFile = null) {
  const formData = new FormData();
  const merged = {
    ...activePatient,
    ...overrides
  };

  formData.set("id", String(activePatient.id));
  formData.set("fullName", String(merged.fullName).trim());
  formData.set("roomNumber", String(merged.roomNumber).trim());
  formData.set("floor", String(merged.floor).trim());
  formData.set("birthDate", String(merged.birthDate).trim());
  formData.set("admissionDate", String(merged.admissionDate).trim());
  formData.set("identityNumber", String(merged.identityNumber).trim());
  formData.set("status", String(merged.status).trim());
  formData.set("heightWeight", String(merged.heightWeight).trim());
  formData.set("prescribedMedications", JSON.stringify(Array.isArray(merged.prescribedMedications) ? merged.prescribedMedications : []));
  formData.set("medicationHours", String(merged.medicationHours).trim());
  formData.set("diagnosis", String(merged.diagnosis).trim());
  formData.set("emergencyContact", String(merged.emergencyContact).trim());
  formData.set("notes", String(merged.notes).trim());
  formData.set(
    "carePlan",
    (Array.isArray(merged.carePlan) ? merged.carePlan : String(merged.carePlan).split(","))
      .map((item) => String(item).trim())
      .filter(Boolean)
      .join(", ")
  );

  if (photoFile) {
    formData.set("photo", photoFile);
  }

  return formData;
}

async function saveField(fieldKey, rawValue) {
  const overrides = {
    [fieldKey]:
      fieldKey === "prescribedMedications"
        ? (Array.isArray(rawValue) ? rawValue : [])
        :
      fieldKey === "carePlan"
        ? String(rawValue)
            .split(",")
            .map((item) => item.trim())
            .filter(Boolean)
        : String(rawValue).trim()
  };

  activePatient = await updatePatient(buildPatientFormData(overrides));
  editingField = null;
  syncHeader();
  renderView(activePatient);
}

function renderPrescribedMedicationsStatic(patient) {
  const items = Array.isArray(patient.prescribedMedications) ? patient.prescribedMedications : [];
  if (!items.length) {
    return '<strong>-</strong>';
  }

  return `
    <div class="prescribed-medications-static-list">
      ${items.map((item) => `
        <div class="prescribed-medications-static-item${item.isExpired ? " prescribed-medication-expired" : ""}">
          <strong>${escapeHtml(item.name || "-")}</strong>
          <span>${escapeHtml(formatMedicationExpiryDate(item.expiryDate || ""))}</span>
        </div>
      `).join("")}
    </div>
  `;
}

function createMedicationEditorRows(items = []) {
  const normalizedItems = items.length ? items : [{ name: "", expiryDate: "" }];
  return normalizedItems.map((item) => `
    <div class="prescribed-medication-row">
      <textarea name="medicationName" class="prescribed-medication-name" rows="2" placeholder="İlaç adı">${escapeHtml(item.name || "")}</textarea>
      <input name="medicationExpiryDate" class="prescribed-medication-expiry" type="date" value="${escapeHtml(item.expiryDate || "")}" />
      <button class="file-action-btn file-action-btn-danger" type="button" data-remove-medication-row aria-label="İlaç satırını sil">×</button>
    </div>
  `).join("");
}

function attachMedicationRowHandlers(scope) {
  scope.querySelectorAll("[data-remove-medication-row]").forEach((button) => {
    if (button.dataset.bound === "1") return;
    button.dataset.bound = "1";
    button.addEventListener("click", () => {
      const row = button.closest(".prescribed-medication-row");
      const rowsHost = button.closest("[data-medication-rows]");
      row?.remove();
      if (rowsHost && !rowsHost.querySelector(".prescribed-medication-row")) {
        rowsHost.insertAdjacentHTML("beforeend", createMedicationEditorRows([{ name: "", expiryDate: "" }]));
        attachMedicationRowHandlers(rowsHost);
      }
    });
  });
}

function renderStaticRow(field, patient) {
  const value =
    field.key === "prescribedMedications"
      ? renderPrescribedMedicationsStatic(patient)
      :
    field.key === "carePlan"
      ? `<ul class="detail-inline-list">${(patient.carePlan || []).map((item) => `<li>${escapeHtml(item)}</li>`).join("")}</ul>`
      : `<strong>${escapeHtml(getFieldValue(patient, field.key) || "-")}</strong>`;

  return `
    <div class="detail-row">
      <div class="detail-row-content">
        <span>${field.label}</span>
        ${value}
      </div>
      <button class="mini-edit-btn" type="button" data-field="${field.key}" aria-label="${field.label} duzenle">✎</button>
    </div>
  `;
}

function renderEditRow(field, patient) {
  if (field.key === "prescribedMedications") {
    return `
      <form class="detail-row detail-row-form detail-row-form-medications" data-edit-form="${field.key}">
        <div class="detail-row-content">
          <span>${field.label}</span>
          <div class="prescribed-medications-rows" data-medication-rows>
            ${createMedicationEditorRows(Array.isArray(patient.prescribedMedications) ? patient.prescribedMedications : [])}
          </div>
          <button class="file-action-btn" type="button" data-add-medication-row aria-label="İlaç satırı ekle">+</button>
        </div>
        <div class="detail-row-actions">
          <button class="mini-edit-btn mini-edit-btn-save" type="submit">Kaydet</button>
          <button class="mini-edit-btn" type="button" data-cancel-field="${field.key}">Iptal</button>
        </div>
      </form>
    `;
  }

  const value = escapeHtml(field.type === "date" ? (patient[field.key] || "") : getFieldValue(patient, field.key));
  const rows = field.type === "textarea-list" ? 4 : field.type === "textarea" ? 3 : 2;
  const inputMarkup =
    field.type === "textarea" || field.type === "textarea-list" || field.type === "text"
      ? `<textarea name="value" rows="${rows}" ${field.type === "textarea-list" ? 'placeholder="Virgülle ayırın"' : ""}>${value}</textarea>`
      : `<input name="value" type="${field.type}" value="${value}" />`;

  return `
    <form class="detail-row detail-row-form" data-edit-form="${field.key}">
      <div class="detail-row-content">
        <span>${field.label}</span>
        ${inputMarkup}
      </div>
      <div class="detail-row-actions">
        <button class="mini-edit-btn mini-edit-btn-save" type="submit">Kaydet</button>
        <button class="mini-edit-btn" type="button" data-cancel-field="${field.key}">Iptal</button>
      </div>
    </form>
  `;
}

function renderSection(title, fields, patient, extraContent = "") {
  return `
    <article class="panel-card detail-card">
      <h2>${title}</h2>
      <div class="detail-list">
        ${fields
          .map((field) => (editingField === field.key ? renderEditRow(field, patient) : renderStaticRow(field, patient)))
          .join("")}
      </div>
      ${extraContent}
    </article>
  `;
}

function renderOrdersSection() {
  return `
    <article class="panel-card detail-card">
      <div class="orders-link-card-body orders-link-card" role="link" tabindex="0" data-open-orders>
        <div>
          <h2>Order</h2>
          <p class="helper-text">Yeni boş orders tablosu aç.</p>
        </div>
        <span class="orders-link-arrow" aria-hidden="true">→</span>
      </div>
      <div class="orders-list">
        ${
          orderForms.length
            ? orderForms
                .map(
                  (item, index) => `
                    <div class="orders-list-item">
                      <button class="orders-list-open" type="button" data-open-order-id="${item.id}">
                        <span>Order ${orderForms.length - index}</span>
                        <small>Kayıt Tarihi: ${formatDisplayDate(item.createdAt)}</small>
                      </button>
                      <button class="file-action-btn" type="button" data-copy-order-id="${item.id}" aria-label="Order kopyala">⧉</button>
                      <button class="file-action-btn file-action-btn-danger" type="button" data-delete-order-id="${item.id}" aria-label="Orders kaydını sil">×</button>
                    </div>
                  `
                )
                .join("")
            : '<p class="helper-text">Henüz kaydedilmiş orders yok.</p>'
        }
      </div>
    </article>
  `;
}

function bindRowEvents() {
  detailContent.querySelectorAll("[data-field]").forEach((button) => {
    button.addEventListener("click", () => {
      editingField = button.dataset.field;
      renderView(activePatient);
    });
  });

  detailContent.querySelectorAll("[data-cancel-field]").forEach((button) => {
    button.addEventListener("click", () => {
      editingField = null;
      renderView(activePatient);
    });
  });

  detailContent.querySelectorAll("[data-edit-form]").forEach((form) => {
    form.addEventListener("submit", async (event) => {
      event.preventDefault();
      const fieldKey = form.dataset.editForm;
      const value = fieldKey === "prescribedMedications"
        ? Array.from(form.querySelectorAll(".prescribed-medication-row")).map((row) => ({
            name: row.querySelector(".prescribed-medication-name")?.value?.trim() || "",
            expiryDate: row.querySelector(".prescribed-medication-expiry")?.value || ""
          })).filter((item) => item.name || item.expiryDate)
        : new FormData(form).get("value");

      try {
        await saveField(fieldKey, value);
      } catch (error) {
        window.alert(error.message);
      }
    });
  });

  detailContent.querySelectorAll("[data-add-medication-row]").forEach((button) => {
    button.addEventListener("click", () => {
      const rowsHost = button.closest("form")?.querySelector("[data-medication-rows]");
      if (!rowsHost) return;
      rowsHost.insertAdjacentHTML("beforeend", createMedicationEditorRows([{ name: "", expiryDate: "" }]));
      attachMedicationRowHandlers(rowsHost);
    });
  });
  attachMedicationRowHandlers(detailContent);

  detailContent.querySelectorAll("[data-open-orders]").forEach((card) => {
    const openOrders = () => {
      window.location.href = `orders.php?slug=${encodeURIComponent(activePatient.slug)}`;
    };

    card.addEventListener("click", openOrders);
    card.addEventListener("keydown", (event) => {
      if (event.key === "Enter" || event.key === " ") {
        event.preventDefault();
        openOrders();
      }
    });
  });

  detailContent.querySelectorAll("[data-open-order-id]").forEach((button) => {
    button.addEventListener("click", () => {
      window.location.href = `orders.php?slug=${encodeURIComponent(activePatient.slug)}&formId=${encodeURIComponent(button.dataset.openOrderId)}`;
    });
  });

  detailContent.querySelectorAll("[data-delete-order-id]").forEach((button) => {
    button.addEventListener("click", async (event) => {
      event.stopPropagation();
      const formId = button.dataset.deleteOrderId;
      const confirmed = window.confirm("Bu orders kaydını silmek istiyor musunuz?");
      if (!confirmed) return;

      const { deleteOrder } = await import("./api.js");
      try {
        const response = await deleteOrder(Number(activePatient.id), Number(formId));
        orderForms = response.orderForms || [];
        renderView(activePatient);
      } catch (error) {
        window.alert(error.message);
      }
    });
  });

  detailContent.querySelectorAll("[data-copy-order-id]").forEach((button) => {
    button.addEventListener("click", async (event) => {
      event.stopPropagation();
      const formId = Number(button.dataset.copyOrderId || 0);
      if (!formId || !activePatient?.id || !activePatient?.slug) return;

      try {
        const data = await getOrdersBySlug(activePatient.slug, formId);
        const items = data.activeOrder?.items || [];
        const response = await saveOrders(Number(activePatient.id), items, 0);
        orderForms = response.orderForms || orderForms;
        renderView(activePatient);
      } catch (error) {
        window.alert(error.message);
      }
    });
  });
}

function renderView(patient) {
  const basicFields = rowFields.filter((field) => field.section === "Temel Bilgiler");
  const healthFields = rowFields.filter((field) => field.section === "Sağlık");

  detailContent.innerHTML = `
    <section class="detail-grid">
      ${renderSection(
        "Temel Bilgiler",
        basicFields,
        patient,
        `<p class="helper-text">Son güncelleme: ${escapeHtml(formatDisplayDateTime(patient.updatedAt))} - ${escapeHtml(patient.lastModifiedByUsername || "-")}</p>`
      )}
      ${renderSection("Sağlık", healthFields, patient)}
      ${renderOrdersSection()}
    </section>
  `;

  bindRowEvents();
}

function syncHeader() {
  patientName.textContent = activePatient.fullName;
  patientAge.textContent = getPatientAgeText(activePatient.birthDate);
  deletePatientBtn.classList.toggle("hidden", currentUser?.role !== "admin");
  patientFilesBtn.href = `patient-files.php?slug=${encodeURIComponent(activePatient.slug)}`;
  patientFilesBadge.textContent = String(activePatient.filesCount || 0);
  patientFilesBadge.classList.toggle("hidden", Number(activePatient.filesCount || 0) <= 0);
  archivePatientBtnLabel.textContent = activePatient.archivedAt ? "Arşivden Çıkar" : "Arşiv";
  archivePatientBtn.setAttribute("aria-label", activePatient.archivedAt ? "Hastayı arşivden çıkar" : "Hastayı arşivle");

  detailHeaderPhoto.outerHTML = `<img id="detailHeaderPhoto" class="detail-header-avatar" src="${activePatient.photoUrl || DEFAULT_PATIENT_PHOTO}" alt="${escapeHtml(activePatient.fullName)} fotoğrafı" />`;

  detailHeaderPhoto = document.getElementById("detailHeaderPhoto");
}

async function init() {
  try {
    const session = await getSession();
    if (!session.authenticated) {
      window.location.replace("index.php");
      return;
    }

    currentUser = session.user;
  } catch {
    detailContent.innerHTML = '<section class="panel-card"><p class="empty-state">Sunucu bağlantısı kurulamadı.</p></section>';
    return;
  }

  if (!slug) {
    detailContent.innerHTML = '<section class="panel-card"><p class="empty-state">Hasta kaydı bulunamadı.</p></section>';
    return;
  }

  try {
    const patient = await getPatientBySlug(slug);
    activePatient = patient;
    orderForms = patient.orderForms || [];
    syncHeader();
    renderView(activePatient);

    photoEditBtn.addEventListener("click", () => {
      photoEditInput.click();
    });

    photoEditInput.addEventListener("change", async () => {
      const file = photoEditInput.files?.[0];
      if (!file) return;

      try {
        activePatient = await updatePatient(buildPatientFormData({}, file));
        syncHeader();
        renderView(activePatient);
      } catch (error) {
        window.alert(error.message);
      } finally {
        photoEditInput.value = "";
      }
    });

    editPatientNameBtn?.addEventListener("click", async () => {
      const nextName = window.prompt("Yeni isim soyisim", String(activePatient?.fullName || "").trim());
      if (nextName === null) return;

      const normalizedName = nextName.trim();
      if (!normalizedName) {
        window.alert("İsim boş olamaz.");
        return;
      }

      try {
        activePatient = await updatePatient(buildPatientFormData({ fullName: normalizedName }));
        syncHeader();
        renderView(activePatient);
      } catch (error) {
        window.alert(error.message);
      }
    });

    archivePatientBtn.addEventListener("click", async () => {
      if (!activePatient) return;

      const isArchived = Boolean(activePatient.archivedAt);
      const confirmed = window.confirm(
        isArchived
          ? `${activePatient.fullName} adlı kişiyi arşivden çıkarayım mı?`
          : `${activePatient.fullName} adlı kişiyi arşive ekleyeyim mi?`
      );
      if (!confirmed) return;

      const secondConfirm = window.confirm(
        isArchived
          ? "Bu kişi tekrar Ana Sayfa listesinde görünecek. Devam edilsin mi?"
          : "Arşivlenen kişi ana sayfada görünmeyecek, Arşiv sayfasında listelenecek. Devam edilsin mi?"
      );
      if (!secondConfirm) return;

      try {
        if (isArchived) {
          await unarchivePatient(Number(activePatient.id));
        } else {
          await archivePatient(Number(activePatient.id));
        }
        window.location.replace("index.php");
      } catch (error) {
        window.alert(error.message);
      }
    });

    deletePatientBtn.addEventListener("click", async () => {
      if (currentUser?.role !== "admin" || !activePatient) return;

      const firstConfirm = window.confirm(`${activePatient.fullName} kaydını silmek istiyor musunuz?`);
      if (!firstConfirm) return;

      const secondConfirm = window.confirm("Bu işlem geri alınmaz. Tüm bilgiler ve fotoğraf tamamen silinecek. Devam edilsin mi?");
      if (!secondConfirm) return;

      try {
        await deletePatient(Number(activePatient.id));
        window.location.replace("index.php");
      } catch (error) {
        window.alert(error.message);
      }
    });
  } catch (error) {
    detailContent.innerHTML = `<section class="panel-card"><p class="empty-state">${error.message}</p></section>`;
  }
}

init();
