import { useEffect, useMemo, useRef, useState } from "react"; import { useRouter } from "next/router"; import IncomeDistribution from "./IncomeDistribution"; import { categorySummary, evidenceUrl, technicalReviewLabels, reviewCompanyIds, type ResearchEvidence, type ResearchReview, type ResearchSnapshot, } from "@/lib/ai-research"; const pageSize = 12; const evidencePageSize = 30; const revenueLabels = { self: "公司披露,待核口径", estimate: "仅第三方估算", platform: "仅支付平台记录", unknown: "暂无可用收入数字" }; const useLabels: Record = { platform: "支付平台记录", signal: "公司披露信号", estimate: "第三方估算", historical: "历史里程碑", "historical-estimate": "其他时点估算", excluded: "排除收入比较", scale: "团队规模", adoption: "采用规模", funding: "融资", technical: "第三方技术评测", crosscheck: "同一里程碑的其他资料", }; const money = (value: number, unit = "USD") => unit === "USD" ? new Intl.NumberFormat("zh-CN", { style: "currency", currency: "USD", maximumFractionDigits: 0 }).format(value) : `${new Intl.NumberFormat("zh-CN").format(value)} ${unit}`; function External({ url, children }: { url: string; children: React.ReactNode }) { const safe = evidenceUrl(url); return safe ? {children} ↗ : {children}; } function Evidence({ item, prefix = "evidence" }: { item: ResearchEvidence; prefix?: string }) { return
  • {item.id}{item.kind}
    {item.title}

    {item.summary}

    {item.limitation}

    发布:{item.publishedAt ?? "未注明"} 读取:{item.accessedAt}
  • ; } export default function AICompanyResearch() { const router = useRouter(); const [data, setData] = useState(null); const [error, setError] = useState(false); const [attempt, setAttempt] = useState(0); const [query, setQuery] = useState(""); const [categoryChoice, setCategoryChoice] = useState<{ route: string; id: string } | null>(null); const linkedCategory = router.query.category; const category = categoryChoice && categoryChoice.route === router.asPath ? categoryChoice.id : router.isReady && typeof linkedCategory === "string" && data?.categories.some((c) => c.id === linkedCategory) ? linkedCategory : ""; function setCategory(id: string) { setCategoryChoice({ route: router.asPath, id }); } const [cohort, setCohort] = useState(""); const [income, setIncome] = useState(""); const [page, setPage] = useState(0); const [sourcePage, setSourcePage] = useState(0); const [depth, setDepth] = useState(""); const [teamBand, setTeamBand] = useState(""); const [technicalLevel, setTechnicalLevel] = useState(""); const [selection, setSelection] = useState<{ route: string; id: string | null } | null>(null); const linkedCompany = router.query.company; const selected = selection && selection.route === router.asPath ? selection.id : router.isReady && typeof linkedCompany === "string" && data?.companies.some((c) => c.id === linkedCompany) ? linkedCompany : null; function setSelected(id: string | null) { setSelection({ route: router.asPath, id }); } const [tab, setTab] = useState<"companies" | "revenue" | "sources" | "reviews">("companies"); const companySection = useRef(null); const detailSection = useRef(null); useEffect(() => { const controller = new AbortController(); fetch("/api/research/ai-companies", { signal: controller.signal, cache: "no-store" }) .then(async (response) => { if (!response.ok) throw new Error("Research unavailable"); const snapshot: ResearchSnapshot = await response.json(); setData(snapshot); }).catch(() => { if (!controller.signal.aborted) setError(true); }); return () => controller.abort(); }, [attempt]); useEffect(() => { if (selected) detailSection.current?.focus(); }, [selected]); const summaries = useMemo(() => data ? categorySummary(data) : [], [data]); const filtered = useMemo(() => data?.companies.filter((c) => { const search = `${c.name} ${c.business} ${c.location ?? ""} ${c.buyer}`.toLocaleLowerCase(); const yearMatch = !cohort || (cohort === "other" ? ![2025, 2026].includes(c.year ?? 0) : c.year === Number(cohort)); const depthMatch = !depth || (depth === "profile" ? c.profileOnly : !c.profileOnly); const teamMatch = !teamBand || (teamBand === "unknown" ? c.team === null || (!!c.teamBound && c.team < 51) : c.team !== null && (teamBand === "xl" ? c.team >= 51 : !c.teamBound && (teamBand === "small" ? c.team <= 5 : teamBand === "medium" ? c.team >= 6 && c.team <= 20 : c.team >= 21 && c.team <= 50))); return (!technicalLevel || (c.technicalReview?.level ?? "unreviewed") === technicalLevel) && depthMatch && teamMatch && (!category || c.cat === category) && yearMatch && (!income || c.revenueStatus === income) && search.includes(query.trim().toLocaleLowerCase()); }) ?? [], [data, query, category, cohort, income, depth, teamBand, technicalLevel]); if (error) return
    研究数据库暂时不可用。
    ; if (!data) return

    正在读取研究数据库…

    ; const categories = new Map(data.categories.map((c) => [c.id, c])); const selectedCompany = data.companies.find((c) => c.id === selected); const observed = data.observations.filter((o) => ["signal", "estimate"].includes(o.selection)); const disclosedCompanies = new Set(observed.map((o) => o.company)).size; const revenueCompanies = data.companies.filter((c) => c.revenueStatus !== "unknown").length; const selectedObservations = data.observations.filter((o) => o.company === selected); const selectedEvidenceIds = new Set([ ...(selectedCompany?.evidenceIds ?? []), ...(selectedCompany?.pricingEvidence ? [selectedCompany.pricingEvidence] : []), ...(selectedCompany?.technicalReview?.evidenceIds ?? []), ...selectedObservations.map((o) => o.evidence), ]); const selectedEvidence = data.evidence.filter((e) => e.companyId === selected || selectedEvidenceIds.has(e.id)); const reviewCompanies = (review: ResearchReview) => { const ids = new Set(reviewCompanyIds(data, review)); return data.companies.filter((c) => ids.has(c.id)); }; const selectedReviews = data.reviews.filter((r) => selected && reviewCompanyIds(data, r).includes(selected)); function chooseCategory(id: string) { setCategory(id); setPage(0); setTab("companies"); companySection.current?.scrollIntoView({ behavior: "smooth", block: "start" }); } return
    资料截至 {data.asOf}首批研究 · 持续补全
    {data.companies.length}公司/产品记录
    {data.categories.length}业务类别
    {revenueCompanies}有收入线索的记录
    {data.evidence.length}证据记录

    {data.scope}

    {data.coverage &&

    YC 候选池 {data.coverage.candidateRecords} 条,官方页面读取 {data.coverage.profilesRead} 条;初筛匹配 {data.coverage.matchingProfiles} 条,新增 {data.coverage.newProfiles} 条目录记录。年份不符或缺失 {data.coverage.otherOrMissingYear} 条、AI 业务待确认 {data.coverage.unclearAI} 条、日期冲突 {data.coverage.dateConflicts} 条。目录基础资料尚未逐家核验收入和交付能力。

    }
    数据口径与覆盖限制
      {data.limitations.map((note) =>
    • {note}
    • )}

    来源以 YC、公司官网、投资机构名录与经营案例为主。同一披露的转载不构成独立验证。团队人数包含公司自报的 Team Size,与正式员工口径可能不同。

    业务分类

    点击类别查看对应公司。数量反映本次采集覆盖,不是市场份额。

    {summaries.map((c) => )}

    研究数据

    {([['companies','公司与产品'],['revenue','收入观测'],['sources','原始证据'],['reviews','核查记录']] as const).map(([id,label]) => )}
    {tab === "companies" && <>

    技术验证层级记录我们查到了什么,不是能力强弱评分。技术专项评审与业务分类复核分别记录。

    {filtered.length} 条匹配记录
    {filtered.slice(page * pageSize, (page + 1) * pageSize).map((c) => )}
    公司/产品分类与经营资料。选择名称查看指标和原始证据。
    公司或产品 / 地区业务与买家成立 / 发布组别团队规模交付与技术验证证据收入资料
    {c.location ?? "地区未注明"} {categories.get(c.cat)?.name}{c.profileOnly && 目录基础资料 · 分类依据见明细}

    {c.business}

    买家:{c.buyer}
    {c.cohort}{c.team !== null && c.teamBound}{c.team ?? "未披露"}{c.team !== null && " 人"}{c.stage}{technicalReviewLabels[c.technicalReview?.level ?? "unreviewed"]}{c.profileOnly ? "收入尚未逐一核验" : revenueLabels[c.revenueStatus]}
    {!filtered.length &&

    没有匹配公司,请调整筛选条件。

    } {filtered.length > pageSize && } } {tab === "revenue" && <>

    公司披露与估算的历史里程碑

    这一组包含 {disclosedCompanies} 家公司的披露或估算信号,多为异时点历史里程碑,ARR 与年化收入口径仍待核对,暂不计算其同期领域均值。币种未确认的记录仅显示原值,不绘制美元长度条。上面的平台MRR统计与这一组分开。

    {observed.map((o) =>
    {o.bound !== "=" && o.bound}{money(o.value, o.unit)}
    {o.unit === "USD" && } {o.kind} · {useLabels[o.selection]} · {o.timing}
    )}
    {summaries.map((c) => )}
    当前研究数据中的收入可得性,目录项未逐一检索;未建立同期、同龄、同口径比较组
    业务分类公司披露数仅估算数仅平台数暂无可用数字同期均值 / 离散度
    {c.self}{c.estimate}{c.platform}{c.unknown}条件不足

    离散度用于筛选值得核查的异常,还需排除公司年龄、口径和披露偏差;不能据此认定财务造假。

    } {tab === "sources" && <>

    来源链接保留原始位置。相同 URL 的记录可能属于同一披露,不能按记录数计算独立证据数量。

      {data.evidence.slice(sourcePage * evidencePageSize, (sourcePage + 1) * evidencePageSize).map((e) => )}
    {data.evidence.length > evidencePageSize && }} {tab === "reviews" &&
      {data.reviews.map((r) =>
    • {r.type}

      {r.company}

      {r.scope === "dataset" && 全局数据方法核查}{r.scope === "excluded-candidate" && 未纳入公司表的候选}

      {r.summary}

      {r.handling}

      {reviewCompanies(r).map((c) => )}
      {r.evidenceIds.map((id) => { const e=data.evidence.find((item) => item.id === id); return e ? {id} : null; })}
    • )}
    }
    {selectedCompany &&

    {selectedCompany.name}

    资料入口 {selectedCompany.extraUrl && 额外核验入口}

    主营业务
    {selectedCompany.business}
    样本组别
    {selectedCompany.cohort}
    买家
    {selectedCompany.buyer}
    收费/交付模式
    {selectedCompany.businessModel ?? "待进一步核验"}
    收费方式
    {selectedCompany.price}
    交付证据
    {selectedCompany.delivery}
    团队口径
    {selectedCompany.teamBasis ?? "本轮未核验人数"}
    分类依据
    {selectedCompany.classificationBasis ?? "原有个案分类;随研究复核"}
    技术验证证据
    {technicalReviewLabels[selectedCompany.technicalReview?.level ?? "unreviewed"]}

    {selectedCompany.technicalReview?.summary ?? "本轮未形成专项技术评审记录;不表示公司没有技术能力。"}

    {selectedCompany.technicalReview && 评审日期:{selectedCompany.technicalReview.reviewedAt}}{selectedCompany.technicalReview?.testScope &&

    测试范围:{selectedCompany.technicalReview.testScope}

    }

    材料可访问仅确认可查看,不证明性能、可靠性或商业交付质量;不同任务不作统一能力排名。

    观测主体
    {selectedCompany.entityBasis ?? "公司或经营品牌,法律主体未逐一核验"}
    身份与限制
    {selectedCompany.notes}

    经营与技术观测

    {!!selectedReviews.length &&
    关联核查记录({selectedReviews.length})
      {selectedReviews.map((r) =>
    • {r.type}:{r.summary}

      {r.handling}

      {r.evidenceIds.map((id) => { const item = data.evidence.find((e) => e.id === id); return item ? {id} : null; })}
    • )}
    } {selectedObservations.length ?
    {selectedObservations.map((o) => )}
    指标 / 归属原始数值数据时点用途及限制证据
    {o.kind}{o.scope}{o.bound !== "=" && o.bound}{money(o.value,o.unit)}{o.timing}{useLabels[o.selection] ?? o.selection}{o.reason}{o.evidence}
    :

    本轮尚未找到可记录的量化经营指标。收入保持未知。

    }

    原始证据

      {selectedEvidence.map((e) => )}
    }

    数据版本 {data.version}。当前为首批资料,覆盖、收入定义、财务透明度与商业模式评估将随核验补充。

    ; }