/**
 * 乐读派 AI 创作系统 — C 端 API 封装
 *
 * 调用流程：
 *   1. B1 校验额度 → 2. A1/A2/A3 创作 → 3. 进度追踪 → 4. B2 获取结果
 *
 * 所有 API 均需 HMAC-SHA256 签名（除 B6 画风列表）
 */

import { generateSignHeaders } from './HmacSigner.js'

export default class CreationApi {
  /**
   * @param {string} serverUrl - 服务器地址
   * @param {string} appKey - 机构 App Key (orgId)
   * @param {string} appSecret - 机构密钥
   */
  constructor(serverUrl, appKey, appSecret) {
    this.serverUrl = serverUrl
    this.appKey = appKey
    this.appSecret = appSecret
  }

  // ─── 通用请求方法 ─────────────────────────────────────────────────

  async _get(path, queryParams = {}) {
    const signHeaders = generateSignHeaders(this.appKey, this.appSecret, queryParams)
    const qs = Object.entries(queryParams).map(([k, v]) => `${k}=${encodeURIComponent(v)}`).join('&')
    const url = `${this.serverUrl}${path}${qs ? '?' + qs : ''}`

    const res = await fetch(url, {
      method: 'GET',
      headers: { ...signHeaders, 'Content-Type': 'application/json' }
    })
    return this._handleResponse(res)
  }

  async _post(path, body, queryParams = {}) {
    // POST 的 JSON body 不参与签名，只有 query params 参与
    const signHeaders = generateSignHeaders(this.appKey, this.appSecret, queryParams)
    const qs = Object.entries(queryParams).map(([k, v]) => `${k}=${encodeURIComponent(v)}`).join('&')
    const url = `${this.serverUrl}${path}${qs ? '?' + qs : ''}`

    const res = await fetch(url, {
      method: 'POST',
      headers: { ...signHeaders, 'Content-Type': 'application/json' },
      body: JSON.stringify(body)
    })
    return this._handleResponse(res)
  }

  async _handleResponse(res) {
    if (!res.ok) {
      throw new Error(`HTTP ${res.status}: ${res.statusText}`)
    }
    const json = await res.json()
    if (json.code !== 200) {
      const err = new Error(json.msg || 'API Error')
      err.code = json.code
      throw err
    }
    return json.data
  }

  // ─── B 类接口（查询） ─────────────────────────────────────────────

  /**
   * B1 - 创作请求校验（检查额度是否充足）
   * @param {string} orgId
   * @param {string} phone
   * @returns {Promise<{valid: boolean, reason?: string, remainQuota?: number}>}
   */
  async validate(orgId, phone) {
    return this._post('/api/v1/query/validate', { orgId, phone })
  }

  /**
   * B2 - 查询作品详情（含实时进度）
   * @param {string} workId
   * @returns {Promise<CreationResultVO>}
   *
   * CreationResultVO 结构:
   * {
   *   workId, status, title, author, pages, style,
   *   videoStatus, videoUrl, failReason, durationMs, retryCount,
   *   progress,         // 0-100 进度百分比，-1 表示失败
   *   progressMessage,  // "正在绘制第3/7页..."
   *   pageList: [{pageNum, text, imageUrl, audioUrl}]  // 仅 COMPLETED 时有值
   * }
   */
  async getWork(workId) {
    return this._get(`/api/v1/query/work/${workId}`, { orgId: this.appKey })
  }

  /**
   * B3 - 作品列表
   */
  async listWorks(phone, page = 1, pageSize = 20) {
    return this._get('/api/v1/query/works', {
      orgId: this.appKey, phone, page, pageSize
    })
  }

  /**
   * B6 - 画风列表（无需签名）
   */
  async getStyles() {
    const res = await fetch(`${this.serverUrl}/api/v1/query/styles`)
    return this._handleResponse(res)
  }

  // ─── A 类接口（创作） ─────────────────────────────────────────────

  /**
   * A1 - 一句话创作
   * @param {Object} params
   * @param {string} params.orgId
   * @param {string} params.phone
   * @param {string} params.sentence - 故事描述
   * @param {string} params.style - 画风标识 (如 style_cartoon)
   * @param {boolean} [params.enableVoice=false] - 是否配音
   * @param {string} [params.author] - 作者名
   * @param {number} [params.age] - 适龄
   * @returns {Promise<{workId: string, status: string}>}
   */
  async createBySentence(params) {
    return this._post('/api/v1/creation/one-sentence', params)
  }

  /**
   * A2 - 四要素创作
   * @param {Object} params
   * @param {string} params.orgId
   * @param {string} params.phone
   * @param {string} params.time - 时间
   * @param {string} params.place - 地点
   * @param {string} params.character - 角色
   * @param {string} params.event - 事件
   * @param {string} params.style
   * @param {boolean} [params.enableVoice=false]
   * @returns {Promise<{workId: string, status: string}>}
   */
  async createByElements(params) {
    return this._post('/api/v1/creation/scene-elements', params)
  }

  /**
   * A3 - 图片故事创作
   * @param {Object} params
   * @param {string} params.orgId
   * @param {string} params.phone
   * @param {string} params.imageUrl - 参考图片 URL
   * @param {string} [params.storyHint] - 故事方向提示
   * @param {string} params.style
   * @param {boolean} [params.enableVoice=false]
   * @param {string} [params.heroCharId] - 主角 charId (来自 A5/A6)
   * @param {Array<{charId, imageUrl, name}>} [params.characterRefs] - 角色引用列表
   * @returns {Promise<{workId: string, status: string}>}
   */
  async createByImage(params) {
    return this._post('/api/v1/creation/image-story', params)
  }

  /**
   * A4 - 视频合成
   * @param {Object} params
   * @param {string} params.orgId
   * @param {string} params.phone
   * @param {string} params.workId
   * @returns {Promise<{workId: string}>}
   */
  async createVideo(params) {
    return this._post('/api/v1/creation/video', params)
  }
}
