"use client";

/**
 * CapacitorBootstrap — NATIVE sloj za BiznisPortal consumer aplikaciju.
 *
 * Komponenta vraća `null` i potpuno je INERTNA na web-u: sav native kod je
 * iza `Capacitor.isNativePlatform()` i dinamičkih `import()`-a, tako da
 * SSR / web build nikad ne učitava native plugin module.
 *
 * Šta radi (samo na native platformi):
 *  - skriva SplashScreen posle prvog paint-a
 *  - postavlja StatusBar stil + brend pozadinu
 *  - obrađuje Android hardversko BACK dugme (history.back ili minimize)
 *  - deep linkovi (appUrlOpen) → in-app ruta ili sistemski browser
 *  - eksterni linkovi (target=_blank / strani host) → in-app custom tab
 *  - registruje push (FCM), šalje token na /api/native/push/register
 *  - push tap → deep-link na ciljni URL + laka haptika
 *
 * Mount: u `app/layout.tsx` POSLE postojećih providera.
 */

import { useEffect } from "react";

const SITE_HOSTS = ["biznisportal.rs", "www.biznisportal.rs"];

function isInternalHost(host: string): boolean {
  const h = host.toLowerCase();
  // Host sa kog je sama aplikacija servirana je PO DEFINICIJI interni
  // (prod, localhost, ili emulator dev host poput 10.0.2.2). Bez ovoga su
  // se SVI interni linkovi otvarali u spoljnom Chrome Custom Tab-u.
  const servedHost =
    typeof window !== "undefined"
      ? window.location.hostname.toLowerCase()
      : "";
  return (
    h === servedHost ||
    SITE_HOSTS.includes(h) ||
    h.endsWith(".biznisportal.rs") ||
    h === "localhost" ||
    h === "127.0.0.1" ||
    h === "10.0.2.2" || // Android emulator (standardni AVD) → host
    h === "10.0.3.2" // Genymotion → host
  );
}

function pathFromUrl(raw: string): string | null {
  try {
    const u = new URL(raw);
    if (!isInternalHost(u.hostname)) return null;
    return `${u.pathname}${u.search}${u.hash}` || "/";
  } catch {
    return null;
  }
}

/**
 * Laka haptika (light impact). Bezbedno no-op na web-u / ako plugin fali.
 * Eksportovano za buduću upotrebu (npr. potvrde, tap-ovi).
 */
export async function nativeHaptic(): Promise<void> {
  try {
    const { Capacitor } = await import("@capacitor/core");
    if (!Capacitor.isNativePlatform()) return;
    const { Haptics, ImpactStyle } = await import("@capacitor/haptics");
    await Haptics.impact({ style: ImpactStyle.Light });
  } catch {
    /* no-op */
  }
}

export function CapacitorBootstrap() {
  useEffect(() => {
    let disposed = false;
    const cleanups: Array<() => void> = [];

    (async () => {
      let Capacitor: typeof import("@capacitor/core").Capacitor;
      try {
        ({ Capacitor } = await import("@capacitor/core"));
      } catch {
        return;
      }
      if (disposed || !Capacitor.isNativePlatform()) return;

      // ── SplashScreen: sakrij posle prvog paint-a ──────────────────────
      try {
        const { SplashScreen } = await import("@capacitor/splash-screen");
        const hide = () => SplashScreen.hide().catch(() => undefined);
        if (document.readyState === "complete") {
          setTimeout(hide, 250);
        } else {
          window.addEventListener("load", () => setTimeout(hide, 250), {
            once: true,
          });
        }
      } catch {
        /* no-op */
      }

      // ── StatusBar ─────────────────────────────────────────────────────
      try {
        const { StatusBar, Style } = await import("@capacitor/status-bar");
        await StatusBar.setOverlaysWebView({ overlay: false }).catch(
          () => undefined,
        );
        await StatusBar.setStyle({ style: Style.Dark }).catch(() => undefined);
        if (Capacitor.getPlatform() === "android") {
          await StatusBar.setBackgroundColor({ color: "#0c1828" }).catch(
            () => undefined,
          );
        }
      } catch {
        /* no-op */
      }

      // ── App: Android BACK dugme + deep linkovi ────────────────────────
      try {
        const { App } = await import("@capacitor/app");

        const backHandle = await App.addListener("backButton", () => {
          if (window.history.length > 1) {
            window.history.back();
          } else {
            // Ne zatvaraj naglo — minimizuj (UX kao native).
            App.minimizeApp().catch(() => undefined);
          }
        });
        cleanups.push(() => backHandle.remove().catch(() => undefined));

        const urlHandle = await App.addListener("appUrlOpen", async (event) => {
          const internalPath = pathFromUrl(event.url);
          if (internalPath) {
            window.location.assign(internalPath);
            return;
          }
          try {
            const { Browser } = await import("@capacitor/browser");
            await Browser.open({ url: event.url });
          } catch {
            window.open(event.url, "_blank");
          }
        });
        cleanups.push(() => urlHandle.remove().catch(() => undefined));
      } catch {
        /* no-op */
      }

      // ── Eksterni linkovi → in-app custom tab ──────────────────────────
      try {
        const onClick = async (e: MouseEvent) => {
          const target = e.target as HTMLElement | null;
          const anchor = target?.closest?.(
            "a[href]",
          ) as HTMLAnchorElement | null;
          if (!anchor) return;
          const href = anchor.getAttribute("href") || "";
          if (
            !href ||
            href.startsWith("#") ||
            href.startsWith("javascript:") ||
            href.startsWith("mailto:") ||
            href.startsWith("tel:")
          ) {
            return;
          }
          let url: URL;
          try {
            url = new URL(href, window.location.href);
          } catch {
            return;
          }
          if (url.protocol !== "http:" && url.protocol !== "https:") return;

          const external =
            !isInternalHost(url.hostname) ||
            anchor.target === "_blank";
          if (!external) return;
          // Interni _blank → samo navigiraj u webview-u (ne otvaraj browser).
          if (isInternalHost(url.hostname)) {
            e.preventDefault();
            window.location.assign(
              `${url.pathname}${url.search}${url.hash}` || "/",
            );
            return;
          }
          e.preventDefault();
          try {
            const { Browser } = await import("@capacitor/browser");
            await Browser.open({ url: url.toString() });
          } catch {
            window.open(url.toString(), "_blank");
          }
        };
        document.addEventListener("click", onClick, true);
        cleanups.push(() =>
          document.removeEventListener("click", onClick, true),
        );
      } catch {
        /* no-op */
      }

      // ── Network: offline banner (reuse postojeći OfflineToast) ────────
      // OfflineToast je već mountovan u app/layout.tsx i sluša
      // `navigator.onLine`. Native plugin samo dodatno emituje DOM evente
      // da bi se UI ažurirao i u edge slučajevima webview-a.
      try {
        const { Network } = await import("@capacitor/network");
        const netHandle = await Network.addListener(
          "networkStatusChange",
          (status) => {
            window.dispatchEvent(
              new Event(status.connected ? "online" : "offline"),
            );
          },
        );
        cleanups.push(() => netHandle.remove().catch(() => undefined));
      } catch {
        /* no-op */
      }

      // ── Push notifikacije (FCM na Androidu) ───────────────────────────
      // VAŽNO: @capacitor/push-notifications na Androidu zahteva Firebase.
      // Bez `android/app/google-services.json` poziv register()/permissions
      // baca Java IllegalStateException ("Default FirebaseApp is not
      // initialized") i RUŠI app na startu. Zato je ceo blok iza flega —
      // postavi NEXT_PUBLIC_PUSH_ENABLED="1" (build env) TEK kad dodaš
      // google-services.json + Firebase projekat.
      const PUSH_ENABLED = process.env.NEXT_PUBLIC_PUSH_ENABLED === "1";
      try {
        if (!PUSH_ENABLED) throw new Error("push-disabled-no-firebase");
        const { PushNotifications } = await import(
          "@capacitor/push-notifications"
        );

        const perm = await PushNotifications.checkPermissions();
        let receive = perm.receive;
        if (receive === "prompt" || receive === "prompt-with-rationale") {
          const { showRationale } = await import("@/lib/native/rationale");
          const ok = await showRationale({
            key: "push",
            title: "Ostani u toku",
            body: "Uključi obaveštenja za nove poruke, odgovore na recenzije i potvrde rezervacija. Možeš ih isključiti bilo kada.",
            confirm: "Uključi obaveštenja",
            cancel: "Ne sada",
          });
          if (ok) {
            receive = (await PushNotifications.requestPermissions()).receive;
          }
        }

        if (receive === "granted") {
          const regHandle = await PushNotifications.addListener(
            "registration",
            async (token) => {
              try {
                // Veži token za nalog (ako je ulogovan) da bi relevantni
                // push (sačuvane pretrage) mogao da se cilja po korisniku.
                let visitorAccountId: string | null = null;
                try {
                  const me = await fetch("/api/visitor-auth/me", {
                    cache: "no-store",
                  });
                  if (me.ok) {
                    const j = (await me.json()) as {
                      account: { id: string } | null;
                    };
                    visitorAccountId = j.account?.id ?? null;
                  }
                } catch {
                  /* anoniman token je i dalje ok */
                }
                await fetch("/api/native/push/register", {
                  method: "POST",
                  headers: { "content-type": "application/json" },
                  body: JSON.stringify({
                    token: token.value,
                    platform: Capacitor.getPlatform(),
                    provider:
                      Capacitor.getPlatform() === "ios" ? "APNS" : "FCM",
                    visitorAccountId,
                  }),
                  keepalive: true,
                }).catch(() => undefined);
              } catch {
                /* no-op */
              }
            },
          );
          cleanups.push(() => regHandle.remove().catch(() => undefined));

          const errHandle = await PushNotifications.addListener(
            "registrationError",
            () => {
              /* tihо — push nije kritičan */
            },
          );
          cleanups.push(() => errHandle.remove().catch(() => undefined));

          const tapHandle = await PushNotifications.addListener(
            "pushNotificationActionPerformed",
            async (action) => {
              await nativeHaptic();
              const data = (action.notification?.data || {}) as Record<
                string,
                unknown
              >;
              const url =
                typeof data.url === "string"
                  ? data.url
                  : typeof data.link === "string"
                    ? data.link
                    : "";
              if (!url) return;
              const internalPath = pathFromUrl(url) || pathFromUrl(
                new URL(url, window.location.origin).toString(),
              );
              if (internalPath) {
                window.location.assign(internalPath);
              } else {
                try {
                  const { Browser } = await import("@capacitor/browser");
                  await Browser.open({ url });
                } catch {
                  window.open(url, "_blank");
                }
              }
            },
          );
          cleanups.push(() => tapHandle.remove().catch(() => undefined));

          await PushNotifications.register().catch(() => undefined);
        }
      } catch {
        /* no-op — push nije dostupan dok Firebase nije podešen */
      }
    })();

    return () => {
      disposed = true;
      for (const fn of cleanups) {
        try {
          fn();
        } catch {
          /* no-op */
        }
      }
    };
  }, []);

  return null;
}

export default CapacitorBootstrap;
