/**
 * [INPUT]: 依赖 React、formalAtlasData 与 styles.css
 * [OUTPUT]: 对外提供正式 Web 对齐的 Landing、Auth、Atlas Media Detail 三页原型
 * [POS]: Formal Atlas Reframe 的状态编排入口；所有动作均为浏览器内模拟
 * [PROTOCOL]: 变更时更新此头部，然后检查 CLAUDE.md
 */
const { useEffect, useState } = React;
const { work, nav, connections, releases } = window.formalAtlasData;
const SCREEN_META = { landing: ["01", "落地页"], auth: ["02", "登录 / 注册"], detail: ["03", "正式详情页"] };

function Brand({ full = true }) {
  return <span className={`atlas-brand ${full ? "" : "atlas-brand--compact"}`}><b>T</b>{full && <span>TINUE</span>}<i></i></span>;
}

function Glyph({ children }) { return <span className="glyph" aria-hidden="true">{children}</span>; }
function Poster({ art = 1, className = "" }) { return <span className={`poster-art poster-art--${art} ${className}`} aria-hidden="true"></span>; }

function PrototypeBar({ screen, onChange }) {
  return <div className="prototype-bar"><div className="prototype-label"><Brand /><span className="bar-divider"></span><span>FORMAL WEB / COMPACT DETAIL STUDY</span></div><div className="prototype-tabs" role="tablist" aria-label="原型页面切换">{Object.entries(SCREEN_META).map(([key, [index, label]]) => <button key={key} type="button" role="tab" aria-selected={screen === key} className={screen === key ? "is-active" : ""} onClick={() => onChange(key)}><small>{index}</small>{label}</button>)}</div><span className="prototype-note">基于正式项目</span></div>;
}

function LandingPage({ onNavigate, onToast }) {
  return <section className="public-page landing-page" data-screen-label="01 / Landing">
    <header className="public-header"><button type="button" className="header-brand" onClick={() => onNavigate("landing")}><Brand /></button><nav><button type="button" onClick={() => document.getElementById("formal-loop")?.scrollIntoView({ behavior: "smooth" })}>产品</button><button type="button" onClick={() => onToast("正式项目的核心入口是 Atlas 工作台。")}>工作台</button><button type="button" onClick={() => onToast("播放器连接会在登录后从 Profile 进入。")}>连接</button></nav><div className="header-actions"><button type="button" onClick={() => onNavigate("auth", "login")}>登录</button><button className="light-button light-button--solid" type="button" onClick={() => onNavigate("auth", "register")}>开始使用 <Glyph>→</Glyph></button></div></header>
    <div className="landing-layout"><div className="landing-intro"><p className="atlas-kicker">TINUE CORE / PERSONAL WATCH STATE</p><h1>把作品放回生活，<br /><em>把进度留在身边。</em></h1><p className="landing-copy">Tinue 是你的观看工作台：探索作品、管理片库、连接播放器，并在下一次打开时继续上次停下的地方。</p><div className="landing-buttons"><button className="light-button light-button--solid" type="button" onClick={() => onNavigate("auth", "register")}>创建个人档案 <Glyph>↗</Glyph></button><button className="light-button light-button--outline" type="button" onClick={() => onNavigate("detail")}>查看作品详情</button></div><div className="landing-facts"><div><strong>01</strong><span>探索 → 片库 → 继续</span></div><div><strong>02</strong><span>观看状态属于你的个人账号</span></div><div><strong>03</strong><span>连接只在需要时出现</span></div></div></div><div className="landing-board"><div className="board-top"><span>ATLAS / RECENTLY WATCHED</span><button type="button" onClick={() => onNavigate("detail")}>打开详情 <Glyph>↗</Glyph></button></div><div className="board-feature"><div className="board-poster"><Poster art={1} /><span>62%</span></div><div className="board-copy"><p>正在观看 · 电影</p><h2>沙丘：第二部</h2><span>Dune: Part Two</span><div className="board-progress"><i></i></div><div className="board-meta"><span>Infuse · Apple TV</span><b>01:43:12</b></div><button type="button" onClick={() => onToast("原型：这里会打开已连接播放器。")}>播放器中继续 <Glyph>→</Glyph></button></div></div><div className="board-list"><div><Poster art={2} /><span><b>人生切割术</b><small>S01 E05 · SenPlayer</small></span><em>18%</em></div><div><Poster art={3} /><span><b>三体</b><small>S01 E03 · HamHub</small></span><em>41%</em></div><div><Poster art={4} /><span><b>奥本海默</b><small>已看 · Infuse</small></span><em>100%</em></div></div></div></div>
    <section className="formal-loop" id="formal-loop"><div className="loop-heading"><p className="atlas-kicker">THE ATLAS LOOP</p><h2>正式产品的三个入口，<br /><em>都回到同一份状态。</em></h2></div><div className="loop-grid"><article><span>01</span><h3>探索内容</h3><p>在 Discover 找到作品，详情页统一承接作品、季集与资源层级。</p></article><article><span>02</span><h3>管理片库</h3><p>想看与已看写入作品级片库，单集观看仍保留在历史。</p></article><article><span>03</span><h3>从播放器继续</h3><p>Bridge 回传播放状态，Atlas 只展示属于你的观看进度。</p></article></div></section>
    <footer className="public-footer"><Brand full={false} /><span>探索、片库、历史、资源与片单</span><span>© 2026 Tinue</span></footer>
  </section>;
}

function AuthPage({ mode, setMode, onNavigate, onToast }) {
  const [name, setName] = useState(""); const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const [error, setError] = useState(""); const [pending, setPending] = useState(false);
  function submit(event) { event.preventDefault(); setError(""); if (mode === "register" && !name.trim()) return setError("请输入昵称。"); if (!email.includes("@")) return setError("请输入有效的邮箱地址。"); if (password.length < 12) return setError("密码至少需要 12 位。"); setPending(true); window.setTimeout(() => { setPending(false); onToast(mode === "register" ? "个人档案已准备好。" : "已登录，进入 Atlas 工作台。 "); }, 600); }
  return <section className="public-page auth-page" data-screen-label="02 / Auth"><header className="public-header"><button type="button" className="header-brand" onClick={() => onNavigate("landing")}><Brand /></button><span className="auth-crumb">ACCOUNT / {mode === "register" ? "REGISTER" : "LOGIN"}</span><button className="header-back" type="button" onClick={() => onNavigate("landing")}><Glyph>←</Glyph> 返回首页</button></header><div className="auth-layout"><div className="auth-context"><p className="atlas-kicker">A PERSONAL ATLAS</p><h1>先有一份档案，<br /><em>再谈下一部。</em></h1><p>注册或登录一个独立个人账户，保存自己的片库与观看状态。播放器连接不取代你的账号，也不改变个人账户边界。</p><div className="auth-context-card"><div className="auth-card-poster"><Poster art={1} /></div><div><span>YOUR WATCH STATE</span><strong>62%</strong><small>沙丘：第二部 · Infuse</small><div className="mini-progress"><i></i></div></div></div><div className="auth-note"><i></i><span>邮箱 + 密码 · 无需邮箱验证</span></div></div><div className="auth-form-card"><div className="form-heading"><div><p className="atlas-kicker">TINUE ACCOUNT</p><h2>{mode === "register" ? "创建个人档案" : "欢迎回来"}</h2></div><span>02 / 03</span></div><div className="form-tabs" role="tablist" aria-label="登录注册切换"><button type="button" role="tab" aria-selected={mode === "login"} className={mode === "login" ? "is-active" : ""} onClick={() => { setMode("login"); setError(""); }}>登录</button><button type="button" role="tab" aria-selected={mode === "register"} className={mode === "register" ? "is-active" : ""} onClick={() => { setMode("register"); setError(""); }}>注册</button></div><form onSubmit={submit} noValidate>{mode === "register" && <label><span>昵称</span><input value={name} onChange={(event) => setName(event.target.value)} placeholder="例如：Ming" autoComplete="name" /></label>}<label><span>邮箱</span><input value={email} onChange={(event) => setEmail(event.target.value)} type="email" placeholder="you@example.com" autoComplete="email" /></label><label><span>密码</span><input value={password} onChange={(event) => setPassword(event.target.value)} type="password" placeholder="至少 12 位" autoComplete={mode === "register" ? "new-password" : "current-password"} /></label>{error && <p className="form-error" role="alert">! {error}</p>}<button className="light-button light-button--solid light-button--wide" type="submit" disabled={pending}>{pending ? "正在准备…" : mode === "register" ? "注册并进入 Atlas" : "登录并进入 Atlas"}<Glyph>→</Glyph></button></form><div className="form-footer"><span>独立个人账户</span><button type="button" onClick={() => onToast("登录后从 Profile 管理播放器连接。")}>播放器连接 <Glyph>↗</Glyph></button></div></div></div></section>;
}

function AtlasShell({ children, active = "作品", onNavigate, onToast }) {
  return <div className="atlas-shell"><aside className="atlas-sidebar"><button className="sidebar-brand" type="button" onClick={() => onNavigate("landing")} aria-label="Tinue 首页"><Brand full={false} /></button><nav aria-label="主要导航">{nav.map((item) => <button key={item} type="button" className={active === item ? "is-current" : ""} onClick={() => onToast(`${item} 是正式 Atlas 的导航入口。`)}><span aria-hidden="true">{item === "首页" ? "⌂" : item === "探索" ? "◈" : item === "片库" ? "▦" : item === "历史" ? "◷" : item === "资源" ? "◆" : "≋"}</span><b>{item}</b></button>)}</nav><button className="sidebar-user" type="button" onClick={() => onToast("Profile 承载设备与设置。 ")}><span>MI</span><b>Ming</b></button><button className="sidebar-logout" type="button" onClick={() => onNavigate("landing")}>退出</button></aside><div className="atlas-main"><header className="atlas-topbar"><span className="mobile-brand"><Brand full={false} /></span><p><span>ATLAS</span> / {active}</p><button className="atlas-search" type="button" onClick={() => onToast("搜索电影、剧集、演员、片单或资源。 ")}><Glyph>⌕</Glyph><b>搜索电影、剧集、演员、片单或资源</b><kbd>⌘ K</kbd></button><div className="atlas-actions"><button type="button" onClick={() => onToast("正式项目保留求资源入口。")}>求资源</button><button className="publish-button" type="button" onClick={() => onToast("正式项目保留发布资源入口。")}>＋ 发布资源</button><button className="avatar" type="button" onClick={() => onToast("打开 Profile。")}>MI</button></div></header><main className="atlas-content">{children}</main><nav className="mobile-nav" aria-label="移动端主导航">{["首页", "探索", "片库", "资源", "我的"].map((item) => <button key={item} type="button" className={active === item ? "is-current" : ""} onClick={() => onToast(`${item} 是正式 Atlas 的导航入口。`)}><span>{item === "首页" ? "⌂" : item === "探索" ? "◈" : item === "片库" ? "▦" : item === "资源" ? "◆" : "◎"}</span><b>{item}</b></button>)}</nav></div></div>;
}

function DetailPage({ onNavigate, onToast }) {
  const [tab, setTab] = useState("overview"); const [saved, setSaved] = useState(false); const [progress, setProgress] = useState(work.progress);
  function continueWatching() { setProgress((value) => Math.min(value + 6, 100)); onToast("原型：已打开已连接的 Infuse。 "); }
  return <AtlasShell active="作品" onNavigate={onNavigate} onToast={onToast}><section className="detail-page" data-screen-label="03 / Formal Media Detail"><button className="detail-back" type="button" onClick={() => onToast("原型：返回片库列表。 ")}><Glyph>←</Glyph> 返回上一页</button><section className="compact-hero"><div className="compact-backdrop" aria-hidden="true"></div><div className="compact-poster"><Poster art={work.posterArt} /><span>ATLAS</span></div><div className="compact-copy"><p className="atlas-kicker">{work.kind === "movie" ? "电影" : "剧集"} · {work.year} · {work.region}</p><h1>{work.title}</h1><h2>{work.originalTitle}</h2><div className="compact-meta"><span><b>{work.rating}</b> 评分</span><span><b>{work.tmdbRating}</b> TMDB</span><span>{work.genres.join(" · ")}</span><span>{work.runtime}</span></div><p className="compact-summary">{work.overview}</p><div className="compact-actions"><button className="atlas-button atlas-button--primary" type="button" onClick={continueWatching}>{progress > 0 && progress < 100 ? "▶ 播放器中继续" : "▶ 播放器中打开"}</button><button className={`atlas-button ${saved ? "is-on" : ""}`} type="button" onClick={() => { setSaved(!saved); onToast(saved ? "已从想看移除。" : "已加入想看。"); }}>＋ {saved ? "已在想看" : "想看"}</button><button className="square-action" type="button" onClick={() => onToast("已记录为已看。")}>✓</button></div></div><aside className="compact-state"><div><span>YOUR STATE</span><b>{progress}%</b></div><p>上次观看 · {work.last}</p><div className="state-progress"><i style={{ width: `${progress}%` }}></i></div><dl><div><dt>当前位置</dt><dd>{work.current}</dd></div><div><dt>播放器</dt><dd>Infuse · Apple TV</dd></div></dl><button type="button" onClick={continueWatching}>从这里继续 <Glyph>→</Glyph></button></aside></section><nav className="detail-tabs" role="tablist" aria-label="作品内容切换"><button type="button" role="tab" aria-selected={tab === "overview"} className={tab === "overview" ? "is-current" : ""} onClick={() => setTab("overview")}>总览</button><button type="button" role="tab" aria-selected={tab === "resources"} className={tab === "resources" ? "is-current" : ""} onClick={() => setTab("resources")}>Release 与资源 <span>{work.releaseCount}</span></button><button type="button" role="tab" aria-selected={tab === "cast"} className={tab === "cast" ? "is-current" : ""} onClick={() => setTab("cast")}>演职员</button><span>CATALOG KEY / {work.catalogKey}</span></nav>{tab === "overview" && <section className="overview-grid"><div className="overview-main"><div className="section-heading"><p>SYNOPSIS</p><h2>作品简介</h2></div><p className="overview-copy">{work.overview}</p><div className="metadata-grid"><div><span>导演</span><b>{work.director}</b></div><div><span>类型</span><b>{work.genres.join(" / ")}</b></div><div><span>地区</span><b>{work.region}</b></div><div><span>片长</span><b>{work.runtime}</b></div><div><span>首播年份</span><b>{work.year}</b></div><div><span>元数据来源</span><b>Tinue Core</b></div></div></div><aside className="overview-side"><div className="section-heading"><p>RESOURCE AVAILABILITY</p><h2>资源可用性</h2></div><div className="resource-summary"><strong>{work.resourceCount}</strong><span>个资源 · {work.releaseCount} 个 Release</span><small><i></i> 最近验证 {work.resourceFresh}</small><button type="button" onClick={() => setTab("resources")}>查看全部资源 <Glyph>↗</Glyph></button></div><div className="section-heading section-heading--cast"><p>CAST</p><h2>主要演员</h2></div>{work.cast.slice(0, 4).map((person, index) => <button key={person} className="cast-row" type="button" onClick={() => onToast(`正在搜索演员：${person}`)}><span>{String(index + 1).padStart(2, "0")}</span><b>{person}</b><em>↗</em></button>)}</aside></section>}{tab === "resources" && <section className="resources-view"><div className="resource-hierarchy"><div><span>WORK</span><b>{work.title}</b></div><i>→</i><div><span>RELEASE</span><b>{work.releaseCount} 个版本</b></div><i>→</i><div><span>RESOURCE</span><b>{work.resourceCount} 个来源</b></div></div><div className="resource-toolbar"><span>全部画质</span><button type="button" onClick={() => onToast("已按你的 Release 偏好排序。")}>按我的偏好排序 ↗</button></div><div className="release-rows">{releases.map((release) => <article key={release.title}><span className={`release-state ${release.state === "可用" ? "is-ready" : ""}`}></span><div><b>{release.title}</b><small>{release.detail}</small></div><div><b>{release.source}</b><small>{release.state}</small></div><button type="button" onClick={() => onToast(`${release.title} 已打开资源详情。`)}>↗</button></article>)}</div></section>}{tab === "cast" && <section className="cast-grid">{work.cast.map((person, index) => <button key={person} type="button" onClick={() => onToast(`正在搜索演员：${person}`)}><span>{String(index + 1).padStart(2, "0")}</span><b>{person}</b><small>演员</small><em>↗</em></button>)}<div><span>DIRECTOR</span><b>{work.director}</b><small>导演</small></div></section>}<footer className="atlas-footer"><Brand full={false} /><span>作品级片库 · Release · Resource · 观看状态</span><span>正式 Web 视觉合同</span></footer></section></AtlasShell>;
}

function Toast({ message }) { return message ? <div className="toast" role="status"><i>✓</i>{message}</div> : null; }

function App() { const hash = window.location.hash.replace("#", ""); const [screen, setScreen] = useState(SCREEN_META[hash] ? hash : "landing"); const [authMode, setAuthMode] = useState("register"); const [toast, setToast] = useState(""); useEffect(() => { window.history.replaceState(null, "", `#${screen}`); window.scrollTo({ top: 0, behavior: "smooth" }); }, [screen]); useEffect(() => { if (!toast) return undefined; const timer = window.setTimeout(() => setToast(""), 2600); return () => window.clearTimeout(timer); }, [toast]); function navigate(next, mode) { if (mode) setAuthMode(mode); setScreen(next); } return <div className={`prototype prototype--${screen}`}><PrototypeBar screen={screen} onChange={setScreen} /><main>{screen === "landing" && <LandingPage onNavigate={navigate} onToast={setToast} />}{screen === "auth" && <AuthPage mode={authMode} setMode={setAuthMode} onNavigate={navigate} onToast={setToast} />}{screen === "detail" && <DetailPage onNavigate={navigate} onToast={setToast} />}</main><Toast message={toast} /></div>; }

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
