"use client";

import { useEffect, useRef } from "react";
import { usePathname, useSearchParams } from "next/navigation";

const NOTICE_ID = "admin-inline-save-feedback";
const FLOATING_NOTICE_ID = "admin-floating-save-feedback";

function findPrimarySubmitButton(form?: HTMLFormElement | null) {
  if (!form) {
    return null;
  }

  return form.querySelector<HTMLButtonElement>(
    'button[type="submit"].primary-button, button[type="submit"], input[type="submit"]',
  );
}

function ensureNotice(target: Element, message: string, tone: "pending" | "success") {
  const parent = target.parentElement ?? target;
  let notice = parent.querySelector<HTMLSpanElement>(`[data-admin-save-feedback="${NOTICE_ID}"]`);

  if (!notice) {
    notice = document.createElement("span");
    notice.dataset.adminSaveFeedback = NOTICE_ID;
    notice.setAttribute("role", "status");
    notice.setAttribute("aria-live", "polite");
    notice.className =
      "inline-flex min-h-10 items-center rounded-full border px-4 text-sm font-semibold shadow-[0_12px_35px_rgba(22,22,22,0.08)] transition";
    target.insertAdjacentElement("afterend", notice);
  }

  notice.textContent = message;
  notice.dataset.tone = tone;
  notice.classList.toggle("border-secondary/20", tone === "pending");
  notice.classList.toggle("bg-secondary/10", tone === "pending");
  notice.classList.toggle("text-secondary", tone === "pending");
  notice.classList.toggle("border-emerald-500/20", tone === "success");
  notice.classList.toggle("bg-emerald-50", tone === "success");
  notice.classList.toggle("text-emerald-700", tone === "success");

  return notice;
}

function ensureFloatingNotice(message: string, tone: "pending" | "success") {
  let notice = document.querySelector<HTMLDivElement>(`[data-admin-floating-feedback="${FLOATING_NOTICE_ID}"]`);

  if (!notice) {
    notice = document.createElement("div");
    notice.dataset.adminFloatingFeedback = FLOATING_NOTICE_ID;
    notice.setAttribute("role", "status");
    notice.setAttribute("aria-live", "polite");
    notice.className =
      "pointer-events-none fixed right-5 top-5 z-[120] flex min-h-14 min-w-[260px] max-w-[420px] items-center rounded-[1.35rem] border px-5 py-3 text-sm font-semibold shadow-[0_22px_55px_rgba(12,24,40,0.16)] backdrop-blur-xl transition-all duration-300";
    document.body.appendChild(notice);
  }

  notice.textContent = message;
  notice.dataset.tone = tone;
  notice.classList.toggle("border-secondary/20", tone === "pending");
  notice.classList.toggle("bg-secondary/92", tone === "pending");
  notice.classList.toggle("text-white", tone === "pending");
  notice.classList.toggle("border-emerald-500/22", tone === "success");
  notice.classList.toggle("bg-emerald-50/96", tone === "success");
  notice.classList.toggle("text-emerald-800", tone === "success");
  notice.classList.toggle("translate-y-0", true);
  notice.classList.toggle("opacity-100", true);

  return notice;
}

function clearPendingNotices() {
  document
    .querySelectorAll<HTMLElement>(`[data-admin-save-feedback="${NOTICE_ID}"]`)
    .forEach((node) => {
      if (node.dataset.tone === "pending") {
        node.remove();
      }
    });

  const floating = document.querySelector<HTMLElement>(
    `[data-admin-floating-feedback="${FLOATING_NOTICE_ID}"]`,
  );
  if (floating && floating.dataset.tone === "pending") {
    floating.remove();
  }
}

export function AdminFormFeedback() {
  const pathname = usePathname();
  const searchParams = useSearchParams();
  const hideTimeoutRef = useRef<number | null>(null);
  const safetyTimeoutRef = useRef<number | null>(null);

  useEffect(() => {
    function handleSubmit(event: SubmitEvent) {
      const form = event.target instanceof HTMLFormElement ? event.target : null;
      const submitter =
        event.submitter instanceof Element ? event.submitter : findPrimarySubmitButton(form);

      if (!form || !submitter) {
        return;
      }

      if (!form.closest(".admin-shell")) {
        return;
      }

      ensureNotice(submitter, "Čuvanje promena...", "pending");
      ensureFloatingNotice("Čuvanje promena...", "pending");
      sessionStorage.setItem("admin-last-save-path", window.location.pathname);

      // Sigurnosni ventil: ako akcija nikad ne razreši (mrežni prekid,
      // greška bez navigacije, ugnežđena forma...) ne ostavljaj spinner
      // "Čuvanje promena..." da visi zauvek — skloni ga posle 12s.
      if (safetyTimeoutRef.current) {
        window.clearTimeout(safetyTimeoutRef.current);
      }
      safetyTimeoutRef.current = window.setTimeout(clearPendingNotices, 12000);
    }

    document.addEventListener("submit", handleSubmit, true);

    return () => {
      document.removeEventListener("submit", handleSubmit, true);
      if (safetyTimeoutRef.current) {
        window.clearTimeout(safetyTimeoutRef.current);
      }
    };
  }, []);

  // Kada se navigacija završi (promena rute) bez `?saved=1` — npr. posle
  // brisanja koje redirect-uje na listu — uspešni "saved" tok se ne pokreće,
  // pa eksplicitno sklanjamo zaostali "Čuvanje promena..." indikator.
  useEffect(() => {
    const saved = searchParams.get("saved");
    if (saved === "1" || saved === "true") {
      return;
    }
    clearPendingNotices();
  }, [pathname, searchParams]);

  useEffect(() => {
    const saved = searchParams.get("saved");
    const shouldShowSaved = saved === "1" || saved === "true";

    if (!shouldShowSaved) {
      return;
    }

    const forms = Array.from(document.querySelectorAll<HTMLFormElement>(".admin-shell form"));
    const form = forms.find((candidate) => candidate.querySelector(".primary-button")) ?? forms[0];
    const button = findPrimarySubmitButton(form);

    if (!button) {
      return;
    }

    const notice = ensureNotice(button, "Promene su sačuvane.", "success");
    const floatingNotice = ensureFloatingNotice("Promene su sačuvane.", "success");

    const nextUrl = new URL(window.location.href);
    nextUrl.searchParams.delete("saved");
    window.history.replaceState({}, "", nextUrl.toString());

    if (hideTimeoutRef.current) {
      window.clearTimeout(hideTimeoutRef.current);
    }

    const timeout = window.setTimeout(() => {
      notice.remove();
      floatingNotice.remove();
    }, 6500);

    hideTimeoutRef.current = timeout;

    return () => {
      window.clearTimeout(timeout);
    };
  }, [pathname, searchParams]);

  return null;
}
