"use client";

/**
 * AppFinder — NATIVE-FIRST "Company Finder" ekran.
 *
 * Renderuje se SAMO u Capacitor native ljusci I kada je ruta finder ruta
 * (`/pretraga`, `/kompanije` + locale varijante). Pokriva web listu punim
 * fixed slojem (isti overlay pristup kao AppHome — između native top bara
 * i bottom tab bara). Na web-u vraća `null` pre bilo kakvog markup-a →
 * web ostaje bajt-identičan.
 *
 * Podatke vuče iz read-only `/api/app/search` (wrap nad
 * `listPublicDirectory()`). Query (`q`, `kategorija`, `grad`,
 * `lat/lng/near`) se parsira iz URL-a (deep linkovi iz AppHome rade),
 * a izmene se drže u URL-u preko `router.replace(scroll:false)` da
 * back radi prirodno.
 */

import Link from "next/link";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { useCallback, useEffect, useRef, useState } from "react";

import { nativeHaptic } from "@/components/native/CapacitorBootstrap";
import { NativeTierBadge } from "@/components/native/NativeTierBadge";
import { trackScreen } from "@/lib/native/analytics";
import { getNativeCoords } from "@/lib/native/geo";
import { getLocalePrefix, type Locale } from "@/lib/i18n/i18n";

type SlimCompany = {
  id: string;
  name: string;
  slug: string;
  type: "company" | "place";
  logoUrl: string | null;
  city: string;
  category: string;
  rating: number;
  reviewCount: number;
  isVerified: boolean;
  phone: string | null;
  tier?: string | null;
};

type Facet = { name: string; slug: string; count: number };

type SearchPayload = {
  items: SlimCompany[];
  page: number;
  hasMore: boolean;
  nextPage: number | null;
  facets: { categories: Facet[]; cities: Facet[] };
};

function useIsNative(): boolean | null {
  const [native, setNative] = useState<boolean | null>(null);
  useEffect(() => {
    let disposed = false;
    (async () => {
      try {
        const { Capacitor } = await import("@capacitor/core");
        if (!disposed) setNative(Capacitor.isNativePlatform());
      } catch {
        if (!disposed) setNative(false);
      }
    })();
    return () => {
      disposed = true;
    };
  }, []);
  return native;
}

function finderKind(
  pathname: string,
  prefix: string,
): "company" | "place" | null {
  const path =
    prefix && pathname.startsWith(prefix)
      ? pathname.slice(prefix.length)
      : pathname;
  const norm = path.replace(/\/+$/, "") || "/";
  if (norm === "/pretraga" || norm === "/kompanije") return "company";
  if (norm === "/mesta") return "place";
  return null;
}

function Avatar({ name, logoUrl }: { name: string; logoUrl: string | null }) {
  if (logoUrl) {
    return (
      // eslint-disable-next-line @next/next/no-img-element
      <img src={logoUrl} alt="" className="appfinder-logo" loading="lazy" />
    );
  }
  return (
    <span className="appfinder-logo appfinder-logo-fallback" aria-hidden>
      {name.trim().charAt(0).toUpperCase() || "?"}
    </span>
  );
}

export function AppFinder({
  locale,
  dictionary,
}: {
  locale: Locale;
  dictionary: Record<string, string>;
}) {
  const native = useIsNative();
  const pathname = usePathname();
  const router = useRouter();
  const searchParams = useSearchParams();
  const prefix = getLocalePrefix(locale);
  const kind = finderKind(pathname, prefix);
  const active = kind !== null;

  const t = (k: string, fallback: string) => dictionary[k] ?? fallback;

  // URL → početno stanje (deep linkovi iz AppHome).
  const urlQ = searchParams.get("q") ?? "";
  const urlCat = searchParams.get("kategorija") ?? "";
  const urlGrad = searchParams.get("grad") ?? searchParams.get("city") ?? "";
  const urlNear =
    searchParams.get("near") === "1" || searchParams.get("near") === "true";
  const urlLat = searchParams.get("lat");
  const urlLng = searchParams.get("lng");

  const [q, setQ] = useState(urlQ);
  const [category, setCategory] = useState(urlCat);
  const [verifiedOnly, setVerifiedOnly] = useState(false);
  const [nearMe, setNearMe] = useState(urlNear);
  const [coords, setCoords] = useState<{ lat: number; lng: number } | null>(
    urlNear && urlLat && urlLng
      ? { lat: Number(urlLat), lng: Number(urlLng) }
      : null,
  );

  const [items, setItems] = useState<SlimCompany[]>([]);
  const [facets, setFacets] = useState<Facet[]>([]);
  const [page, setPage] = useState(1);
  const [hasMore, setHasMore] = useState(false);
  const [loading, setLoading] = useState(false);
  const [loadingMore, setLoadingMore] = useState(false);
  const [error, setError] = useState(false);

  // Debounced search term.
  const [debouncedQ, setDebouncedQ] = useState(urlQ);
  useEffect(() => {
    const id = setTimeout(() => setDebouncedQ(q), 250);
    return () => clearTimeout(id);
  }, [q]);

  // Sync stanja → URL (back dugme radi prirodno).
  useEffect(() => {
    if (native !== true || !active) return;
    const sp = new URLSearchParams();
    if (debouncedQ) sp.set("q", debouncedQ);
    if (category) sp.set("kategorija", category);
    if (urlGrad) sp.set("grad", urlGrad);
    if (verifiedOnly) sp.set("verified", "1");
    if (nearMe && coords) {
      sp.set("near", "1");
      sp.set("lat", String(coords.lat));
      sp.set("lng", String(coords.lng));
    }
    const qs = sp.toString();
    router.replace(`${pathname}${qs ? `?${qs}` : ""}`, { scroll: false });
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [debouncedQ, category, verifiedOnly, nearMe, coords]);

  const buildUrl = useCallback(
    (p: number) => {
      const sp = new URLSearchParams();
      if (debouncedQ) sp.set("q", debouncedQ);
      if (category) sp.set("kategorija", category);
      if (urlGrad) sp.set("grad", urlGrad);
      if (verifiedOnly) sp.set("verified", "1");
      if (nearMe && coords) {
        sp.set("near", "1");
        sp.set("lat", String(coords.lat));
        sp.set("lng", String(coords.lng));
      }
      if (kind === "place") sp.set("type", "PLACE");
      sp.set("page", String(p));
      return `/api/app/search?${sp.toString()}`;
    },
    [debouncedQ, category, urlGrad, verifiedOnly, nearMe, coords, kind],
  );

  const reqRef = useRef(0);

  // Fetch (resetuje listu) kad se promene kriterijumi.
  useEffect(() => {
    if (native !== true || !active) return;
    const reqId = ++reqRef.current;
    setLoading(true);
    setError(false);
    (async () => {
      try {
        const res = await fetch(buildUrl(1), { cache: "no-store" });
        if (reqId !== reqRef.current) return;
        if (!res.ok) {
          setError(true);
          return;
        }
        const j = (await res.json()) as SearchPayload;
        if (reqId !== reqRef.current) return;
        setItems(j.items);
        setFacets(j.facets?.categories ?? []);
        setPage(1);
        setHasMore(j.hasMore);
      } catch {
        if (reqId === reqRef.current) setError(true);
      } finally {
        if (reqId === reqRef.current) setLoading(false);
      }
    })();
  }, [native, active, buildUrl]);

  const loadMore = async () => {
    if (loadingMore || !hasMore) return;
    void nativeHaptic();
    setLoadingMore(true);
    const next = page + 1;
    try {
      const res = await fetch(buildUrl(next), { cache: "no-store" });
      if (res.ok) {
        const j = (await res.json()) as SearchPayload;
        setItems((prev) => [...prev, ...j.items]);
        setPage(next);
        setHasMore(j.hasMore);
      }
    } catch {
      /* no-op — ostaje prethodna lista */
    } finally {
      setLoadingMore(false);
    }
  };

  const onToggleNear = async () => {
    void nativeHaptic();
    if (nearMe) {
      setNearMe(false);
      return;
    }
    const c = coords ?? (await getNativeCoords());
    if (!c) return;
    setCoords(c);
    setNearMe(true);
  };

  const onPickCategory = (slug: string) => {
    void nativeHaptic();
    setCategory((prev) => (prev === slug ? "" : slug));
  };

  useEffect(() => {
    if (native === true && active) {
      trackScreen(kind === "place" ? "finder_places" : "finder");
    }
  }, [native, active, kind]);

  if (native !== true || !active) return null;

  return (
    <div className="appfinder-root" role="region" aria-label="BiznisPortal">
      <div className="appfinder-header">
        <div className="appfinder-searchbox">
          <svg
            width={20}
            height={20}
            viewBox="0 0 24 24"
            fill="none"
            stroke="currentColor"
            strokeWidth={2}
            strokeLinecap="round"
            aria-hidden
          >
            <circle cx="11" cy="11" r="7" />
            <path d="m20 20-3.5-3.5" />
          </svg>
          <input
            className="appfinder-input"
            type="search"
            inputMode="search"
            value={q}
            onChange={(e) => setQ(e.target.value)}
            placeholder={t(
              "app.finder.searchPlaceholder",
              "Pretraži firme, usluge…",
            )}
            aria-label={t(
              "app.finder.searchPlaceholder",
              "Pretraži firme, usluge…",
            )}
          />
          {q ? (
            <button
              type="button"
              className="appfinder-clear"
              aria-label={t("app.finder.clear", "Obriši")}
              onClick={() => {
                void nativeHaptic();
                setQ("");
              }}
            >
              ✕
            </button>
          ) : null}
        </div>

        <div className="appfinder-chips">
          <button
            type="button"
            className="appfinder-chip"
            data-on={!category ? "1" : "0"}
            onClick={() => onPickCategory("")}
          >
            {t("app.finder.all", "Sve")}
          </button>
          <button
            type="button"
            className="appfinder-chip"
            data-on={nearMe ? "1" : "0"}
            onClick={() => void onToggleNear()}
          >
            ◎ {t("app.finder.nearMe", "U mojoj blizini")}
          </button>
          <button
            type="button"
            className="appfinder-chip"
            data-on={verifiedOnly ? "1" : "0"}
            onClick={() => {
              void nativeHaptic();
              setVerifiedOnly((v) => !v);
            }}
          >
            ✓ {t("app.finder.verifiedOnly", "Verifikovani")}
          </button>
          {facets.map((f) => (
            <button
              key={f.slug}
              type="button"
              className="appfinder-chip"
              data-on={category === f.slug ? "1" : "0"}
              onClick={() => onPickCategory(f.slug)}
            >
              {f.name}
            </button>
          ))}
        </div>
      </div>

      <div className="appfinder-body">
        {nearMe && coords ? (
          <p className="appfinder-near">
            ◎ {t("app.finder.nearLabel", "u tvojoj blizini")}
          </p>
        ) : null}

        {loading ? (
          <div className="appfinder-skel-list" aria-hidden>
            {Array.from({ length: 6 }).map((_, i) => (
              <div key={i} className="appfinder-skel" />
            ))}
          </div>
        ) : error ? (
          <div className="appfinder-state">
            <p>{t("app.finder.error", "Nešto je pošlo po zlu.")}</p>
            <button
              type="button"
              className="appfinder-retry"
              onClick={() => {
                void nativeHaptic();
                // re-trigger fetch
                setDebouncedQ((v) => `${v}`);
                reqRef.current++;
                setQ((v) => v);
              }}
            >
              {t("app.finder.retry", "Pokušaj ponovo")}
            </button>
          </div>
        ) : items.length === 0 ? (
          <p className="appfinder-empty">
            {t(
              "app.finder.empty",
              "Nema rezultata — probaj drugu reč ili kategoriju",
            )}
          </p>
        ) : (
          <>
            <ul className="appfinder-list">
              {items.map((c) => {
                const base = c.type === "place" ? "mesta" : "kompanije";
                return (
                  <li key={c.id}>
                    <Link
                      href={`${prefix}/${base}/${c.slug}`}
                      className="appfinder-card"
                      data-tier={c.tier ?? "STANDARD"}
                      onClick={() => void nativeHaptic()}
                    >
                      <Avatar name={c.name} logoUrl={c.logoUrl} />
                      <div className="appfinder-card-main">
                        <span className="appfinder-card-name">
                          {c.name}
                          {c.isVerified ? (
                            <span className="appfinder-verified" aria-hidden>
                              ✓
                            </span>
                          ) : null}
                        </span>
                        <NativeTierBadge tier={c.tier} />
                        <span className="appfinder-card-meta">
                          {[c.category, c.city].filter(Boolean).join(" · ") ||
                            " "}
                        </span>
                        <span className="appfinder-card-rating">
                          {c.reviewCount > 0
                            ? `★ ${c.rating.toFixed(1)} · ${c.reviewCount}`
                            : t("app.finder.new", "Novo")}
                        </span>
                      </div>
                      {c.phone ? (
                        <button
                          type="button"
                          className="appfinder-call"
                          aria-label={t("app.finder.call", "Pozovi")}
                          onClick={(e) => {
                            e.stopPropagation();
                            e.preventDefault();
                            void nativeHaptic();
                            window.location.href = `tel:${c.phone}`;
                          }}
                        >
                          <svg
                            width={18}
                            height={18}
                            viewBox="0 0 24 24"
                            fill="none"
                            stroke="currentColor"
                            strokeWidth={2}
                            strokeLinecap="round"
                            strokeLinejoin="round"
                            aria-hidden
                          >
                            <path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.13.96.36 1.9.7 2.8a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.9.34 1.85.57 2.8.7A2 2 0 0 1 22 16.92Z" />
                          </svg>
                        </button>
                      ) : null}
                    </Link>
                  </li>
                );
              })}
            </ul>
            {hasMore ? (
              <button
                type="button"
                className="appfinder-more"
                onClick={() => void loadMore()}
                disabled={loadingMore}
              >
                {loadingMore
                  ? "…"
                  : t("app.finder.loadMore", "Učitaj još")}
              </button>
            ) : null}
          </>
        )}
      </div>
    </div>
  );
}

export default AppFinder;
