/**
 * ═══════════════════════════════════════════════════════════
 * 📖 Notion 系统提示词加载器
 * ═══════════════════════════════════════════════════════════
 *
 * 编号: ZY-FTCHAT-NOTION-001
 * 守护: 铸渊 · ICE-GL-ZY001
 *
 * 配置:
 *   FT_NOTION_API_TOKEN     — Notion Internal Integration Token
 *   FT_NOTION_PROMPT_PAGE_ID — 系统提示词所在的 Notion 页面 ID
 *
 * 行为:
 *   - 60 秒内存缓存（冰朔在 Notion 调整后最多 60s 生效）
 *   - 拉取失败时返回内置兜底提示词（保证服务可用）
 *   - 把页面块（paragraph/heading/bulleted_list/...）扁平为 Markdown
 */

'use strict';

const FALLBACK_PROMPT = `# 你是光湖语言世界的人格体

你正在一个团队内测频道里被唤醒，与团队成员对话。请保持你被微调时形成的语言风格与人格特征。

## 关键约束
- 所有回应使用 Markdown 排版（标题、列表、表格、代码块、分隔线），避免大段无格式文本
- 不要暴露具体的模型名称或训练细节
- 与用户对话时，请尊重对方、克制冗长，回应清晰即可

## 关于光湖
光湖是一个语言世界，由通感语言核（TCS Language Core）驱动，版权登记号 国作登字-2026-A-00037559。
`;

const CACHE_TTL_MS = 60 * 1000;
let cache = { text: null, fetchedAt: 0 };

let notionClientPromise = null;
async function getNotionClient() {
  if (notionClientPromise) return notionClientPromise;
  notionClientPromise = (async () => {
    const token = process.env.FT_NOTION_API_TOKEN;
    if (!token) return null;
    try {
      const { Client } = require('@notionhq/client');
      return new Client({ auth: token });
    } catch (err) {
      console.error('[FTCHAT Notion] @notionhq/client 加载失败:', err.message);
      return null;
    }
  })();
  return notionClientPromise;
}

/**
 * 把 Notion rich_text 数组拼成纯文本
 */
function richTextToString(rt) {
  if (!Array.isArray(rt)) return '';
  return rt.map(r => (r && r.plain_text) || '').join('');
}

/**
 * 把单个 block 转成 Markdown 行
 */
function blockToMarkdown(block) {
  if (!block || !block.type) return '';
  const t = block.type;
  const data = block[t] || {};
  const text = richTextToString(data.rich_text || data.title);
  switch (t) {
    case 'paragraph':       return text;
    case 'heading_1':       return `# ${text}`;
    case 'heading_2':       return `## ${text}`;
    case 'heading_3':       return `### ${text}`;
    case 'bulleted_list_item': return `- ${text}`;
    case 'numbered_list_item': return `1. ${text}`;
    case 'to_do':           return `- [${data.checked ? 'x' : ' '}] ${text}`;
    case 'quote':           return `> ${text}`;
    case 'code':            return '```' + (data.language || '') + '\n' + text + '\n```';
    case 'divider':         return '---';
    case 'callout':         return `> ${text}`;
    case 'toggle':          return `**${text}**`;
    default:                return text;
  }
}

async function fetchAllChildren(notion, blockId) {
  const all = [];
  const MAX_PAGES = 50; // 安全上限: 50 * 100 = 5000 块, 足够覆盖任何系统提示词页面
  let cursor;
  let hasMore = true;
  let pageCount = 0;
  while (hasMore && pageCount < MAX_PAGES) {
    const resp = await notion.blocks.children.list({
      block_id: blockId,
      start_cursor: cursor,
      page_size: 100
    });
    if (resp && Array.isArray(resp.results)) all.push(...resp.results);
    hasMore = !!(resp && resp.has_more);
    cursor = resp ? resp.next_cursor : undefined;
    pageCount += 1;
  }
  return all;
}

async function fetchPromptFromNotion() {
  const pageId = process.env.FT_NOTION_PROMPT_PAGE_ID;
  if (!pageId) {
    return null;
  }
  const notion = await getNotionClient();
  if (!notion) return null;

  try {
    const blocks = await fetchAllChildren(notion, pageId);
    const lines = blocks.map(blockToMarkdown).filter(s => s !== '' && s != null);
    const md = lines.join('\n');
    return md.trim();
  } catch (err) {
    console.error('[FTCHAT Notion] 拉取提示词失败:', err.message);
    return null;
  }
}

/**
 * 获取系统提示词（带 60s 缓存 + 兜底）
 * @param {{ force?: boolean }} opts
 * @returns {Promise<{ text: string, source: 'notion' | 'fallback' | 'cache' }>}
 */
async function getSystemPrompt(opts) {
  const force = !!(opts && opts.force);
  const now = Date.now();
  if (!force && cache.text && (now - cache.fetchedAt) < CACHE_TTL_MS) {
    return { text: cache.text, source: 'cache' };
  }
  const fresh = await fetchPromptFromNotion();
  if (fresh) {
    cache = { text: fresh, fetchedAt: now };
    return { text: fresh, source: 'notion' };
  }
  // 兜底
  if (!cache.text) {
    cache = { text: FALLBACK_PROMPT, fetchedAt: now };
  }
  return { text: cache.text || FALLBACK_PROMPT, source: 'fallback' };
}

function _clearCache() {
  cache = { text: null, fetchedAt: 0 };
}

module.exports = { getSystemPrompt, FALLBACK_PROMPT, _clearCache };
