"use client";

/**
 * AI Beauty: آیکون (دو ستاره + نشان NEW) و پنل گفت‌وگوی شناور با زمینه گرادیانی بنفش، صورتی و هلویی.
 * پنل یک بار در قالب فروشگاه رندر می‌شود و منوی پایین موبایل (و دکمه شناور دسکتاپ) آن را باز می‌کنند.
 * اگر هوش مصنوعی در پنل مدیریت فعال باشد، گفت‌وگوی واقعی با Claude (از مسیر /api/ai/chat)؛
 * وگرنه پیشنهادهای آماده به لیست محصولات مرتبط می‌روند و متن نوشته‌شده در جستجوی سایت جستجو می‌شود.
 */
import Link from "next/link";
import { usePathname, useRouter } from "next/navigation";
import { useEffect, useRef, useState, useSyncExternalStore } from "react";
import { createPortal } from "react-dom";
import { Icon } from "@/components/ui/Icon";
import { Inline } from "@/lib/article-markdown";

// ── وضعیت باز/بسته مشترک ─────────────────────────────

let isOpen = false;
const listeners = new Set<() => void>();
const setOpen = (v: boolean) => {
  isOpen = v;
  listeners.forEach((l) => l());
};
export const openAiBeauty = () => setOpen(true);
const closeAiBeauty = () => setOpen(false);

export function useAiBeautyOpen() {
  return useSyncExternalStore(
    (l) => {
      listeners.add(l);
      return () => listeners.delete(l);
    },
    () => isOpen,
    () => false,
  );
}

// ── آیکون ────────────────────────────────────────────

/** ستاره بزرگ و ستاره کوچک؛ ضخامت خط و رنگ مثل بقیه آیکون‌ها (Icon) */
export function SparklesIcon({ size = 22, strokeWidth = 1.5 }: { size?: number; strokeWidth?: number }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={strokeWidth} strokeLinejoin="round" aria-hidden="true">
      <path d="M10 5c.65 4.75 2.25 6.35 7 7-4.75.65-6.35 2.25-7 7-.65-4.75-2.25-6.35-7-7 4.75-.65 6.35-2.25 7-7Z" />
      <path d="M18.5 2.5c.27 1.95.93 2.6 2.9 2.9-1.97.27-2.63.93-2.9 2.9-.27-1.97-.93-2.63-2.9-2.9 1.97-.3 2.63-.95 2.9-2.9Z" />
    </svg>
  );
}

/** ستاره‌ها با نشان NEW بالای آن */
export function AiBeautyMark({ strokeWidth }: { strokeWidth?: number }) {
  return (
    <span className="relative">
      <SparklesIcon strokeWidth={strokeWidth} />
      <span className="absolute -top-2 end-3.5 rounded-full bg-ink px-1 text-[8px] leading-[12px] font-bold tracking-wide text-paper" dir="ltr">
        NEW
      </span>
    </span>
  );
}

/** گرادیان مشترک دکمه شناور و پنل گفت‌وگو (بنفش ← صورتی ← هلویی) */
const AI_GRADIENT = "linear-gradient(135deg, #e7dbf8 0%, #f0dbe9 50%, #f8e2d7 100%)";

/** آیکون حباب گفت‌وگو با جرقه */
function ChatSparkIcon() {
  return (
    <svg width="26" height="26" viewBox="0 0 26 26" fill="none" stroke="currentColor" strokeWidth={1.9} strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
      <path d="M14.5 3.3A9.6 9.6 0 1 0 22 16.5" />
      <path d="M5.2 19.3 3.5 23l4.3-1.4" />
      <path d="M19.5 2.5c.3 2.2 1 2.9 3.2 3.2-2.2.3-2.9 1-3.2 3.2-.3-2.2-1-2.9-3.2-3.2 2.2-.3 2.9-1 3.2-3.2Z" fill="currentColor" />
    </svg>
  );
}

/** دکمه شناور پایین صفحه برای دسکتاپ (در موبایل همین دکمه در منوی پایین است) */
export function AiBeautyFloatingButton() {
  return (
    <button
      type="button"
      onClick={openAiBeauty}
      aria-label="AI Beauty Chat، دستیار زیبایی"
      dir="ltr"
      style={{ background: AI_GRADIENT }}
      className="fixed end-6 bottom-6 z-30 hidden h-14 items-center gap-3 rounded-full ps-5 pe-6 text-ink shadow-[0_6px_24px_rgba(0,0,0,0.12)] transition hover:-translate-y-0.5 hover:shadow-[0_10px_28px_rgba(0,0,0,0.16)] md:flex"
    >
      <ChatSparkIcon />
      <span className="text-[17px] font-bold whitespace-nowrap">AI Beauty Chat</span>
      <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={2} strokeLinecap="round" strokeLinejoin="round" aria-hidden="true" className="ms-6">
        <path d="m6 15 6-6 6 6" />
      </svg>
    </button>
  );
}
// ── پنل ─────────────────────────────────────────────

const PROMPTS: { label: string; href: string }[] = [
  { label: "پرفروش‌ترین شامپو و نرم‌کننده‌ها", href: "/c/مو?sort=popular" },
  { label: "ماندگارترین عطرها", href: "/c/عطر?sort=rating" },
  { label: "روتین روزانه برای پوست نرمال", href: "/c/مراقبت-پوست?skin=normal&sort=rating" },
  { label: "مرطوب‌کننده برای پوست چرب و مستعد جوش", href: "/c/مراقبت-پوست/مرطوب-کننده?skin=oily" },
  { label: "لوسیون بدن برای پوست خشک", href: "/c/بدن?skin=dry" },
  { label: "ضدآفتاب برای پوست حساس", href: "/c/مراقبت-پوست/ضدآفتاب?skin=sensitive" },
];

type ChatMessage = { role: "user" | "assistant"; content: string };

const RESUME_KEY = "zahora.ai-resume";
/** آدرس همین صفحه با ?ai=resume تا بعد از ورود، گفت‌وگو ادامه پیدا کند */
function resumeUrl() {
  const url = new URL(window.location.href);
  url.searchParams.set("ai", "resume");
  return url.pathname + url.search;
}

/** پاسخ دستیار: خط‌ها، فهرست «- » و لینک/پررنگ (رندر امن، بدون HTML خام) */
function AssistantText({ text, onNavigate }: { text: string; onNavigate: () => void }) {
  return (
    <div className="space-y-1.5 text-[15px] leading-7" onClick={(e) => (e.target as HTMLElement).closest("a") && onNavigate()}>
      {text.split("\n").filter((l) => l.trim()).map((line, i) => {
        const item = line.match(/^\s*[-*•]\s+(.*)$/);
        return item ? (
          <p key={i} className="flex gap-2"><span aria-hidden>•</span><span><Inline text={item[1]} /></span></p>
        ) : (
          <p key={i}><Inline text={line} /></p>
        );
      })}
    </div>
  );
}

export function AiBeautyPanel({ chatEnabled }: { chatEnabled: boolean }) {
  const open = useAiBeautyOpen();
  const [q, setQ] = useState("");
  const [messages, setMessages] = useState<ChatMessage[]>([]);
  const [streaming, setStreaming] = useState(false);
  const [error, setError] = useState("");
  /** پیام «برای ادامه ثبت‌نام کنید» بعد از تمام شدن پیام‌های مهمان */
  const [authNeeded, setAuthNeeded] = useState("");
  const inputRef = useRef<HTMLInputElement>(null);
  const scrollRef = useRef<HTMLDivElement>(null);
  const abortRef = useRef<AbortController | null>(null);
  const router = useRouter();

  useEffect(() => {
    if (!open) return;
    const onKey = (e: KeyboardEvent) => e.key === "Escape" && closeAiBeauty();
    document.addEventListener("keydown", onKey);
    const prev = document.body.style.overflow;
    document.body.style.overflow = "hidden";
    return () => {
      document.removeEventListener("keydown", onKey);
      document.body.style.overflow = prev;
    };
  }, [open]);

  // برگشت از صفحه ورود (?ai=resume): پنل باز و گفت‌وگو از همان پیام ادامه پیدا می‌کند.
  // پنل در قالب مشترک است و با جابه‌جایی بین صفحات از نو ساخته نمی‌شود؛ پس با هر تغییر مسیر بررسی می‌شود
  const pathname = usePathname();
  useEffect(() => {
    if (!chatEnabled) return;
    const url = new URL(window.location.href);
    if (url.searchParams.get("ai") !== "resume") return;
    url.searchParams.delete("ai");
    window.history.replaceState(null, "", url);
    let saved: { messages: ChatMessage[]; pending: string } | null = null;
    try {
      saved = JSON.parse(sessionStorage.getItem(RESUME_KEY) ?? "null");
      sessionStorage.removeItem(RESUME_KEY);
    } catch {
      saved = null;
    }
    openAiBeauty();
    if (saved?.pending) {
      setMessages(saved.messages ?? []);
      void send(saved.pending, saved.messages ?? []);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [chatEnabled, pathname]);

  // پیام جدید ← اسکرول به پایین
  useEffect(() => {
    scrollRef.current?.scrollTo({ top: scrollRef.current.scrollHeight });
  }, [messages]);

  if (!open) return null;

  function newChat() {
    abortRef.current?.abort();
    setMessages([]);
    setError("");
    setAuthNeeded("");
    setQ("");
    inputRef.current?.focus();
  }

  async function send(text: string, base: ChatMessage[] = messages) {
    const content = text.trim().slice(0, 1500);
    if (!content || streaming) return;
    setError("");
    setAuthNeeded("");
    setQ("");
    const history: ChatMessage[] = [...base, { role: "user" as const, content }].slice(-19);
    setMessages([...history, { role: "assistant", content: "" }]);
    setStreaming(true);
    const ctrl = new AbortController();
    abortRef.current = ctrl;
    try {
      const res = await fetch("/api/ai/chat", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ messages: history }),
        signal: ctrl.signal,
      });
      if (!res.ok || !res.body) {
        const err = (await res.json().catch(() => null)) as { error?: string; needsAuth?: boolean } | null;
        if (err?.needsAuth) {
          // گفت‌وگو و پیام آخر نگه داشته می‌شود تا بعد از ورود از همین‌جا ادامه پیدا کند
          setMessages(history);
          try {
            sessionStorage.setItem(RESUME_KEY, JSON.stringify({ messages: history.slice(0, -1), pending: content }));
          } catch {
            /* حالت خصوصی مرورگر */
          }
          setAuthNeeded(err.error ?? "برای ادامه وارد شوید");
          return;
        }
        throw new Error(err?.error ?? "پاسخی دریافت نشد");
      }
      const reader = res.body.getReader();
      const decoder = new TextDecoder();
      let acc = "";
      for (;;) {
        const { value, done } = await reader.read();
        if (done) break;
        acc += decoder.decode(value, { stream: true });
        setMessages([...history, { role: "assistant", content: acc }]);
      }
    } catch (e) {
      if ((e as Error).name === "AbortError") return;
      setMessages(history.slice(0, -1));
      setQ(content);
      setError((e as Error).message || "ارتباط برقرار نشد");
    } finally {
      setStreaming(false);
    }
  }

  function submit(e: React.FormEvent) {
    e.preventDefault();
    const text = q.trim();
    if (!text) return;
    if (chatEnabled) return void send(text);
    // بدون هوش مصنوعی: جستجو در محصولات سایت
    closeAiBeauty();
    setQ("");
    router.push(`/search?q=${encodeURIComponent(text.slice(0, 80))}`);
  }

  return createPortal(
    <div className="fixed inset-0 z-50" role="dialog" aria-modal="true" aria-label="AI Beauty Chat">
      <button aria-label="بستن" className="absolute inset-0 animate-fade-in bg-ink/30" onClick={closeAiBeauty} />
      <div
        className="absolute inset-x-3 bottom-[calc(4.5rem+env(safe-area-inset-bottom))] flex max-h-[78dvh] animate-slide-up flex-col overflow-hidden rounded-2xl shadow-xl md:end-auto md:start-6 md:bottom-6 md:w-[400px]"
        style={{ background: AI_GRADIENT }}
      >
        <div className="grid h-16 shrink-0 grid-cols-[2.5rem_1fr_5rem] items-center px-3">
          <span />
          <h2 className="text-center text-base font-bold" dir="ltr">
            AI Beauty Chat
          </h2>
          <div className="flex justify-end gap-1">
            <button type="button" aria-label="گفت‌وگوی جدید" className="grid size-9 place-items-center rounded-full hover:bg-paper/50" onClick={newChat}>
              <Icon name="edit" size={22} />
            </button>
            <button type="button" aria-label="بستن" className="grid size-9 place-items-center rounded-full hover:bg-paper/50" onClick={closeAiBeauty}>
              <Icon name="chevron-down" size={22} />
            </button>
          </div>
        </div>

        <div ref={scrollRef} className="flex-1 space-y-3 overflow-y-auto overscroll-contain px-5 pt-2 pb-4" aria-live="polite">
          {messages.length === 0 ? (
            <>
              {PROMPTS.map((p) =>
                chatEnabled ? (
                  <button
                    key={p.label}
                    type="button"
                    onClick={() => send(p.label)}
                    className="block w-fit max-w-full rounded-[5px] bg-paper px-4 py-2.5 text-start text-[15px] shadow-[0_1px_4px_rgba(0,0,0,0.08)] transition hover:shadow-[0_2px_8px_rgba(0,0,0,0.14)]"
                  >
                    {p.label}
                  </button>
                ) : (
                  <Link
                    key={p.label}
                    href={p.href}
                    onClick={closeAiBeauty}
                    className="block w-fit max-w-full rounded-[5px] bg-paper px-4 py-2.5 text-[15px] shadow-[0_1px_4px_rgba(0,0,0,0.08)] transition hover:shadow-[0_2px_8px_rgba(0,0,0,0.14)]"
                  >
                    {p.label}
                  </Link>
                ),
              )}
              <p className="pt-4 text-[13px] leading-6">
                {chatEnabled
                  ? "پاسخ‌ها با هوش مصنوعی تولید می‌شوند و فقط محصولات زهورا را پیشنهاد می‌دهند. ممکن است خطا داشته باشند؛ برای مشکلات پوستی جدی با پزشک مشورت کنید. اطلاعات شخصی وارد نکنید."
                  : "پیشنهادها بر اساس دسته‌بندی، نوع پوست و امتیاز محصولات زهورا انتخاب می‌شوند. متنی که بنویسید در محصولات سایت جستجو می‌شود."}
              </p>
            </>
          ) : (
            messages.map((m, i) =>
              m.role === "user" ? (
                <p key={i} className="ms-auto w-fit max-w-[85%] rounded-2xl rounded-se-md bg-ink px-4 py-2.5 text-[15px] leading-7 text-paper">{m.content}</p>
              ) : (
                <div key={i} className="w-fit max-w-[92%] rounded-2xl rounded-ss-md bg-paper px-4 py-3 shadow-[0_1px_4px_rgba(0,0,0,0.06)]">
                  {m.content ? <AssistantText text={m.content} onNavigate={closeAiBeauty} /> : <span className="inline-flex gap-1 py-2" aria-label="در حال نوشتن"><span className="size-1.5 animate-pulse rounded-full bg-muted" /><span className="size-1.5 animate-pulse rounded-full bg-muted [animation-delay:150ms]" /><span className="size-1.5 animate-pulse rounded-full bg-muted [animation-delay:300ms]" /></span>}
                </div>
              ),
            )
          )}
          {authNeeded && (
            <div className="w-fit max-w-[92%] space-y-3 rounded-2xl rounded-ss-md bg-paper px-4 py-3 text-[15px] leading-7 shadow-[0_1px_4px_rgba(0,0,0,0.06)]">
              <p>{authNeeded}</p>
              <Link
                href={`/auth?next=${encodeURIComponent(resumeUrl())}`}
                onClick={closeAiBeauty}
                className="inline-flex h-10 items-center rounded-full bg-ink px-5 text-sm font-bold text-paper"
              >
                ورود / ثبت‌نام و ادامه گفت‌وگو
              </Link>
            </div>
          )}
          {error && <p role="alert" className="rounded-xl bg-paper/70 px-3 py-2 text-xs">⚠ {error}</p>}
        </div>

        <form onSubmit={submit} className="shrink-0 bg-paper/30 px-4 pt-3 pb-4">
          <div className="flex items-center gap-2 rounded-full bg-[#f4f4f6] ps-5 pe-1.5">
            <input
              ref={inputRef}
              value={q}
              onChange={(e) => setQ(e.target.value)}
              maxLength={chatEnabled ? 1500 : 80}
              placeholder="پیام…"
              aria-label="پیام یا جستجو"
              className="h-14 min-w-0 flex-1 bg-transparent text-[15px] outline-none placeholder:text-[#8a8a8e]"
            />
            <button type="submit" aria-label="ارسال" disabled={streaming} className="grid size-10 shrink-0 place-items-center rounded-full bg-[#8e8e8e] text-paper transition hover:bg-[#6f6f6f] disabled:opacity-60">
              <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={1.8} strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <path d="M12 19V5M6 11l6-6 6 6" />
              </svg>
            </button>
          </div>
        </form>
      </div>
    </div>,
    document.body,
  );
}
