import { useCallback, useEffect, useMemo, useState } from "react";
import { api, getToken, setToken } from "./api";
import { IconKitSvg } from "./components/IconKitSvg";
import type {
  AITask,
  Asset,
  BillingSummary,
  Ledger,
  ModelConfig,
  Product,
  Project,
  Team,
  TeamMember,
  User
} from "./types";
import { CornerMarks, Decorations, Sidebar, ToastLike } from "./components/app-shell";
import {
  AccountPage,
  AssetFactoryPage,
  AuthScreen,
  Dashboard,
  ImageWorkbenchPage,
  LibraryPage,
  MessagesPage,
  ModelPhotoDemoPage,
  PipelinePage,
  ProductCreateUploadPage,
  ProductDetailPage,
  ProductsPage,
  ProjectWizardPage,
  ProjectsPage,
  SettingsPage,
  TeamPage
} from "./routes";
import type { AuthMode, NavigateOptions, Notice, Page, ResolvedRoute } from "./routes/route-config";
import { pathForPage, resolveRoute, routeLabels } from "./routes/route-config";
import { money } from "./routes/stage-config";

const crumbLabels: Partial<Record<Page, string>> = {
  dashboard: "工作台",
  products: "商品库",
  productDetail: "商品详情",
  productCreateUpload: "新建商品",
  projects: "视频项目",
  projectWizard: "新建视频项目",
  pipeline: "生产管线",
  library: "资产库",
  account: "消费",
  team: "团队",
  messages: "消息中心",
  assetFactory: "图片生成",
  imageOptimize: "图片创作",
  modelPhoto: "模特上身图",
  modelPhotoDemoA: "模特图方案 A",
  modelPhotoDemoB: "模特图方案 B",
  platformCover: "平台套图",
  settings: "设置",
  settingsNotify: "设置"
};

export function App() {
  const [route, setRoute] = useState<ResolvedRoute>(() => resolveRoute());
  const page = route.page;
  const [authMode, setAuthMode] = useState<AuthMode>(route.authMode);
  const [authed, setAuthed] = useState<boolean>(() => Boolean(getToken()));
  const [booting, setBooting] = useState<boolean>(() => Boolean(getToken()));

  const [user, setUser] = useState<User | null>(null);
  const [team, setTeam] = useState<Team | null>(null);
  const [products, setProducts] = useState<Product[]>([]);
  const [projects, setProjects] = useState<Project[]>([]);
  const [assets, setAssets] = useState<Asset[]>([]);
  const [teamMembers, setTeamMembers] = useState<TeamMember[]>([]);
  const [modelConfigs, setModelConfigs] = useState<ModelConfig[]>([]);
  const [aiTasks, setAiTasks] = useState<AITask[]>([]);
  const [billing, setBilling] = useState<BillingSummary | null>(null);
  const [ledgers, setLedgers] = useState<Ledger[]>([]);
  const [projectDetail, setProjectDetail] = useState<Project | null>(null);

  const [activeProductId, setActiveProductId] = useState(route.productId || "");
  const [activeProjectId, setActiveProjectId] = useState(route.projectId || "");
  const [notice, setNotice] = useState<Notice>(null);
  const [loading, setLoading] = useState(false);

  const activeProject = useMemo(
    () => projects.find((project) => project.id === activeProjectId) || projects[0],
    [projects, activeProjectId]
  );
  const activeProduct = useMemo(
    () => products.find((product) => product.id === activeProductId) || products[0],
    [products, activeProductId]
  );

  const loadData = useCallback(async () => {
    const [productData, projectData, assetData, billingData, ledgerData, memberData, modelData, taskData] =
      await Promise.all([
        api.products(),
        api.projects(),
        api.assets(),
        api.billingSummary().catch(() => null),
        api.ledgers().catch(() => []),
        api.teamMembers().catch(() => []),
        api.modelConfigs().catch(() => null),
        api.aiTasks().catch(() => null)
      ]);
    setProducts(productData.results);
    setProjects(projectData.results);
    setAssets(assetData.results);
    setTeamMembers(memberData);
    setModelConfigs(modelData?.results || []);
    setAiTasks(taskData?.results || []);
    if (billingData) setBilling(billingData);
    setLedgers(ledgerData);
    setActiveProjectId((current) => current || projectData.results[0]?.id || "");
    setActiveProductId((current) => current || productData.results[0]?.id || "");
  }, []);

  // Boot: validate token, hydrate identity + data.
  useEffect(() => {
    if (!getToken()) {
      setBooting(false);
      return;
    }
    let cancelled = false;
    (async () => {
      try {
        const identity = await api.me();
        if (cancelled) return;
        setUser(identity.user);
        setTeam(identity.team);
        await loadData();
      } catch {
        setToken(null);
        if (!cancelled) setAuthed(false);
      } finally {
        if (!cancelled) setBooting(false);
      }
    })();
    return () => {
      cancelled = true;
    };
  }, [loadData]);

  // Keep route in sync with browser navigation.
  useEffect(() => {
    function syncRouteFromHistory() {
      const next = resolveRoute();
      setRoute(next);
      setAuthMode(next.authMode);
      if (next.productId !== undefined) setActiveProductId(next.productId);
      if (next.projectId !== undefined) setActiveProjectId(next.projectId);
    }
    window.addEventListener("popstate", syncRouteFromHistory);
    return () => window.removeEventListener("popstate", syncRouteFromHistory);
  }, []);

  // Load full project detail when entering the pipeline.
  useEffect(() => {
    if (!authed || page !== "pipeline" || !activeProjectId) {
      if (page !== "pipeline") setProjectDetail(null);
      return;
    }
    let cancelled = false;
    api
      .project(activeProjectId)
      .then((detail) => {
        if (!cancelled) setProjectDetail(detail);
      })
      .catch(() => undefined);
    return () => {
      cancelled = true;
    };
  }, [authed, page, activeProjectId]);

  function navigate(next: Page, options: NavigateOptions = {}) {
    const productId = options.productId ?? activeProductId;
    const projectId = options.projectId ?? activeProjectId;
    if (options.productId !== undefined) setActiveProductId(options.productId);
    if (options.projectId !== undefined) setActiveProjectId(options.projectId);
    const hash = options.hash?.replace(/^#/, "");
    setRoute({ page: next, authMode, productId, projectId, hash });
    const path = `${pathForPage(next, { productId, projectId })}${hash ? `#${hash}` : ""}`;
    if (`${window.location.pathname}${window.location.hash}` !== path || window.location.search) {
      const method = options.replace ? "replaceState" : "pushState";
      window.history[method](null, "", path);
    }
    window.scrollTo({ top: 0, behavior: "auto" });
  }

  async function refreshProjectDetail() {
    if (!activeProjectId) return;
    const detail = await api.project(activeProjectId).catch(() => null);
    if (detail) setProjectDetail(detail);
  }

  async function action<T>(work: () => Promise<T>, successText: string): Promise<T | null> {
    setLoading(true);
    setNotice(null);
    try {
      const result = await work();
      setNotice({ type: "success", text: successText });
      await loadData();
      await refreshProjectDetail();
      return result;
    } catch (error) {
      setNotice({ type: "error", text: error instanceof Error ? error.message : "操作失败" });
      return null;
    } finally {
      setLoading(false);
    }
  }

  function onAuthed(payload: { token: string; user: User; team: Team }) {
    setToken(payload.token);
    setUser(payload.user);
    setTeam(payload.team);
    setAuthed(true);
    setBooting(true);
    loadData().finally(() => setBooting(false));
    navigate("dashboard", { replace: true });
  }

  async function logout() {
    await api.logout().catch(() => undefined);
    setToken(null);
    setAuthed(false);
    setUser(null);
    setTeam(null);
    setAuthMode("login");
    window.history.replaceState(null, "", "/login");
  }

  // ---- Auth gate ----
  if (!authed) {
    return (
      <AuthScreen
        initialMode={authMode}
        onModeChange={(next) => {
          setAuthMode(next);
          window.history.pushState(null, "", next === "register" ? "/register" : "/login");
        }}
        onAuthed={onAuthed}
      />
    );
  }

  if (booting || !user || !team) {
    return (
      <div className="app">
        <main>
          <div className="content">
            <div className="page-head">
              <div>
                <h1>加载中…</h1>
                <div className="sub">
                  <span className="mono">// 正在拉取团队数据</span>
                </div>
              </div>
            </div>
          </div>
        </main>
      </div>
    );
  }

  const currentUser: User = user;
  const currentTeam: Team = team;

  function renderPage() {
    switch (page) {
      case "dashboard":
        return <Dashboard products={products} projects={projects} assets={assets} billing={billing} userName={currentUser.username} navigate={navigate} />;
      case "products":
        return (
          <ProductsPage
            products={products}
            navigate={navigate}
            openProduct={(productId) => navigate("productDetail", { productId })}
            onCreate={(payload) => action(() => api.createProduct(payload), "商品已创建")}
          />
        );
      case "productCreateUpload":
        return (
          <ProductCreateUploadPage
            onCreate={async (payload) => {
              const created = await action(() => api.createProduct(payload), "商品已创建");
              if (created) navigate("productDetail", { productId: created.id });
            }}
            onBack={() => navigate("products")}
          />
        );
      case "productDetail":
        if (!activeProduct) return <ProductsPage products={products} navigate={navigate} openProduct={(productId) => navigate("productDetail", { productId })} onCreate={(payload) => action(() => api.createProduct(payload), "商品已创建")} />;
        return (
          <ProductDetailPage
            product={activeProduct}
            projects={projects.filter((project) => project.product === activeProduct.id)}
            navigate={navigate}
            onUpdate={(payload) => action(() => api.updateProduct(activeProduct.id, payload), "商品已更新")}
          />
        );
      case "projects":
        return (
          <ProjectsPage
            products={products}
            projects={projects}
            navigate={navigate}
            onCreate={(payload) => action(() => api.createProject(payload), "项目已创建")}
            openPipeline={(projectId) => navigate("pipeline", { projectId })}
            onDelete={(projectId) => action(() => api.deleteProject(projectId), "项目已删除")}
          />
        );
      case "projectWizard":
        return (
          <ProjectWizardPage
            products={products}
            onBack={() => navigate("projects")}
            onCreate={async (payload) => {
              const created = await action(() => api.createProject(payload), "项目已创建");
              if (created) navigate("pipeline", { projectId: created.id });
            }}
          />
        );
      case "pipeline":
        // 有项目时由下方 full-screen 特例渲染;这里只兜底「暂无项目」
        return (
          <div className="page-head">
            <div>
              <h1>暂无项目</h1>
              <div className="sub">
                <span className="mono">// 先创建一个视频项目</span>
              </div>
            </div>
            <div className="actions">
              <button className="btn btn-primary" type="button" onClick={() => navigate("projectWizard")}>
                新建视频项目
              </button>
            </div>
          </div>
        );
      case "library":
        return <LibraryPage assets={assets} onUpload={(formData) => action(() => api.uploadAsset(formData), "资产已上传")} />;
      case "account":
        return <AccountPage billing={billing} ledgers={ledgers} projects={projects} teamMembers={teamMembers} />;
      case "team":
        return <TeamPage team={currentTeam} user={currentUser} members={teamMembers} billing={billing} navigate={navigate} />;
      case "messages":
        return <MessagesPage navigate={navigate} />;
      case "assetFactory":
        return <AssetFactoryPage navigate={navigate} aiTasks={aiTasks} />;
      case "imageOptimize":
        return <ImageWorkbenchPage mode="image" products={products} assets={assets} modelConfigs={modelConfigs} onBack={() => navigate("assetFactory")} navigate={navigate} />;
      case "modelPhoto":
        return <ImageWorkbenchPage mode="model" products={products} assets={assets} modelConfigs={modelConfigs} onBack={() => navigate("assetFactory")} navigate={navigate} />;
      case "platformCover":
        return <ImageWorkbenchPage mode="cover" products={products} assets={assets} modelConfigs={modelConfigs} onBack={() => navigate("assetFactory")} navigate={navigate} />;
      case "modelPhotoDemoA":
        return <ModelPhotoDemoPage variant="A" products={products} onBack={() => navigate("modelPhoto")} />;
      case "modelPhotoDemoB":
        return <ModelPhotoDemoPage variant="B" products={products} onBack={() => navigate("modelPhoto")} />;
      case "settings":
        return <SettingsPage user={currentUser} team={currentTeam} />;
      case "settingsNotify":
        return <SettingsPage user={currentUser} team={currentTeam} initialSection="notify" />;
      default:
        return <Dashboard products={products} projects={projects} assets={assets} billing={billing} navigate={navigate} />;
    }
  }

  const avatarChar = (currentTeam.name || currentUser.username || "A").slice(0, 1).toUpperCase();
  const here = crumbLabels[page] || routeLabels[page] || "工作台";

  // 生产管线 · 全屏 bespoke 布局(自带顶栏 + 步进器),脱离常规 shell
  const pipelineProject = projectDetail || activeProject;
  if (page === "pipeline" && pipelineProject) {
    return (
      <PipelinePage
        project={pipelineProject}
        loading={loading}
        navigate={navigate}
        user={currentUser}
        team={currentTeam}
        products={products}
        projects={projects}
        billing={billing}
        notice={notice}
        avatarChar={avatarChar}
        logout={logout}
        onRefresh={refreshProjectDetail}
        onGenerateScript={(prompt) => action(() => api.generateScript(pipelineProject.id, { prompt }), "脚本已生成")}
        onAdoptScript={(scriptId) => action(() => api.adoptScript(pipelineProject.id, scriptId), "脚本已采用")}
        onGenerateBaseAsset={(kind, prompt) => action(() => api.generateBaseAsset(pipelineProject.id, { kind, prompt }), "基础资产已生成")}
        onGenerateStoryboard={(prompt) => action(() => api.generateStoryboard(pipelineProject.id, { prompt }), "故事板已生成")}
        onSkipStoryboard={() => action(() => api.skipStoryboard(pipelineProject.id), "已跳过故事板")}
        onSubmitVideo={(segmentId, prompt) => action(() => api.submitVideo(pipelineProject.id, { video_segment_id: segmentId, prompt }), "视频片段已提交")}
        onPollVideo={(segmentId) => action(() => api.pollVideo(pipelineProject.id, segmentId), "片段状态已刷新")}
        onSubmitAllVideos={(prompt) =>
          action(async () => {
            const targets = pipelineProject.video_segments.filter((segment) => !["running", "succeeded"].includes(segment.status));
            for (const segment of targets) {
              await api.submitVideo(pipelineProject.id, {
                video_segment_id: segment.id,
                prompt: `${prompt} 第 ${segment.sort_order + 1} 段，时长 ${segment.target_duration_seconds} 秒`
              });
            }
            return targets.length;
          }, "60s 多段视频任务已提交")
        }
        onPollAllVideos={() =>
          action(async () => {
            const targets = pipelineProject.video_segments.filter((segment) => ["running", "queued"].includes(segment.status));
            for (const segment of targets) {
              await api.pollVideo(pipelineProject.id, segment.id).catch(() => undefined);
            }
            return targets.length;
          }, "视频片段状态已刷新")
        }
        onSubmitExport={() => action(() => api.submitExport(pipelineProject.id), "导出任务已提交")}
      />
    );
  }

  return (
    <div className="app">
      <Sidebar page={page} navigate={navigate} user={currentUser} team={currentTeam} products={products} projects={projects} />
      <main>
        <Decorations />
        <header className="topbar">
          <div className="crumbs">
            {page === "dashboard" ? (
              <span className="here">工作台</span>
            ) : (
              <>
                <a href="/dashboard" onClick={(event) => { event.preventDefault(); navigate("dashboard"); }}>工作台</a>
                <span className="sep">/</span>
                <span className="here">{here}</span>
              </>
            )}
          </div>
          <div className="right">
            <span className="balance-chip" onClick={() => navigate("account")}>
              <IconKitSvg name="creditCard" />
              余额 <strong>{money(billing?.account.balance)}</strong>
            </span>
            <button className="icon-btn" type="button" onClick={() => navigate("messages")} title="消息中心">
              <IconKitSvg name="bell" />
              <span className="count-noti">12</span>
            </button>
            <div className="topbar-avatar" onDoubleClick={logout} title="账户(双击退出)">
              <span>{avatarChar}</span>
            </div>
          </div>
        </header>
        <div className="content" id="page-content">
          <CornerMarks />
          {notice && <ToastLike notice={notice} />}
          {renderPage()}
        </div>
      </main>
    </div>
  );
}
