/* 跨页面复用的小组件（独立文件以满足 react-refresh) */
import { useEffect, useState, type ReactNode } from "react"
import { RiArrowDownSLine, RiHeartLine, RiPhoneLine } from "@remixicon/react"
import { Button } from "@/components/ui/button"
import { contentLang } from "@/lib/locale"

/* 心理危机熔断面板：温和但醒目，热线可直接点按拨打 (Cast 与 Tab2 共用） */
export function CrisisPanel({ message, helplines, onClose }: {
  message: string
  helplines: { name: string; tel: string }[]
  onClose: () => void
}) {
  return (
    <div className="rounded-2xl border p-8 text-left"
      style={{ background: "rgba(163,91,91,0.07)", borderColor: "#A35B5B" }}>
      <div className="mb-4 flex items-center gap-2.5" style={{ color: "#A35B5B" }}>
        <RiHeartLine className="h-6 w-6" />
        <span className="text-base tracking-[0.25em]">先停一停</span>
      </div>
      <p className="text-sm leading-7 whitespace-pre-wrap">{message.split("\n\n")[0] || message}</p>
      <div className="my-5 space-y-1">
        {helplines.map((h) => (
          <a key={h.tel} href={`tel:${h.tel.replace(/\s/g, "")}`}
            className="hover:bg-foreground/5 flex items-center gap-2 rounded-lg px-3 py-2 text-sm tracking-wide transition-colors"
            style={{ color: "var(--gold)" }}>
            <RiPhoneLine className="h-4 w-4 shrink-0" /> {h.name} | {h.tel}
          </a>
        ))}
      </div>
      <p className="text-muted-foreground mb-5 text-xs leading-6">
        这不是命理问题，而是此刻最该被认真对待的事。你不必独自面对。
      </p>
      <Button variant="outline" onClick={onClose}>回到安静处</Button>
    </div>
  )
}

/* 次级内容折叠：居中分隔线式开关，默认收起，让主角聚焦 */
export function Foldable({ label, children, defaultOpen = false }: {
  label: string
  children: React.ReactNode
  defaultOpen?: boolean
}) {
  const [open, setOpen] = useState(defaultOpen)
  return (
    <div className="mx-auto w-full">
      <div className="flex justify-center">
        <button type="button" aria-expanded={open} onClick={() => setOpen((o) => !o)}
          className="text-muted-foreground hover:text-foreground group flex items-center gap-2.5 py-2 transition-colors">
          <span className="bg-border h-px w-8 transition-all group-hover:w-10" />
          <span className="text-xs tracking-[0.3em]">{open ? label.replace(/^展开/, "收起") : label}</span>
          <RiArrowDownSLine className={`h-4 w-4 transition-transform ${open ? "rotate-180" : ""}`} />
          <span className="bg-border h-px w-8 transition-all group-hover:w-10" />
        </button>
      </div>
      {open && <div className="fade-in mt-5">{children}</div>}
    </div>
  )
}

/* 长文按换行分段, 段落间留白, 错落有致 (解读叙事/弹窗长文共用) */
/* 行内 Markdown 渲染: **粗** / *强调* 一律渲染为加黑, 不再原样输出星号 */
function renderInline(text: string): ReactNode[] {
  const out: ReactNode[] = []
  const re = /\*\*([^*]+)\*\*|\*([^*\n]+)\*|__([^_]+)__/g
  let last = 0, key = 0, m: RegExpExecArray | null
  while ((m = re.exec(text)) !== null) {
    if (m.index > last) out.push(text.slice(last, m.index))
    out.push(
      <strong key={key++} className="text-foreground font-semibold">
        {m[1] ?? m[2] ?? m[3]}
      </strong>,
    )
    last = re.lastIndex
  }
  if (last < text.length) out.push(text.slice(last))
  return out
}

export function Prose({ text, className = "" }: { text: string; className?: string }) {
  let t = text
  // 英文环境的兜底: 模型偶尔照搬中文「今日可行的一小步：」前缀, 这里统一替换
  if (contentLang() === "en") t = t.replace(/今日可行的一小步\s*[:：]?\s*/g, "Today's small step: ")
  const paras = t.split(/\n+/).map((s) => s.trim()).filter(Boolean)
  return (
    <div className={`space-y-3 text-sm leading-[1.85] ${className}`}>
      {paras.map((p, i) => <p key={i}>{renderInline(p)}</p>)}
    </div>
  )
}

/* 墨迹晕开式逐字显示 */
export function InkText({ text }: { text: string }) {
  const [n, setN] = useState(0)
  useEffect(() => {
    // 动画初始化： text 变化时从头重放，是有意的同步重置
    // eslint-disable-next-line react-hooks/set-state-in-effect
    setN(0)
    const t = setInterval(() => {
      setN((x) => {
        if (x >= text.length) {
          clearInterval(t)
          return x
        }
        return x + 1
      })
    }, 18)
    return () => clearInterval(t)
  }, [text])
  return <div className="text-sm whitespace-pre-wrap">{text.slice(0, n)}</div>
}

/* 水墨晕开式加载占位（替代 18s 思考段的静态"推演中") */
export function InkLoading({ label = "推演中" }: { label?: string }) {
  return (
    <div className="ink-loading">
      <span className="ink-blot" />
      <span className="ink-blot" />
      <span className="ink-blot" />
      <span className="ink-loading-label">{label}</span>
    </div>
  )
}

/* 离线徽标：本应用全本地运行，离线仍可推演 —— 提示是安心而非警告 */
export function OfflineBadge() {
  const [offline, setOffline] = useState(typeof navigator !== "undefined" && !navigator.onLine)
  useEffect(() => {
    const on = () => setOffline(false)
    const off = () => setOffline(true)
    window.addEventListener("online", on)
    window.addEventListener("offline", off)
    return () => { window.removeEventListener("online", on); window.removeEventListener("offline", off) }
  }, [])
  if (!offline) return null
  return (
    <div className="glass-heavy fixed top-3 left-1/2 z-50 -translate-x-1/2 rounded-full px-4 py-1.5 text-xs tracking-[0.2em]"
      style={{ color: "var(--gold)" }}>
      离线中 | 本地推演仍可用
    </div>
  )
}

export function CardLabel({ children }: { children: React.ReactNode }) {
  return <div className="mb-3 text-[0.95rem] font-medium tracking-[0.18em]" style={{ color: "var(--gold)" }}>{children}</div>
}

export function ZoneTitle({ children }: { children: React.ReactNode }) {
  return (
    <h3 className="text-foreground mb-7 text-lg font-medium tracking-[0.4em]">
      {children}
      <span className="mt-3 block h-px w-10 opacity-50" style={{ background: "var(--gold)" }} />
    </h3>
  )
}
