"use client";
import { useCallback, useEffect, useRef, useState } from "react";
import Link from "next/link";
import {
  ArrowLeft,
  ArrowRight,
  AtSign,
  Bot,
  Check,
  CheckCheck,
  Contact,
  FileText,
  Globe2,
  Inbox,
  Languages,
  MessageCircle,
  MoreHorizontal,
  Plus,
  RefreshCw,
  Search,
  Send,
  ShieldAlert,
  Tag,
  UserRound,
  X,
  Zap,
} from "lucide-react";
import { toast, Toaster } from "sonner";
type Row = Record<string, unknown>;
type Data = {
  workspace: Row;
  permissions: string[];
  user: { id: string; name: string };
  conversations: Row[];
  counts: Row;
  channels: Row[];
  members: Row[];
  agents: Row[];
  savedReplies: Row[];
  detail: null | {
    conversation: Row;
    messages: Row[];
    notes: Row[];
    contact: Row | null;
    leads: Row[];
    tasks: Row[];
    assignments: Row[];
  };
};
const text = {
  ar: {
    inbox: "صندوق المحادثات",
    subtitle: "كل محادثات العملاء في مكان واحد",
    search: "ابحث بالاسم أو الرسالة أو رقم التواصل",
    all: "الكل",
    mine: "محادثاتي",
    unassigned: "غير معيّنة",
    handoff: "تحتاج موظفًا",
    unread: "غير مقروءة",
    resolved: "تم حلها",
    empty: "لا توجد محادثات في هذا المسار",
    emptyHelp: "عند وصول رسالة من قناة متصلة ستظهر هنا تلقائيًا.",
    openChannels: "إدارة القنوات",
    select: "اختر محادثة لعرضها",
    take: "استلام المحادثة",
    returnAi: "إعادة إلى AI",
    reply: "رد للعميل",
    note: "ملاحظة داخلية",
    placeholder: "اكتب ردًا للعميل…",
    notePlaceholder: "اكتب ملاحظة لا يراها العميل…",
    send: "إرسال",
    aiDraft: "اقتراح رد",
    draftNotice: "مسودة فقط — راجعها قبل الإرسال",
    customer: "ملف العميل",
    owner: "المسؤول",
    priority: "الأولوية",
    state: "الحالة",
    unknown: "غير مسجل",
    createLead: "إنشاء Lead",
    createTask: "إنشاء مهمة",
    activity: "السجل",
    noMessages: "لا توجد رسائل محفوظة بعد",
    channelUnavailable:
      "الإرسال غير متاح لهذه القناة حتى يكتمل تكاملها الفعلي.",
    takeFirst: "استلم المحادثة قبل الرد.",
    back: "العودة",
    filters: "التصفية",
    normal: "عادية",
    high: "عالية",
    urgent: "عاجلة",
    low: "منخفضة",
    resolve: "حل المحادثة",
    reopen: "إعادة فتح",
    loading: "جارٍ تحميل المحادثات…",
  },
  en: {
    inbox: "Unified inbox",
    subtitle: "Every customer conversation in one place",
    search: "Search names, messages, email or phone",
    all: "All",
    mine: "My conversations",
    unassigned: "Unassigned",
    handoff: "Needs a human",
    unread: "Unread",
    resolved: "Resolved",
    empty: "No conversations in this queue",
    emptyHelp: "New messages from connected channels will appear here.",
    openChannels: "Manage channels",
    select: "Select a conversation to open it",
    take: "Take conversation",
    returnAi: "Return to AI",
    reply: "Customer reply",
    note: "Internal note",
    placeholder: "Write a reply…",
    notePlaceholder: "Write a note the customer cannot see…",
    send: "Send",
    aiDraft: "Suggest reply",
    draftNotice: "Draft only — review before sending",
    customer: "Customer profile",
    owner: "Owner",
    priority: "Priority",
    state: "Status",
    unknown: "Not recorded",
    createLead: "Create lead",
    createTask: "Create task",
    activity: "Activity",
    noMessages: "No stored messages yet",
    channelUnavailable:
      "Delivery is unavailable until this channel has a verified integration.",
    takeFirst: "Take this conversation before replying.",
    back: "Back",
    filters: "Filters",
    normal: "Normal",
    high: "High",
    urgent: "Urgent",
    low: "Low",
    resolve: "Resolve",
    reopen: "Reopen",
    loading: "Loading conversations…",
  },
};
export default function InboxCenter({
  initialId,
  initialQueue,
}: {
  initialId?: string;
  initialQueue?: string;
}) {
  const [lang, setLang] = useState<"ar" | "en">("ar"),
    [queue, setQueue] = useState(
      ["all", "mine", "unassigned", "handoff", "unread", "resolved"].includes(
        initialQueue || "",
      )
        ? initialQueue!
        : "all",
    ),
    [q, setQ] = useState(""),
    [channel, setChannel] = useState("all"),
    [priority, setPriority] = useState("all"),
    [selected, setSelected] = useState(initialId || ""),
    [data, setData] = useState<Data | null>(null),
    [loading, setLoading] = useState(true),
    [error, setError] = useState(""),
    [tab, setTab] = useState<"reply" | "note">("reply"),
    [body, setBody] = useState(""),
    [busy, setBusy] = useState(false),
    [showCustomer, setShowCustomer] = useState(false),
    [showFilters, setShowFilters] = useState(false);
  const poll = useRef<number | undefined>(undefined);
  const t = text[lang];
  const load = useCallback(
    async (silent = false) => {
      if (!silent) setLoading(true);
      try {
        const p = new URLSearchParams({ queue, channel, priority });
        if (q) p.set("q", q);
        if (selected) p.set("id", selected);
        const r = await fetch(`/api/inbox?${p}`, { cache: "no-store" });
        const j = (await r.json()) as Data & { error?: string };
        if (!r.ok) throw new Error(j.error || "load_failed");
        setData(j);
        setError("");
      } catch (e) {
        setError(e instanceof Error ? e.message : "load_failed");
      } finally {
        if (!silent) setLoading(false);
      }
    },
    [queue, q, channel, priority, selected],
  );
  useEffect(() => {
    const id = window.setTimeout(() => void load(), q ? 250 : 0);
    return () => window.clearTimeout(id);
  }, [load, q]);
  useEffect(() => {
    const start = () => {
      window.clearInterval(poll.current);
      poll.current = window.setInterval(() => {
        if (document.visibilityState === "visible") void load(true);
      }, 12000);
    };
    start();
    document.addEventListener("visibilitychange", start);
    return () => {
      window.clearInterval(poll.current);
      document.removeEventListener("visibilitychange", start);
    };
  }, [load]);
  const post = async (payload: Row) => {
    setBusy(true);
    try {
      const r = await fetch("/api/inbox", {
        method: "POST",
        headers: { "content-type": "application/json" },
        body: JSON.stringify(payload),
      });
      const j = (await r.json()) as Row;
      if (!r.ok) throw new Error(String(j.error || "action_failed"));
      await load(true);
      return j;
    } catch (e) {
      const code = e instanceof Error ? e.message : "action_failed";
      toast.error(
        code === "assignment_conflict"
          ? lang === "ar"
            ? "استلم موظف آخر المحادثة. تم تحديث الحالة."
            : "Another teammate already took it. State refreshed."
          : lang === "ar"
            ? "تعذر إكمال الإجراء."
            : "Action could not be completed",
      );
      await load(true);
      throw e;
    } finally {
      setBusy(false);
    }
  };
  const choose = (id: string) => {
    setSelected(id);
    setShowCustomer(false);
    window.history.pushState({}, "", `/inbox/${id}`);
  };
  const close = () => {
    setSelected("");
    setShowCustomer(false);
    window.history.pushState({}, "", "/inbox");
  };
  const detail = data?.detail,
    c = detail?.conversation,
    myTurn = c?.owner_mode === "human" && c?.assigned_user_id === data?.user.id,
    web = String(c?.channel || "").toLowerCase(),
    canSend =
      myTurn &&
      ["webchat", "web chat", "الموقع"].includes(web) &&
      c?.state !== "resolved";
  const queues = [
    "all",
    "mine",
    "unassigned",
    "handoff",
    "unread",
    "resolved",
  ] as const;
  const qlabel: Record<string, string> = {
    all: t.all,
    mine: t.mine,
    unassigned: t.unassigned,
    handoff: t.handoff,
    unread: t.unread,
    resolved: t.resolved,
  };
  const count = (k: string) =>
    Number(data?.counts?.[k] ?? (k === "all" ? data?.counts?.total : 0) ?? 0);
  const title = c ? String(c.customer_name) : "";
  return (
    <main className="nx-inbox" dir={lang === "ar" ? "rtl" : "ltr"}>
      <Toaster richColors position={lang === "ar" ? "top-left" : "top-right"} />
      <header className="nx-inbox-head">
        <a href="/dashboard" className="brand">
          <span>
            <Zap />
          </span>
          <b>
            NEXORA <em>AI</em>
          </b>
        </a>
        <div>
          <h1>{t.inbox}</h1>
          <p>{t.subtitle}</p>
        </div>
        <button
          className="lang"
          onClick={() => setLang(lang === "ar" ? "en" : "ar")}
        >
          <Languages />
          {lang === "ar" ? "EN" : "ع"}
        </button>
      </header>
      <section
        className={`inbox-shell ${selected ? "has-selection" : ""} ${showCustomer ? "show-customer" : ""}`}
      >
        <aside className="thread-pane">
          <div className="thread-tools">
            <label>
              <Search />
              <input
                value={q}
                onChange={(e) => setQ(e.target.value)}
                placeholder={t.search}
              />
            </label>
            <button
              aria-label={t.filters}
              onClick={() => setShowFilters(!showFilters)}
            >
              <MoreHorizontal />
            </button>
          </div>
          <nav className="queues" aria-label={t.filters}>
            {queues.map((k) => (
              <button
                className={queue === k ? "active" : ""}
                onClick={() => setQueue(k)}
                key={k}
              >
                {qlabel[k]}
                <b>{count(k)}</b>
              </button>
            ))}
          </nav>
          {showFilters && (
            <div className="extra-filters">
              <select
                aria-label="Channel"
                value={channel}
                onChange={(e) => setChannel(e.target.value)}
              >
                <option value="all">
                  {lang === "ar" ? "كل القنوات" : "All channels"}
                </option>
                {data?.channels.map((x) => (
                  <option value={String(x.provider)} key={String(x.id)}>
                    {String(x.name)}
                  </option>
                ))}
              </select>
              <select
                aria-label={t.priority}
                value={priority}
                onChange={(e) => setPriority(e.target.value)}
              >
                <option value="all">
                  {lang === "ar" ? "كل الأولويات" : "All priorities"}
                </option>
                {["urgent", "high", "normal", "low"].map((x) => (
                  <option value={x} key={x}>
                    {t[x as keyof typeof t]}
                  </option>
                ))}
              </select>
            </div>
          )}
          <div className="threads">
            {loading && !data ? (
              <Empty icon={<RefreshCw className="spin" />} title={t.loading} />
            ) : error ? (
              <Empty
                icon={<ShieldAlert />}
                title={
                  lang === "ar" ? "تعذر تحميل الصندوق" : "Inbox could not load"
                }
                action={lang === "ar" ? "إعادة المحاولة" : "Retry"}
                onAction={() => void load()}
              />
            ) : data?.conversations.length ? (
              data.conversations.map((x) => (
                <button
                  className={selected === x.id ? "active" : ""}
                  onClick={() => choose(String(x.id))}
                  key={String(x.id)}
                >
                  <span className="avatar">
                    {String(x.customer_name).slice(0, 1)}
                  </span>
                  <span>
                    <b>{String(x.customer_name)}</b>
                    <small>{String(x.preview)}</small>
                    <em>
                      <ChannelIcon channel={String(x.channel)} />
                      {String(x.channel)} · {stateName(String(x.state), lang)}
                    </em>
                  </span>
                  <time>
                    {relative(String(x.last_message_at || x.updated_at), lang)}
                  </time>
                  {Number(x.unread_count) > 0 && (
                    <i>{Number(x.unread_count)}</i>
                  )}
                  {["urgent", "high"].includes(String(x.priority)) && (
                    <u>{priorityName(String(x.priority), lang)}</u>
                  )}
                </button>
              ))
            ) : (
              <Empty
                icon={<Inbox />}
                title={t.empty}
                copy={t.emptyHelp}
                action={t.openChannels}
                href="/dashboard/operations?view=channels"
              />
            )}
          </div>
        </aside>
        <section className="conversation-pane">
          {detail && c ? (
            <>
              <header className="conversation-head">
                <button
                  className="mobile-back"
                  onClick={close}
                  aria-label={t.back}
                >
                  {lang === "ar" ? <ArrowRight /> : <ArrowLeft />}
                </button>
                <span className="avatar">{title.slice(0, 1)}</span>
                <div>
                  <h2>{title}</h2>
                  <p>
                    <ChannelIcon channel={String(c.channel)} />
                    {String(c.channel)} ·{" "}
                    <b>
                      {c.owner_mode === "ai"
                        ? "AI"
                        : String(c.assigned_to || t.unassigned)}
                    </b>
                  </p>
                </div>
                <div className="conversation-actions">
                  <button
                    className="customer-toggle"
                    onClick={() => setShowCustomer(!showCustomer)}
                  >
                    <Contact />
                    <span>{t.customer}</span>
                  </button>
                  {c.owner_mode !== "human" ? (
                    <button
                      className="primary"
                      disabled={
                        busy || !data.permissions.includes("inbox.assign")
                      }
                      onClick={() =>
                        void post({
                          action: "take",
                          conversationId: c.id,
                          version: Number(c.lock_version),
                        })
                      }
                    >
                      <UserRound />
                      {t.take}
                    </button>
                  ) : myTurn && c.agent_id ? (
                    <button
                      disabled={busy}
                      onClick={() =>
                        void post({
                          action: "return_to_ai",
                          conversationId: c.id,
                          version: Number(c.lock_version),
                        })
                      }
                    >
                      <Bot />
                      {t.returnAi}
                    </button>
                  ) : null}
                  <select
                    aria-label={t.priority}
                    value={String(c.priority)}
                    onChange={(e) =>
                      void post({
                        action: "priority",
                        conversationId: c.id,
                        priority: e.target.value,
                      })
                    }
                  >
                    <option value="low">{t.low}</option>
                    <option value="normal">{t.normal}</option>
                    <option value="high">{t.high}</option>
                    <option value="urgent">{t.urgent}</option>
                  </select>
                </div>
              </header>
              <div className="ownership">
                <span className={c.owner_mode === "ai" ? "ai" : "human"}>
                  {c.owner_mode === "ai" ? <Bot /> : <UserRound />}
                  {c.owner_mode === "ai"
                    ? lang === "ar"
                      ? "الوكيل يدير المحادثة"
                      : "AI owns this conversation"
                    : lang === "ar"
                      ? `المحادثة مع ${String(c.assigned_to || "موظف")}`
                      : `Owned by ${String(c.assigned_to || "a teammate")}`}
                </span>
                {c.state === "handoff" && (
                  <b>
                    <ShieldAlert />
                    {String(c.handoff_reason || t.handoff)}
                  </b>
                )}
              </div>
              <div className="messages" aria-live="polite">
                {detail.messages.length ? (
                  detail.messages.map((m) => (
                    <article
                      className={`message ${m.sender_type}`}
                      key={String(m.id)}
                    >
                      <div>{String(m.content)}</div>
                      <footer>
                        <span>{String(m.sender_name)}</span>
                        <time>
                          {new Date(String(m.created_at)).toLocaleString(
                            lang === "ar" ? "ar-SA" : "en-US",
                          )}
                        </time>
                        {m.sender_type !== "customer" &&
                          (m.status === "read" ? <CheckCheck /> : <Check />)}
                      </footer>
                    </article>
                  ))
                ) : (
                  <Empty icon={<MessageCircle />} title={t.noMessages} />
                )}{" "}
                {detail.notes.map((n) => (
                  <article className="internal-note" key={String(n.id)}>
                    <FileText />
                    <div>
                      <b>
                        {t.note} · {String(n.author_name)}
                      </b>
                      <p>{String(n.content)}</p>
                      <time>
                        {new Date(String(n.created_at)).toLocaleString(
                          lang === "ar" ? "ar-SA" : "en-US",
                        )}
                      </time>
                    </div>
                  </article>
                ))}
              </div>
              <div className="composer">
                <div className="composer-tabs">
                  <button
                    className={tab === "reply" ? "active" : ""}
                    onClick={() => setTab("reply")}
                  >
                    <MessageCircle />
                    {t.reply}
                  </button>
                  <button
                    className={tab === "note" ? "active" : ""}
                    onClick={() => setTab("note")}
                  >
                    <FileText />
                    {t.note}
                  </button>
                  {tab === "reply" && (
                    <button
                      className="ai-draft"
                      disabled={busy}
                      onClick={async () => {
                        const j = await post({
                          action: "ai_draft",
                          conversationId: c.id,
                        });
                        setBody(String(j.draft));
                        toast.info(t.draftNotice);
                      }}
                    >
                      <Bot />
                      {t.aiDraft}
                    </button>
                  )}
                </div>
                {tab === "reply" && data.savedReplies.length > 0 && (
                  <select
                    aria-label="Saved replies"
                    defaultValue=""
                    onChange={(e) => {
                      const r = data.savedReplies.find(
                        (x) => x.id === e.target.value,
                      );
                      if (r)
                        setBody(String(lang === "ar" ? r.body_ar : r.body_en));
                      e.currentTarget.value = "";
                    }}
                  >
                    <option value="">
                      {lang === "ar" ? "رد محفوظ…" : "Saved reply…"}
                    </option>
                    {data.savedReplies.map((r) => (
                      <option key={String(r.id)} value={String(r.id)}>
                        {String(lang === "ar" ? r.title_ar : r.title_en)}
                      </option>
                    ))}
                  </select>
                )}
                <textarea
                  value={body}
                  onChange={(e) => setBody(e.target.value)}
                  placeholder={
                    tab === "reply" ? t.placeholder : t.notePlaceholder
                  }
                />
                <footer>
                  <span>
                    {tab === "note"
                      ? t.note
                      : !myTurn
                        ? t.takeFirst
                        : !canSend
                          ? t.channelUnavailable
                          : "Web Chat · NEXORA"}
                  </span>
                  <button
                    className="primary"
                    disabled={
                      busy || !body.trim() || (tab === "reply" && !canSend)
                    }
                    onClick={async () => {
                      await post(
                        tab === "reply"
                          ? {
                              action: "send",
                              conversationId: c.id,
                              content: body,
                              idempotencyKey: crypto.randomUUID(),
                            }
                          : {
                              action: "note",
                              conversationId: c.id,
                              content: body,
                            },
                      );
                      setBody("");
                      toast.success(
                        lang === "ar"
                          ? tab === "reply"
                            ? "تم إرسال الرد"
                            : "تم حفظ الملاحظة"
                          : tab === "reply"
                            ? "Reply sent"
                            : "Note saved",
                      );
                    }}
                  >
                    {tab === "reply" ? <Send /> : <FileText />}
                    {t.send}
                  </button>
                </footer>
              </div>
            </>
          ) : (
            <Empty
              icon={<MessageCircle />}
              title={t.select}
              copy={
                lang === "ar"
                  ? "يعرض الصندوق بيانات حقيقية فقط من مساحة العمل الحالية."
                  : "The inbox only shows real data from the current workspace."
              }
            />
          )}
        </section>
        <aside className="customer-pane">
          {detail && c ? (
            <>
              <header>
                <button
                  className="mobile-close"
                  onClick={() => setShowCustomer(false)}
                >
                  <X />
                </button>
                <span className="avatar large">{title.slice(0, 1)}</span>
                <h2>{title}</h2>
                <p>
                  {String(
                    detail.contact?.company ||
                      c.customer_email ||
                      c.customer_phone ||
                      t.unknown,
                  )}
                </p>
              </header>
              <Info
                icon={<AtSign />}
                label={lang === "ar" ? "البريد" : "Email"}
                value={String(
                  detail.contact?.email || c.customer_email || t.unknown,
                )}
              />
              <Info
                icon={<Contact />}
                label={lang === "ar" ? "الجوال" : "Phone"}
                value={String(
                  detail.contact?.phone || c.customer_phone || t.unknown,
                )}
              />
              <Info
                icon={<Globe2 />}
                label={lang === "ar" ? "اللغة" : "Language"}
                value={String(c.language || "ar").toUpperCase()}
              />
              <Info
                icon={<UserRound />}
                label={t.owner}
                value={String(c.assigned_to || c.agent_name || t.unassigned)}
              />
              <section className="crm-actions">
                <h3>CRM</h3>
                {Boolean(detail.contact?.id) && (
                  <Link href={`/crm/contacts/${String(detail.contact?.id)}`}>
                    {lang === "ar" ? "فتح ملف العميل 360" : "Open Customer 360"}
                  </Link>
                )}
                <button
                  disabled={!data.permissions.includes("crm.leads.manage")}
                  onClick={() => {
                    const title = window.prompt(
                      lang === "ar" ? "عنوان الفرصة" : "Lead title",
                      `${lang === "ar" ? "فرصة" : "Opportunity"} — ${String(c.customer_name)}`,
                    );
                    if (title)
                      void post({
                        action: "create_lead",
                        conversationId: c.id,
                        title,
                        interest: String(c.last_intent || ""),
                        score: 50,
                      });
                  }}
                >
                  <Plus />
                  {t.createLead}
                </button>
                <button
                  disabled={!data.permissions.includes("tasks.manage")}
                  onClick={() => {
                    const title = window.prompt(
                      lang === "ar" ? "عنوان المهمة" : "Task title",
                    );
                    if (title)
                      void post({
                        action: "create_task",
                        conversationId: c.id,
                        title,
                        dueAt: null,
                      });
                  }}
                >
                  <Plus />
                  {t.createTask}
                </button>
              </section>
              <section className="summary">
                <h3>
                  {lang === "ar" ? "ملخص المحادثة" : "Conversation summary"}
                </h3>
                <p>{String(c.summary || c.preview)}</p>
                <span>
                  <Tag />
                  {safeTags(c.tags_json).length
                    ? safeTags(c.tags_json).join(" · ")
                    : lang === "ar"
                      ? "لا توجد وسوم"
                      : "No tags"}
                </span>
              </section>
              <section className="linked">
                <h3>
                  {lang === "ar" ? "العناصر المرتبطة" : "Related records"}
                </h3>
                <p>
                  {detail.leads.length} Leads · {detail.tasks.length}{" "}
                  {lang === "ar" ? "مهام" : "tasks"}
                </p>
              </section>
              <section className="status-actions">
                <button
                  onClick={() =>
                    void post({
                      action: "status",
                      conversationId: c.id,
                      status: c.state === "resolved" ? "open" : "resolved",
                    })
                  }
                >
                  <Check />
                  {c.state === "resolved" ? t.reopen : t.resolve}
                </button>
              </section>
            </>
          ) : null}
        </aside>
      </section>
    </main>
  );
}
function Empty({
  icon,
  title,
  copy,
  action,
  href,
  onAction,
}: {
  icon: React.ReactNode;
  title: string;
  copy?: string;
  action?: string;
  href?: string;
  onAction?: () => void;
}) {
  return (
    <div className="inbox-empty">
      {icon}
      <h3>{title}</h3>
      {copy && <p>{copy}</p>}
      {action &&
        (href ? (
          <a href={href}>{action}</a>
        ) : (
          <button onClick={onAction}>{action}</button>
        ))}
    </div>
  );
}
function Info({
  icon,
  label,
  value,
}: {
  icon: React.ReactNode;
  label: string;
  value: string;
}) {
  return (
    <div className="customer-info">
      <span>{icon}</span>
      <div>
        <small>{label}</small>
        <b>{value}</b>
      </div>
    </div>
  );
}
function ChannelIcon({ channel }: { channel: string }) {
  return channel.toLowerCase().includes("email") ? (
    <AtSign />
  ) : channel.toLowerCase().includes("web") || channel.includes("الموقع") ? (
    <Globe2 />
  ) : (
    <MessageCircle />
  );
}
function stateName(s: string, l: string) {
  const a: Record<string, [string, string]> = {
    open: ["مفتوحة", "Open"],
    handoff: ["محولة", "Handoff"],
    resolved: ["محلولة", "Resolved"],
    snoozed: ["مؤجلة", "Snoozed"],
    spam: ["مزعجة", "Spam"],
  };
  return (a[s] || [s, s])[l === "ar" ? 0 : 1];
}
function priorityName(s: string, l: string) {
  const a: Record<string, [string, string]> = {
    urgent: ["عاجلة", "Urgent"],
    high: ["عالية", "High"],
  };
  return (a[s] || [s, s])[l === "ar" ? 0 : 1];
}
function relative(v: string, l: string) {
  const d = Date.now() - new Date(v).getTime();
  if (!Number.isFinite(d)) return "";
  const m = Math.max(0, Math.floor(d / 60000));
  if (m < 1) return l === "ar" ? "الآن" : "now";
  if (m < 60) return l === "ar" ? `منذ ${m}د` : `${m}m`;
  const h = Math.floor(m / 60);
  if (h < 24) return l === "ar" ? `منذ ${h}س` : `${h}h`;
  return new Date(v).toLocaleDateString(l === "ar" ? "ar-SA" : "en-US");
}
function safeTags(v: unknown) {
  try {
    const x = JSON.parse(String(v || "[]"));
    return Array.isArray(x) ? x.map(String) : [];
  } catch {
    return [];
  }
}
