/**
 * share-api.js - ChatView 在线分享 API 模块
 *
 * 接口：POST http://43.154.202.114:81/api/contents
 * 文档：http://43.154.202.114:81/docs/api
 *
 * 支持字段（全部提交）：
 *   raw_html        - 所选消息 HTML 拼接（必填）
 *   title           - 对话标题
 *   plain_text      - 纯文本摘要（利于 SEO）
 *   source_platform - "ChatGPT"
 *   source_url      - 当前页面 URL
 *   model_name      - 模型名称（从页面 DOM 提取）
 *   metadata        - 扩展信息（conversation_id、language、message_count、tags）
 *
 * Token 存储：chrome.storage.local（安全隔离，不暴露给页面 JS）
 */

(function () {
  'use strict';

  const API_BASE = 'https://chat-view.com/api';
  const TOKEN_KEY = 'chatview_api_token';
  // 内置默认 Token（用户可在面板设置中覆盖）
  const DEFAULT_TOKEN = 'd4654e1acdb00b012a173dc272effc4a';

  // ── Token 管理 ────────────────────────────────────────────

  /**
   * 从 chrome.storage.local 读取 Token
   * @returns {Promise<string|null>}
   */
  async function getToken() {
    return new Promise((resolve) => {
      chrome.storage.local.get([TOKEN_KEY], (result) => {
        // 优先使用用户自定义 Token，否则使用内置默认 Token
        resolve(result[TOKEN_KEY] || DEFAULT_TOKEN);
      });
    });
  }

  /**
   * 保存 Token 到 chrome.storage.local
   * @param {string} token
   * @returns {Promise<void>}
   */
  async function saveToken(token) {
    return new Promise((resolve) => {
      chrome.storage.local.set({ [TOKEN_KEY]: token.trim() }, resolve);
    });
  }

  /**
   * 清除 Token
   * @returns {Promise<void>}
   */
  async function clearToken() {
    return new Promise((resolve) => {
      chrome.storage.local.remove([TOKEN_KEY], resolve);
    });
  }

  // ── 页面元数据提取 ────────────────────────────────────────

  /**
   * 从 ChatGPT 页面提取模型名称
   * ChatGPT 在顶部导航栏显示当前模型（如 "GPT-4o"）
   */
  function _extractModelName() {
    // 尝试从顶部模型选择器提取
    const selectors = [
      '[data-testid="model-switcher-dropdown-button"]',
      'button[aria-label*="GPT"]',
      'button[aria-label*="model"]',
      '[class*="model"] button',
      'nav button[id*="model"]',
    ];
    for (const sel of selectors) {
      const el = document.querySelector(sel);
      if (el) {
        const text = (el.innerText || el.textContent || '').trim();
        if (text && text.length < 50) return text;
      }
    }

    // 从页面 title 推断
    const title = document.title || '';
    if (title.includes('o1')) return 'o1';
    if (title.includes('o3')) return 'o3';

    return 'GPT-4o'; // 默认值
  }

  /**
   * 从 ChatGPT URL 提取 conversation_id
   * URL 格式：https://chatgpt.com/c/{conversation_id}
   */
  function _extractConversationId() {
    const match = location.pathname.match(/\/c\/([a-zA-Z0-9-]+)/);
    return match ? match[1] : null;
  }

  /**
   * 检测页面语言
   */
  function _detectLanguage() {
    return document.documentElement.lang || navigator.language || 'zh-CN';
  }

  // ── 内容组装 ──────────────────────────────────────────────

  /**
   * 从选中的消息列表组装 API 请求体（提交所有支持字段）
   *
   * @param {Object} params
   * @param {Array}  params.messages      - 选中的消息列表 [{role, content, contentNode}, ...]
   * @param {string} params.title         - 对话标题
   * @returns {Object} API 请求体
   */
  function buildPayload({ messages, title }) {
    // 1. raw_html：拼接所有选中消息的 HTML，加上角色标签
    const htmlParts = messages.map((msg) => {
      const roleLabel = msg.role === 'user' ? 'You' : 'ChatGPT';
      const roleClass = msg.role === 'user' ? 'cv-role-user' : 'cv-role-assistant';
      const contentHtml = msg.contentNode
        ? msg.contentNode.innerHTML || ''
        : _escapeHtml(msg.content || '');
      return `<div class="cv-message ${roleClass}"><div class="cv-role">${roleLabel}</div><div class="cv-content">${contentHtml}</div></div>`;
    });
    const raw_html = `<div class="cv-conversation">${htmlParts.join('\n')}</div>`;

    // 2. plain_text：拼接纯文本，用于 SEO description
    const plain_text = messages
      .map((msg) => {
        const roleLabel = msg.role === 'user' ? 'You' : 'ChatGPT';
        return `${roleLabel}:\n${(msg.content || '').trim()}`;
      })
      .join('\n\n---\n\n');

    // 3. metadata：扩展信息
    const conversationId = _extractConversationId();
    const metadata = {
      conversation_id: conversationId,
      language: _detectLanguage(),
      message_count: messages.length,
      user_message_count: messages.filter((m) => m.role === 'user').length,
      assistant_message_count: messages.filter((m) => m.role === 'assistant').length,
      tags: ['chatgpt', 'ai-conversation'],
      exported_at: new Date().toISOString(),
      plugin_version: '1.0.0',
    };

    return {
      raw_html,
      title: title || 'AI Chat',
      plain_text,
      source_platform: 'ChatGPT',
      source_url: location.href,
      model_name: _extractModelName(),
      metadata,
    };
  }

  // ── API 调用 ──────────────────────────────────────────────

  /**
   * 提交内容到 ChatView 平台，获取分享链接
   *
   * @param {Object} params
   * @param {Array}  params.messages  - 选中的消息列表
   * @param {string} params.title     - 对话标题
   * @returns {Promise<{url: string, share_token: string, id: number, title: string}>}
   * @throws {Error} 包含用户友好的错误信息
   */
  async function shareContent({ messages, title }) {
    const token = await getToken();
    if (!token) {
      throw new ShareError('NO_TOKEN', '请先配置 API Token');
    }

    const payload = buildPayload({ messages, title });

    // 通过 background service worker 中转请求，绕过页面 CSP 限制
    let result;
    try {
      result = await new Promise((resolve, reject) => {
        chrome.runtime.sendMessage(
          {
            type: 'FETCH_REQUEST',
            payload: {
              url: `${API_BASE}/contents`,
              method: 'POST',
              headers: {
                'Content-Type': 'application/json',
                'Accept': 'application/json',
                'Authorization': `Bearer ${token}`,
              },
              body: payload,
            },
          },
          (response) => {
            if (chrome.runtime.lastError) {
              reject(new Error(chrome.runtime.lastError.message));
            } else {
              resolve(response);
            }
          }
        );
      });
    } catch (e) {
      throw new ShareError('NETWORK_ERROR', '网络请求失败，请检查网络连接');
    }

    if (!result) {
      throw new ShareError('NETWORK_ERROR', '网络请求失败，请检查网络连接');
    }

    if (result.error && result.status === 0) {
      throw new ShareError('NETWORK_ERROR', '网络请求失败，请检查网络连接');
    }

    const { status, data, retryAfter } = result;

    if (status === 201) {
      return data; // { id, title, url, share_token }
    }

    if (status === 401) {
      throw new ShareError('INVALID_TOKEN', 'Token 无效或已过期，请重新配置');
    }

    if (status === 422) {
      const errMsg = (data && data.message) || '参数校验失败';
      const details = (data && data.errors)
        ? Object.values(data.errors).flat().join('；')
        : '';
      throw new ShareError('VALIDATION_ERROR', details ? `${errMsg}：${details}` : errMsg);
    }

    if (status === 429) {
      const after = retryAfter || '60';
      throw new ShareError('RATE_LIMIT', `请求过于频繁，请 ${after} 秒后重试`);
    }

    if (status === 503) {
      throw new ShareError('SERVER_NOT_CONFIGURED', '服务端未配置 API Token');
    }

    throw new ShareError('UNKNOWN_ERROR', `请求失败（HTTP ${status}）`);
  }

  // ── 自定义错误类 ──────────────────────────────────────────

  class ShareError extends Error {
    constructor(code, message) {
      super(message);
      this.code = code;
      this.name = 'ShareError';
    }
  }

  // ── 工具函数 ──────────────────────────────────────────────

  function _escapeHtml(str) {
    return str
      .replace(/&/g, '&amp;')
      .replace(/</g, '&lt;')
      .replace(/>/g, '&gt;')
      .replace(/"/g, '&quot;');
  }

  // ── 导出到全局 ────────────────────────────────────────────

  window.ShareAPI = {
    getToken,
    saveToken,
    clearToken,
    shareContent,
    ShareError,
  };
})();
