// guide.jsx
const GUIDE_SECTIONS = [
  {
    id: 'quick-start',
    title: '快速开始',
    label: '开始',
    summary: '新同事第一次进入 CRM 时，按这个顺序处理一条线索。',
    tags: ['登录', '首页', '线索', '客户', 'Customers', '负责人', '跟进', '报价单', '发票', 'Invoice'],
    actions: [{ label: '去线索列表', page: 'leads' }],
    steps: [
      '登录 CRM，先看首页的今日跟进、本周新线索和需处理线索。',
      '进入线索列表，打开客户详情面板。',
      '检查客户资料、来源、产品意向和联系方式。',
      '分配负责人，设置下次跟进日期。',
      '添加跟进记录，写清楚客户关注点、下一步和预计时间。',
      '如果客户后续会重复报价或开票，先保存成 Customers / 客户资料。',
      '客户需求明确后，从线索创建报价单并下载 Commercial Proposal。',
      '报价确认后，从报价单创建发票，签发并记录收款。',
    ],
  },
  {
    id: 'sources',
    title: '线索来源',
    label: '来源',
    summary: '来源用于判断客户从哪里进入 CRM，sourcePage 用于保留更具体的页面路径。',
    tags: ['cloudmate.ai', 'seed26.com', '手动创建', 'source', 'sourcePage'],
    actions: [{ label: '查看报表来源', page: 'reports' }],
    steps: [
      'cloudmate.ai 表示客户从 Cloudmate 网站进入。',
      'seed26.com 表示客户从 Seed26 网站进入。',
      '手动创建适合聊天工具、转介绍、线下沟通等没有表单的客户。',
      'source 是线索来源，sourcePage 是来源页面路径。不要把页面路径当成来源覆盖掉。',
    ],
  },
  {
    id: 'lead-processing',
    title: '处理线索',
    label: '线索',
    summary: '日常销售动作主要围绕搜索、筛选、打开 drawer、修改资料和安排跟进。',
    tags: ['搜索', '筛选', 'drawer', '联系人', '状态', '负责人', '跟进日期'],
    actions: [{ label: '去线索列表', page: 'leads' }],
    steps: [
      '使用搜索框查找姓名、公司、邮箱或电话。',
      '用状态、产品、负责人、来源筛选缩小范围。',
      '点击线索行打开右侧 drawer。',
      '确认联系人资料和公司信息是否完整。',
      '修改状态、负责人和下次跟进日期。',
      '如果这家公司后续还会报价或开票，点击 Save as Customer / 保存为客户。',
      '保存前确认筛选条件没有误导你当前看到的线索范围。',
    ],
  },
  {
    id: 'customers',
    title: '客户资料 / Customers',
    label: '客户',
    summary: 'Customer 是可复用客户档案；Lead 是线索来源。报价和发票可以搜索已有客户并带入资料。',
    tags: ['客户', 'Customers', 'Customer picker', 'Save as Customer', 'TG', 'Telegram', 'WhatsApp', 'WeChat', 'Phone', 'Email'],
    actions: [{ label: '去客户资料', page: 'customers' }],
    steps: [
      '左侧进入 Customers / 客户，可搜索公司、联系人、邮箱或联系方式。',
      '没有记录时，用 New Customer / 新增客户创建客户档案。',
      '联系方式支持 Phone、Telegram、WhatsApp、WeChat、Line、Email、Website 和 Other。',
      '从 lead drawer 点击 Save as Customer / 保存为客户时，系统会按邮箱或公司尝试复用已有客户。',
      '开报价单或发票时，先搜索已有客户；没有记录再新增。报价单新建弹窗支持直接从 Customer 创建报价单。',
      '公司名是列表和搜索里最重要的显示名，能填就填。',
    ],
  },
  {
    id: 'follow-up',
    title: '跟进记录',
    label: '跟进',
    summary: '跟进记录是交接和复盘的核心，建议每次客户互动后立刻记录。',
    tags: ['note', 'call', 'email', 'meeting', '模板', '下一步'],
    actions: [{ label: '去我的任务', page: 'tasks' }],
    steps: [
      'note 适合一般备注，call 适合电话，email 适合邮件，meeting 适合会议。',
      '推荐备注模板：客户关注：',
      '推荐备注模板：下一步：',
      '推荐备注模板：预计时间：',
      '如果只是补充背景，用提交备注；如果刚完成客户互动，用保存跟进。',
    ],
  },
  {
    id: 'opportunity',
    title: '商机 / Opportunity',
    label: '商机',
    summary: '简单理解为 Lead / Customer -> Opportunity -> Quotation -> Invoice：线索确认有效后，商机承接销售金额和阶段。',
    tags: ['商机', 'Opportunity', 'Lead', 'Customer', 'Quotation', 'Invoice', '金额', '阶段'],
    actions: [{ label: '去商机列表', page: 'opportunities' }],
    steps: [
      'Lead 是客户进入 CRM 的原始线索。',
      'Customer 是可复用客户资料，方便之后报价和开票。',
      'Opportunity 是可以推进的销售机会，记录金额、阶段、预计成交日期和负责人。',
      'Quotation 是基于商机或线索生成的正式商业报价文件。',
      'Invoice 是报价确认后的财务文件和收款追踪。',
      '如果一条线索还没有商机，创建报价单时系统会自动关联或创建开放商机。',
    ],
  },
  {
    id: 'quotation',
    title: '报价单 / Commercial Proposal',
    label: '报价',
    summary: '报价工作台用于生成客户可读的 Commercial Proposal，不要发送空报价或未检查的报价。',
    tags: ['报价单', 'Commercial Proposal', 'Customer picker', 'Issuing Company', 'Document Language', 'Shared Package Catalog', '共享套餐库', 'Product Platform', 'Included Usage', 'Excess Usage Pricing', 'Cloudflare terms', '折扣', 'Grand Total'],
    actions: [{ label: '去报价单', page: 'quotations' }],
    steps: [
      '从线索详情创建报价单，或进入报价单页面新建。',
      '在新建弹窗选择 From Lead / 从线索 或 From Customer / 从客户；客户资料不存在时可先新增客户再创建报价单。',
      '打开报价工作台后，在 Customer picker 搜索并确认已有客户；如果没有记录，可用当前客户资料新增客户。',
      '打开报价工作台，确认客户、公司、币种、账单周期（支持月付、季付、半年付、年付、一次性和自定义）、付款方式、服务计量周期和有效期。',
      '选择 Issuing Company：Cloudmate Pte. Ltd. 或 Seed26。',
      '选择 Document Language：English 或 简体中文。',
      '添加产品或服务明细，检查数量、单价、折扣、税率和 Grand Total。',
      '如销售套餐，可在 Shared Package Catalog / 共享套餐库选择 Product Platform（Cloudflare、ChinaCDN1、AWS）和 Pack 1 / Pack 2 / Pack 3。',
      'Package / 套餐只会插入可编辑的计价行、Included Resources 和 Excess Usage Pricing；不是 checkout 或 purchase flow。',
      '在服务范围 / Included Usage 中填写已包含资源；这些行只进入客户文件，不参与报价总额。',
      '在 Excess Usage Pricing 中填写超额用量价格；除非之后明确转成计费项目，否则不参与报价总额。',
      '如果报价包含 Cloudflare / CF / CDN / WAF / DDoS / Bot Management / Argo / Rate Limiting，Cloudflare terms 会随 proposal 加入，也可以手动关闭。',
      '下载 Commercial Proposal 前确认没有空行、空金额或错误报价主体；客户文件可下载 Excel 或 PDF，PDF 需要至少一个产品或服务明细。',
    ],
  },
  {
    id: 'invoice',
    title: '发票 / Invoice',
    label: '发票',
    summary: '发票是 Invoice -> Payment 的独立财务流程，可直接新建，也可由报价单创建。',
    tags: ['发票', 'Invoice', 'Customer picker', 'New Invoice', 'Create Invoice', 'Issue Invoice', 'Record Payment', 'Download PDF', 'Delete Draft', 'Void Invoice', 'CM-INV', 'S26-INV'],
    actions: [{ label: '去发票', page: 'invoices' }],
    steps: [
      '可在 Invoices / 发票 页面点击 New Invoice / 新建发票直接创建 draft，也可在报价工作台确认商业计价行和 Grand Total 后点击 Create Invoice。',
      '进入 Invoices / 发票 页面，可按 status、issuer、overdue 和 customer search 筛选。',
      '打开发票详情后，先用 Customer picker 选择已有客户；没有记录时可用当前 Bill To 新增客户。',
      '打开发票详情后，检查 Invoice No.、Invoice Date、Due Date、Billing Period、Payment Term、Service Period、Bill To、Issuer、Items、Payment Instructions、Total Due 和 Balance Due。Draft 可以编辑客户资料、明细和付款说明。',
      '直接开票时可在 Product / Package 选择 Cloudflare、ChinaCDN1 或 AWS 的 Package；系统会插入收费 item，并带出可编辑的 Included Usage 和 Excess Usage Pricing 服务范围说明。',
      'Payment Instructions 会按开票主体带出预设文案；draft 发票可以按客户或付款渠道自定义，也可以恢复预设。',
      '点击 Issue Invoice 签发；签发后的发票不能直接编辑。',
      '客户付款后，用 Record Payment 记录金额、日期、方式和参考号。',
      'Balance Due 为 0 时，发票状态会变成 paid。',
      '未签发的 draft 可用 Delete Draft 删除；需要取消已签发发票时先使用 Void Invoice，作废后确认不需要保留可用 Delete Void 删除。',
      'Download PDF 只返回真实 PDF；如果后端 Browser Run 未配置，会显示 unavailable。',
      'Cloudmate 发票编号为 CM-INV-YYYY-NNNN；Seed26 发票编号为 S26-INV-YYYY-NNNN。',
    ],
  },
  {
    id: 'tasks-reports',
    title: '任务与报表',
    label: '任务',
    summary: '任务页面负责日常跟进节奏，报表页面负责看整体销售情况。',
    tags: ['今日跟进', '超时未处理', '高优先级', '报表', '时间范围'],
    actions: [
      { label: '去我的任务', page: 'tasks' },
      { label: '去报表', page: 'reports' },
    ],
    steps: [
      '今日跟进显示今天应该处理的客户。',
      '超时未处理提醒新线索或高优先级线索没有及时推进。',
      '高优先级线索应优先分配负责人和下次跟进日期。',
      '报表分析可切换时间范围，查看来源、状态、产品和区域分布。',
    ],
  },
  {
    id: 'admin',
    title: '管理员功能',
    label: '管理员',
    summary: '这些动作只适合管理员操作，会影响团队成员、产品选项或数据保留。',
    tags: ['成员管理', '产品管理', '已丢单', '删除', 'admin-only'],
    adminOnly: true,
    actions: [
      { label: '成员管理', page: 'members' },
      { label: '产品管理', page: 'products' },
    ],
    steps: [
      '成员管理用于维护团队成员和负责人选项。',
      '产品管理用于维护产品或服务选项，改名时要注意旧线索和报表影响。',
      '永久删除已丢单线索只应用于测试、重复或明显错误数据。',
      '管理员操作前先确认这不是正常业务数据。',
    ],
  },
];

const GUIDE_FAQS = [
  {
    question: '为什么我看不到某条线索？',
    answer: '先检查搜索词、状态、产品、来源和负责人筛选。如果你不是管理员，也可能是该线索没有分配给你。',
  },
  {
    question: 'Seed26 线索和 Cloudmate 线索有什么区别？',
    answer: '区别主要在来源和报价主体默认值。Seed26 线索通常来自 seed26.com，报价时应确认 Issuing Company 是否正确。',
  },
  {
    question: '报价单下载前要检查什么？',
    answer: '检查是否已选择正确 Customer / 客户资料、报价主体、Document Language、币种、账单周期（例如季付或半年付）、付款方式、服务计量周期、Shared Package Catalog / 共享套餐库、Cloudflare terms、有效期、每一项计价行数量和金额，以及 Grand Total。Included Usage 和 Excess Usage Pricing 只说明服务范围，不参与报价总额。PDF 下载需要至少一个产品或服务明细。',
  },
  {
    question: '什么时候要新增 Customer？',
    answer: '只要客户可能重复报价、重复开票、或已经确认是正式客户，就建议新增或保存为 Customer。一次性测试 lead 可以先不建客户档案。',
  },
  {
    question: '什么时候创建发票？',
    answer: '报价内容确认、需要进入收款流程时创建发票。发票从报价单复制商业计价行和服务范围说明，但不会把 Included Usage 或 Excess Usage Pricing 当成收费行。直接创建 draft 发票时，也可以用 Product / Package 插入 Cloudflare、ChinaCDN1 或 AWS 的收费 item 和服务范围说明。',
  },
  {
    question: '发票 PDF 或 Tax Invoice 要注意什么？',
    answer: 'Download PDF 必须返回真实 PDF；如果 Browser Run 未配置，系统会提示 unavailable。默认标题是 Invoice，不要写成 Tax Invoice，除非对应开票主体已明确配置 GST registration。',
  },
  {
    question: '什么时候用 Cloudmate，什么时候用 Seed26？',
    answer: '按客户来源和实际销售主体选择。来自 Cloudmate 业务的报价用 Cloudmate Pte. Ltd.，来自 Seed26 业务的报价用 Seed26。',
  },
  {
    question: '丢单后还能找回来吗？',
    answer: '可以。已丢单表示暂时不推进，管理员也可以在已丢单列表里查看。只有永久删除才会移除数据。',
  },
  {
    question: '页面加载失败怎么办？',
    answer: '先点击页面里的重试按钮。如果仍失败，刷新页面并确认 Cloudflare Access 登录状态正常，再联系管理员。',
  },
];

function GuidePage({ onNavigate }) {
  const [guideSearch, setGuideSearch] = React.useState('');
  const [activeSection, setActiveSection] = React.useState('all');

  const normalizedQuery = guideSearch.trim().toLowerCase();
  const sectionMatches = (section) => {
    if (activeSection !== 'all' && section.id !== activeSection) return false;
    if (!normalizedQuery) return true;
    const haystack = [
      section.title,
      section.summary,
      ...(section.tags || []),
      ...(section.steps || []),
    ].join(' ').toLowerCase();
    return haystack.includes(normalizedQuery);
  };
  const visibleSections = GUIDE_SECTIONS.filter(sectionMatches);
  const visibleFaqs = GUIDE_FAQS.filter((item) => {
    if (!normalizedQuery) return true;
    return `${item.question} ${item.answer}`.toLowerCase().includes(normalizedQuery);
  });

  const goTo = (page) => {
    if (typeof onNavigate === 'function' && page) onNavigate(page);
  };

  return (
    <main className="main guide-main">
      <header className="main-header">
        <div className="crumbs">
          <span className="crumb-cur">使用指南</span>
        </div>
      </header>
      <div className="page-body guide-page">
        <section className="guide-hero">
          <div className="guide-hero-copy">
            <div className="guide-eyebrow">Operator Guide</div>
            <h1>Cloudmate CRM 使用指南</h1>
            <p>给销售和运营同事的快速操作手册</p>
          </div>
          <label className="guide-search">
            <span>⌕</span>
            <input
              aria-label="搜索使用指南"
              value={guideSearch}
              onChange={(event) => setGuideSearch(event.target.value)}
              placeholder="搜索：线索、跟进、报价、Seed26、成员、产品"
            />
            {guideSearch && (
              <button type="button" onClick={() => setGuideSearch('')} aria-label="清空搜索">
                清空
              </button>
            )}
          </label>
        </section>

        <div className="guide-layout">
          <aside className="guide-toc" aria-label="使用指南目录">
            <button
              type="button"
              className={`guide-toc-item ${activeSection === 'all' ? 'active' : ''}`}
              onClick={() => setActiveSection('all')}
            >
              <span>全部内容</span>
              <strong>{GUIDE_SECTIONS.length}</strong>
            </button>
            {GUIDE_SECTIONS.map((section, index) => (
              <button
                type="button"
                key={section.id}
                className={`guide-toc-item ${activeSection === section.id ? 'active' : ''}`}
                onClick={() => setActiveSection(section.id)}
              >
                <span>{index + 1}. {section.label}</span>
                {section.adminOnly && <em>Admin</em>}
              </button>
            ))}
          </aside>

          <section className="guide-content">
            <div className="guide-action-row">
              <button type="button" className="btn-ghost sm" onClick={() => goTo('leads')}>去线索列表</button>
              <button type="button" className="btn-ghost sm" onClick={() => goTo('quotations')}>去报价单</button>
              <button type="button" className="btn-ghost sm" onClick={() => goTo('reports')}>去报表</button>
            </div>

            {visibleSections.length === 0 ? (
              <div className="guide-empty">
                <div className="guide-empty-title">没有找到匹配内容</div>
                <div className="guide-empty-sub">换一个关键词，或切回全部内容。</div>
              </div>
            ) : visibleSections.map((section, index) => (
              <article className="guide-card" key={section.id} id={`guide-${section.id}`}>
                <div className="guide-card-head">
                  <div>
                    <div className="guide-card-kicker">{String(index + 1).padStart(2, '0')}</div>
                    <h2>{section.title}</h2>
                  </div>
                  {section.adminOnly && <span className="guide-admin-chip">Admin only</span>}
                </div>
                <p className="guide-summary">{section.summary}</p>
                <ol className="guide-steps">
                  {section.steps.map((step) => <li key={step}>{step}</li>)}
                </ol>
                {section.actions?.length > 0 && (
                  <div className="guide-card-actions">
                    {section.actions.map((action) => (
                      <button type="button" className="btn-ghost sm" key={action.label} onClick={() => goTo(action.page)}>
                        {action.label}
                      </button>
                    ))}
                  </div>
                )}
              </article>
            ))}

            <section className="guide-faq">
              <div className="guide-faq-head">
                <div className="guide-card-kicker">FAQ</div>
                <h2>常见问题</h2>
              </div>
              <div className="guide-faq-grid">
                {visibleFaqs.map((item) => (
                  <div className="guide-faq-item" key={item.question}>
                    <h3>{item.question}</h3>
                    <p>{item.answer}</p>
                  </div>
                ))}
              </div>
            </section>
          </section>
        </div>
      </div>
    </main>
  );
}

window.GuidePage = GuidePage;
