"use client";

/**
 * AppPartnerReviews — native overlay za /portal/recenzije.
 *
 * Do sada partner svoje recenzije nije mogao ni da pročita: web `/portal/recenzije`
 * nudi samo link i formu za TRAŽENJE recenzija. Ovaj ekran zatvara tu rupu —
 * čitanje, filtriranje i javni odgovor vlasnika.
 */

import { usePathname } from "next/navigation";
import { useCallback, useEffect, useMemo, useState } from "react";

import { nativeHaptic } from "@/components/native/CapacitorBootstrap";
import { trackScreen } from "@/lib/native/analytics";
import { getLocalePrefix, type Locale } from "@/lib/i18n/i18n";
import { useAppVariant } from "@/lib/native/app-variant";
import { usePartnerPreview } from "@/lib/native/preview-partner";

type Reply = { body: string; authorName: string; createdAt: string };

type Review = {
  id: string;
  rating: number;
  title: string | null;
  content: string | null;
  authorName: string | null;
  status: "PENDING" | "APPROVED" | "REJECTED";
  createdAt: string;
  isVerifiedBooking: boolean;
  reply: Reply | null;
};

type Summary = {
  average: number | null;
  total: number;
  unanswered: number;
  pending: number;
};

type Payload = { summary: Summary; items: Review[] };

/** „Bez odgovora" je podrazumevano: to je jedini skup koji traži akciju. */
type Filter = "UNANSWERED" | "ALL" | "PENDING";

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

function isPath(p: string, prefix: string): boolean {
  const x = prefix && p.startsWith(prefix) ? p.slice(prefix.length) : p;
  return (x.replace(/\/+$/, "") || "/") === "/portal/recenzije";
}

function timeAgo(iso: string): string {
  const diff = Math.max(0, Date.now() - new Date(iso).getTime());
  const m = Math.floor(diff / 60000);
  if (m < 1) return "sad";
  if (m < 60) return `${m}m`;
  const h = Math.floor(m / 60);
  if (h < 24) return `${h}h`;
  return `${Math.floor(h / 24)}d`;
}

/** Zvezdice kao tekst bi se lomile i loše čitale — inline SVG je stabilan. */
function Stars({ rating, size = 14 }: { rating: number; size?: number }) {
  return (
    <span
      className="apprev-stars"
      role="img"
      aria-label={`${rating} od 5`}
      style={{ ["--star-size" as string]: `${size}px` }}
    >
      {[1, 2, 3, 4, 5].map((i) => (
        <svg
          key={i}
          width={size}
          height={size}
          viewBox="0 0 24 24"
          fill={i <= rating ? "currentColor" : "none"}
          stroke="currentColor"
          strokeWidth={1.6}
          strokeLinejoin="round"
          aria-hidden
          data-on={i <= rating ? "1" : "0"}
        >
          <path d="m12 3 2.6 5.6 6.1.8-4.5 4.2 1.2 6-5.4-3-5.4 3 1.2-6L3.3 9.4l6.1-.8z" />
        </svg>
      ))}
    </span>
  );
}

export function AppPartnerReviews({
  locale,
  dictionary,
}: {
  locale: Locale;
  dictionary: Record<string, string>;
}) {
  const native = useIsNative();
  const variant = useAppVariant();
  const preview = usePartnerPreview();
  const pathname = usePathname();
  const prefix = getLocalePrefix(locale);
  const active =
    (preview.enabled && preview.screen === "reviews") ||
    (isPath(pathname, prefix) && native === true && variant === "partner");

  const [data, setData] = useState<Payload | null>(null);
  const [filter, setFilter] = useState<Filter>("UNANSWERED");
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(false);
  const [expanded, setExpanded] = useState<string | null>(null);
  const [draft, setDraft] = useState("");
  const [busy, setBusy] = useState<string | null>(null);
  const [msg, setMsg] = useState<string | null>(null);

  // useCallback (a ne inline strelica kao na drugim ekranima) jer se `t`
  // koristi unutar `submitReply` — inače je zavisnost nestabilna.
  const t = useCallback(
    (k: string, fb: string) => dictionary[k] ?? fb,
    [dictionary],
  );

  const load = useCallback(async () => {
    setLoading(true);
    setError(false);
    try {
      const url = preview.enabled
        ? "/api/app/partner/demo?kind=reviews"
        : "/api/app/partner/reviews";
      const res = await fetch(url, { cache: "no-store" });
      if (res.status === 401 && !preview.enabled) {
        window.location.assign(`${prefix}/portal/login`);
        return;
      }
      if (!res.ok) {
        setError(true);
        return;
      }
      setData((await res.json()) as Payload);
    } catch {
      setError(true);
    } finally {
      setLoading(false);
    }
  }, [prefix, preview.enabled]);

  useEffect(() => {
    if (active) void load();
  }, [active, load]);

  useEffect(() => {
    if (active) trackScreen("partner_reviews");
  }, [active]);

  const submitReply = useCallback(
    async (id: string, body: string) => {
      setMsg(null);
      setBusy(id);
      try {
        if (preview.enabled) {
          await new Promise((r) => setTimeout(r, 450));
          setMsg(t("partner.rev.demo", "Demo: odgovor bi bio objavljen."));
          setExpanded(null);
          setDraft("");
          return;
        }
        const res = await fetch("/api/app/partner/reviews", {
          method: "POST",
          headers: { "content-type": "application/json" },
          body: JSON.stringify({ reviewId: id, body }),
        });
        const j = (await res.json().catch(() => null)) as { error?: string } | null;
        if (!res.ok) {
          setMsg(j?.error ?? t("partner.rev.err.save", "Greška pri slanju odgovora."));
          return;
        }
        setExpanded(null);
        setDraft("");
        await load();
      } catch {
        setMsg(t("partner.rev.err.save", "Greška pri slanju odgovora."));
      } finally {
        setBusy(null);
      }
    },
    [load, preview.enabled, t],
  );

  const visible = useMemo(() => {
    const items = data?.items ?? [];
    switch (filter) {
      case "UNANSWERED":
        return items.filter((r) => r.status === "APPROVED" && !r.reply);
      case "PENDING":
        return items.filter((r) => r.status === "PENDING");
      case "ALL":
      default:
        return items;
    }
  }, [data, filter]);

  if (!active) return null;

  const summary = data?.summary;
  const tabs: Array<{ key: Filter; label: string; count?: number }> = [
    {
      key: "UNANSWERED",
      label: t("partner.rev.tab.unanswered", "Bez odgovora"),
      count: summary?.unanswered,
    },
    { key: "ALL", label: t("partner.rev.tab.all", "Sve"), count: summary?.total },
    {
      key: "PENDING",
      label: t("partner.rev.tab.pending", "Na čekanju"),
      count: summary?.pending,
    },
  ];

  return (
    <div className="apppartner-root" role="region" aria-label="Recenzije">
      <div className="apppartner-hero apppartner-hero-compact">
        <div className="apppartner-hero-text">
          <p className="apppartner-kicker">{t("partner.rev.kicker", "Reputacija")}</p>
          <h1 className="apppartner-title">{t("partner.rev.title", "Recenzije")}</h1>
        </div>
      </div>

      {summary ? (
        <div className="apprev-summary">
          <div className="apprev-score">
            <span className="apprev-score-num">
              {summary.average !== null ? summary.average.toFixed(1) : "—"}
            </span>
            <Stars rating={Math.round(summary.average ?? 0)} size={13} />
            <span className="apprev-score-sub">
              {summary.total}{" "}
              {t("partner.rev.count", "recenzija")}
            </span>
          </div>
          {summary.unanswered > 0 ? (
            <button
              type="button"
              className="apprev-nudge"
              onClick={() => {
                void nativeHaptic();
                setFilter("UNANSWERED");
              }}
            >
              {summary.unanswered}{" "}
              {t("partner.rev.awaiting", "čeka tvoj odgovor")}
            </button>
          ) : (
            <span className="apprev-nudge apprev-nudge-done">
              {t("partner.rev.allAnswered", "Sve odgovoreno")}
            </span>
          )}
        </div>
      ) : null}

      <div className="apppartner-tabs" role="tablist">
        {tabs.map((tab) => (
          <button
            key={tab.key}
            type="button"
            role="tab"
            aria-selected={filter === tab.key}
            className="apppartner-tab"
            data-active={filter === tab.key ? "true" : "false"}
            onClick={() => {
              void nativeHaptic();
              setFilter(tab.key);
              setExpanded(null);
            }}
          >
            {tab.label}
            {tab.count ? ` · ${tab.count}` : ""}
          </button>
        ))}
      </div>

      <div className="apppartner-body">
        {loading && !data ? (
          <div className="apppartner-skel-grid" aria-hidden>
            {Array.from({ length: 4 }).map((_, i) => (
              <div key={i} className="apppartner-skel apppartner-skel-row" />
            ))}
          </div>
        ) : error ? (
          <div className="apppartner-empty">
            <p>{t("partner.rev.err", "Trenutno ne mogu da učitam recenzije.")}</p>
            <button
              type="button"
              className="apppartner-btn-primary"
              onClick={() => {
                void nativeHaptic();
                void load();
              }}
            >
              {t("common.retry", "Pokušaj ponovo")}
            </button>
          </div>
        ) : visible.length === 0 ? (
          <p className="apppartner-empty-line">
            {filter === "UNANSWERED"
              ? t("partner.rev.empty.unanswered", "Nema recenzija koje čekaju odgovor.")
              : t("partner.rev.empty", "Još nema recenzija u ovoj kategoriji.")}
          </p>
        ) : (
          <ul className="apppartner-list">
            {visible.map((r) => {
              const isOpen = expanded === r.id;
              // Odgovor ima smisla samo na JAVNOJ recenziji — PENDING još nije
              // vidljiva posetiocima.
              const canReply = r.status === "APPROVED";
              return (
                <li key={r.id} className="apppartner-list-item">
                  <div
                    className="apppartner-list-link"
                    role="button"
                    tabIndex={0}
                    onClick={() => {
                      if (!canReply) return;
                      void nativeHaptic();
                      setExpanded(isOpen ? null : r.id);
                      setDraft(r.reply?.body ?? "");
                      setMsg(null);
                    }}
                    onKeyDown={(e) => {
                      if (!canReply) return;
                      if (e.key === "Enter" || e.key === " ") {
                        e.preventDefault();
                        setExpanded(isOpen ? null : r.id);
                        setDraft(r.reply?.body ?? "");
                      }
                    }}
                  >
                    <div className="apppartner-list-row">
                      <span className="apppartner-list-title">
                        {r.authorName || t("partner.rev.anon", "Anoniman")}
                      </span>
                      {r.status === "PENDING" ? (
                        <span className="apppartner-pill apppartner-pill-new">
                          {t("partner.rev.tab.pending", "Na čekanju")}
                        </span>
                      ) : !r.reply ? (
                        <span className="apppartner-pill apppartner-pill-new">
                          {t("partner.rev.needsReply", "Bez odgovora")}
                        </span>
                      ) : (
                        <span className="apppartner-pill apppartner-pill-good">
                          {t("partner.rev.answered", "Odgovoreno")}
                        </span>
                      )}
                    </div>

                    <div className="apprev-rating-row">
                      <Stars rating={r.rating} />
                      {r.isVerifiedBooking ? (
                        <span className="apprev-verified">
                          ✓ {t("partner.rev.verified", "Potvrđena poseta")}
                        </span>
                      ) : null}
                    </div>

                    {r.title ? <p className="apprev-title">{r.title}</p> : null}
                    {r.content ? (
                      <p className="apppartner-list-msg">{r.content}</p>
                    ) : null}

                    {r.reply ? (
                      <p className="apppartner-list-answer">↳ {r.reply.body}</p>
                    ) : null}

                    <div className="apppartner-list-meta">
                      <span>{timeAgo(r.createdAt)}</span>
                      {canReply ? (
                        <span>
                          ·{" "}
                          {r.reply
                            ? t("partner.rev.edit", "Izmeni odgovor")
                            : t("partner.rev.reply", "Odgovori")}
                        </span>
                      ) : null}
                    </div>

                    {isOpen && canReply ? (
                      <div className="apppartner-form" onClick={(e) => e.stopPropagation()}>
                        <label className="apppartner-label" htmlFor={`rev-${r.id}`}>
                          {t("partner.rev.reply.label", "Javni odgovor vlasnika")}
                        </label>
                        <textarea
                          id={`rev-${r.id}`}
                          className="apppartner-input apppartner-textarea"
                          rows={3}
                          maxLength={2000}
                          value={draft}
                          onChange={(e) => setDraft(e.target.value)}
                          placeholder={t(
                            "partner.rev.reply.placeholder",
                            "Zahvali se, odgovori konkretno i ponudi rešenje — odgovor vidi svaki budući posetilac.",
                          )}
                        />
                        <div className="apppartner-form-actions">
                          <button
                            type="button"
                            className="apppartner-btn-primary apppartner-btn-block"
                            disabled={busy === r.id || draft.trim().length < 3}
                            onClick={() => {
                              void nativeHaptic();
                              void submitReply(r.id, draft.trim());
                            }}
                          >
                            {busy === r.id
                              ? t("partner.rev.sending", "Šaljem…")
                              : r.reply
                                ? t("partner.rev.update", "Sačuvaj izmenu")
                                : t("partner.rev.publish", "Objavi odgovor")}
                          </button>
                        </div>
                        {msg ? <p className="apppartner-form-msg">{msg}</p> : null}
                      </div>
                    ) : null}
                  </div>
                </li>
              );
            })}
          </ul>
        )}
      </div>
    </div>
  );
}

export default AppPartnerReviews;
