/*!
 * @name 星海音乐源
 * @description 由GDAPI制作的洛雪音乐源
 * @version v2.2.8
 * @author 万去了了 问题反馈https://zrcdy.dpdns.org/lx/fk/index.php
 * @homepage https://zrcdy.dpdns.org/
 * @lastUpdate 2025-2-13
 */

// ============================ 核心配置 ============================
const UPDATE_CONFIG = {
  versionApiUrl: 'https://zrcdy.dpdns.org/lx/version.php',
  latestScriptUrl: 'https://zrcdy.dpdns.org/lx/index.html',
  currentVersion: 'v2.2.8'
};

// 动态稳定源接口
const STABLE_SOURCES_API_URL = 'https://zrcdy.dpdns.org/lx/stable_sources.php';

// 主API - GD Studio
const MAIN_API_BASE = 'https://music-api.gdstudio.xyz/api.php?use_xbridge3=true&loader_name=forest&need_sec_link=1&sec_link_scene=im&theme=light';

// ============================ 全局状态 ============================
let musicSourceEnabled = true;
let serverCheckCompleted = false;

let stableSourcesList = null;          // 服务器返回的稳定源，如 ['netease','kuwo','tencent']
let mainApiSourceMap = {};            // 动态主API映射 { wy: 'netease', tx: 'tencent', kw: 'kuwo', ... }
let availablePlatforms = [];          // 最终可用的平台代码（仅来自主API映射）

// ---------- 音质支持（各平台原生）----------
const MUSIC_QUALITY = {
  wy: ['128k', '192k', '320k', 'flac', 'flac24bit'],
  tx: ['128k', '192k', '320k', 'flac', 'flac24bit'],
  kw: ['128k', '192k', '320k', 'flac', 'flac24bit'],
  kg: ['128k', '192k', '320k', 'flac', 'flac24bit'],
  mg: ['128k', '192k', '320k', 'flac']
};

const PLATFORM_NAME_MAP = {
  wy: '网易云音乐',
  tx: 'QQ音乐',
  kw: '酷我音乐',
  kg: '酷狗音乐',
  mg: '咪咕音乐'
};

const { EVENT_NAMES, request, on, send } = globalThis.lx;

// ============================ 工具函数 ============================
function log(...args) { console.log(...args); }
function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); }

function logSimple(action, source, musicInfo, status, extra = '') {
  const songName = musicInfo.name || '未知歌曲';
  log(`[${action}] 平台:${source} | 歌曲:${songName} | 状态:${status}${extra ? ' | ' + extra : ''}`);
}

/**
 * 音质降级映射
 */
function mapQuality(targetQuality, availableQualities) {
  const priorityMap = {
    '臻品母带': 'flac24bit', '臻品音质2.0': 'flac24bit', '臻品音质': 'flac24bit',
    'Hires 无损24-Bit': 'flac24bit', 'FLAC': 'flac', '320k': '320k', '192k': '192k', '128k': '128k'
  };
  if (availableQualities.includes(targetQuality)) return targetQuality;
  const mapped = priorityMap[targetQuality];
  if (mapped && availableQualities.includes(mapped)) return mapped;
  const order = ['flac24bit', 'flac', '320k', '192k', '128k'];
  for (const q of order) if (availableQualities.includes(q)) return q;
  return availableQualities[0] || '128k';
}

/**
 * 统一网络请求
 */
const httpFetch = (url, options = { method: 'GET' }) => {
  return new Promise((resolve, reject) => {
    const cancelRequest = request(url, options, (err, resp) => {
      if (err) return reject(new Error(`网络请求异常：${err.message}`));
      let body = resp.body;
      if (typeof body === 'string') {
        const trimmed = body.trim();
        if (trimmed.startsWith('{') || trimmed.startsWith('[') || trimmed.startsWith('"')) {
          try { body = JSON.parse(trimmed); } catch (e) {}
        }
      }
      resolve({ body, statusCode: resp.statusCode, headers: resp.headers || {} });
    });
  });
};

/**
 * 版本比较
 */
const compareVersions = (remoteVer, currentVer) => {
  const r = remoteVer.replace(/^v/, '').split('.').map(Number);
  const c = currentVer.replace(/^v/, '').split('.').map(Number);
  for (let i = 0; i < Math.max(r.length, c.length); i++) {
    if ((r[i] || 0) > (c[i] || 0)) return true;
    if ((r[i] || 0) < (c[i] || 0)) return false;
  }
  return false;
};

// ============================ 动态稳定源获取 ============================
const fetchStableSources = async () => {
  log('正在获取服务器稳定源列表...');
  try {
    const resp = await httpFetch(STABLE_SOURCES_API_URL, {
      method: 'GET', timeout: 5000,
      headers: { 'User-Agent': 'LX-Music-Mobile/星海音乐源' }
    });
    if (resp.statusCode !== 200) throw new Error(`HTTP ${resp.statusCode}`);
    let data = resp.body;
    if (typeof data === 'string') {
      try { data = JSON.parse(data); } catch (e) { throw new Error('JSON解析失败'); }
    }
    if (!Array.isArray(data) || data.length === 0) throw new Error('返回数据非数组或为空');
    stableSourcesList = data;
    log('✅ 获取稳定源成功:', stableSourcesList);
  } catch (err) {
    log('❌ 获取稳定源失败，使用默认值 [netease, kuwo]:', err.message);
    stableSourcesList = ['netease', 'kuwo'];
  }
};

/**
 * 根据稳定源列表构建主API映射和可用平台列表
 * 仅使用主API，忽略任何备用源
 */
const buildPlatformsFromStableSources = () => {
  // 可转换的映射（仅包含GD Studio API明确支持且实测可用的组合）
  const sourceToCode = {
    netease: 'wy',
    tencent: 'tx',
    kuwo: 'kw',
    kugou: 'kg',
    migu: 'mg'
  };

  // 1. 主API映射：只有稳定源中存在且能转换的才会加入
  mainApiSourceMap = {};
  stableSourcesList.forEach(src => {
    const code = sourceToCode[src];
    if (code) mainApiSourceMap[code] = src;
  });

  // 2. 可用平台仅来自主API映射（不再合并备用平台）
  availablePlatforms = Object.keys(mainApiSourceMap).filter(code => MUSIC_QUALITY[code]);

  // 3. 特殊降级：如果稳定源只有网易云+酷我（或获取失败），确保平台列表正确
  if (stableSourcesList.length === 2 &&
      stableSourcesList.includes('netease') &&
      stableSourcesList.includes('kuwo') &&
      !stableSourcesList.includes('tencent')) {
    // 此时映射应只包含 wy 和 kw（已在上面生成，但显式确保）
    availablePlatforms = ['wy', 'kw'];
    mainApiSourceMap = { wy: 'netease', kw: 'kuwo' };
  }

  log('主API映射:', mainApiSourceMap);
  log('可用平台:', availablePlatforms);
};

// ============================ 服务器状态检查 ============================
const checkServerStatus = async () => {
  log('正在检查服务器连接状态...');
  for (let attempt = 0; attempt <= 2; attempt++) {
    if (attempt > 0) await delay(1000);
    try {
      const resp = await httpFetch('https://zrcdy.dpdns.org/lx/status.php', {
        method: 'GET', timeout: 5000,
        headers: { 'User-Agent': 'LX-Music-Mobile/星海音乐源', 'Accept': 'application/json' }
      });
      if (resp.statusCode !== 200) throw new Error(`HTTP状态码异常: ${resp.statusCode}`);
      let data = resp.body;
      if (typeof data === 'string') {
        try { data = JSON.parse(data); } catch (e) { throw new Error('JSON解析失败'); }
      }
      if (!data || typeof data !== 'object') throw new Error('无效数据格式');
      const enabled = data.enabled !== false;
      log(`服务器连接状态: ${enabled ? '服务正常' : '服务受限'}`);
      return { enabled, message: data.message || (enabled ? '服务正常' : '服务暂时不可用'), error: null };
    } catch (err) {
      log(`服务器连接检查失败(第${attempt + 1}次):`, err.message);
      if (attempt === 2) {
        log('服务器连接检查多次失败，使用本地模式');
        return { enabled: true, message: `服务器连接失败，使用本地模式: ${err.message}`, error: err.message };
      }
    }
  }
  return { enabled: true, message: '未知错误，使用本地模式', error: '未知错误' };
};

// ============================ 自动更新 ============================
const checkAutoUpdate = async () => {
  if (!musicSourceEnabled) return;
  try {
    const resp = await httpFetch(UPDATE_CONFIG.versionApiUrl, {
      timeout: 10000,
      headers: { 'Content-Type': 'application/json', 'User-Agent': 'LX-Music-Mobile' }
    });
    if (resp.statusCode !== 200) return;
    let data = resp.body;
    if (typeof data === 'string') {
      try { data = JSON.parse(data.trim().replace(/^\uFEFF/, '')); } catch (e) { return; }
    }
    if (!data || typeof data !== 'object') return;
    const remoteVer = data.version || data.VERSION || data.ver;
    if (!remoteVer) return;
    const changelog = data.changelog || data.changelog || '暂无更新日志';
    const minReq = data.min_required || data.minRequired || 'v1.0.0';
    const updateUrl = data.update_url || data.updateUrl || UPDATE_CONFIG.latestScriptUrl;
    const needUpdate = compareVersions(remoteVer, UPDATE_CONFIG.currentVersion);
    if (needUpdate) {
      log('发现新版本:', remoteVer, '当前版本:', UPDATE_CONFIG.currentVersion);
      const force = compareVersions(remoteVer, minReq) && compareVersions(minReq, UPDATE_CONFIG.currentVersion);
      const msg = `【星海音乐源更新通知】\n当前版本：${UPDATE_CONFIG.currentVersion}\n最新版本：${remoteVer}\n\n更新内容：\n${changelog}${force ? '\n\n⚠️ 此版本需要强制更新，请立即更新以正常使用' : ''}`;
      send(EVENT_NAMES.updateAlert, {
        log: msg, updateUrl,
        confirmText: '立即更新',
        cancelText: force ? '退出应用' : '暂不更新'
      });
    }
  } catch (err) { log('更新检查失败:', err.message); }
};

// ============================ 音频地址解析（仅主API）============================
const getMusicUrlFromMainAPI = async (source, songId, apiQuality) => {
  const apiSource = mainApiSourceMap[source];
  if (!apiSource) throw new Error('当前平台不在主API稳定源中');
  const url = `${MAIN_API_BASE}&types=url&source=${apiSource}&id=${songId}&br=${apiQuality}`;
  const resp = await httpFetch(url, {
    method: 'GET',
    headers: { 'User-Agent': 'LX-Music-Mobile', 'Accept': 'application/json' }
  });
  const data = typeof resp.body === 'object' ? resp.body : JSON.parse(resp.body);
  if (!data.url) throw new Error('音频解析失败');
  return data.url;
};

const handleGetMusicUrl = async (source, musicInfo, quality) => {
  if (!musicSourceEnabled) throw new Error('服务暂时不可用');
  if (!serverCheckCompleted) throw new Error('服务初始化中，请稍后');
  if (!availablePlatforms.includes(source)) {
    throw new Error(`当前平台 "${source}" 不可用（未在服务器稳定源中）`);
  }

  logSimple('解析音频地址', source, musicInfo, '开始');
  const songId = musicInfo.hash ?? musicInfo.songmid ?? musicInfo.id;
  if (!songId) throw new Error('歌曲信息不完整');

  const avail = MUSIC_QUALITY[source] || ['128k', '192k', '320k', 'flac'];
  const actual = mapQuality(quality, avail);
  if (actual !== quality) log(`音质自动映射: ${quality} -> ${actual}`);

  let finalUrl = null;
  let lastErr = null;

  // 仅尝试主API
  try {
    const brMap = { '128k': '128', '192k': '192', '320k': '320', 'flac': '740', 'flac24bit': '999' };
    const apiBr = brMap[actual] || '320';
    finalUrl = await getMusicUrlFromMainAPI(source, songId, apiBr);
    logSimple('解析音频地址', source, musicInfo, '成功(主API)');
  } catch (err) {
    lastErr = err;
    logSimple('解析音频地址', source, musicInfo, '主API失败', err.message);
  }

  if (!finalUrl) {
    const msg = `无法获取音频地址：${lastErr ? lastErr.message : '未知错误'}`;
    logSimple('解析音频地址', source, musicInfo, '完全失败', msg);
    throw new Error(msg);
  }
  return finalUrl;
};

// ============================ 构建音乐源对象 ============================
const buildMusicSources = (platforms) => {
  const sources = {};
  platforms.forEach(code => {
    sources[code] = {
      name: PLATFORM_NAME_MAP[code] || code,
      type: 'music',
      actions: ['musicUrl'],
      qualitys: MUSIC_QUALITY[code]
    };
  });
  return sources;
};

// ============================ 事件监听 ============================
on(EVENT_NAMES.request, ({ action, source, info }) => {
  if (action !== 'musicUrl') return Promise.reject(new Error('不支持的操作类型'));
  if (!info?.musicInfo || !info.type) return Promise.reject(new Error('请求参数不完整'));
  return handleGetMusicUrl(source, info.musicInfo, info.type);
});

// ============================ 初始化 ============================
(async () => {
  log('========================================');
  log('星海音乐源 v2.2.8 初始化（仅主API模式）');
  log('========================================');

  try {
    const server = await checkServerStatus();
    musicSourceEnabled = server.enabled;
    if (!musicSourceEnabled) {
      log('⚠️ 服务器状态异常，服务受限:', server.message);
      throw new Error(server.message || '音乐服务已禁用');
    }

    await fetchStableSources();
    buildPlatformsFromStableSources();
    serverCheckCompleted = true;

    const sources = buildMusicSources(availablePlatforms);
    send(EVENT_NAMES.inited, { status: true, openDevTools: false, sources, initStatus: 'ready' });

    log('✅ 初始化完成，可用平台:', availablePlatforms.join(', '));
    setTimeout(checkAutoUpdate, 3000);
  } catch (err) {
    log('❌ 初始化异常，进入降级模式:', err.message);
    // 降级：仅启用网易云+酷我（稳定源固定为netease,kuwo）
    stableSourcesList = ['netease', 'kuwo'];
    buildPlatformsFromStableSources();
    musicSourceEnabled = true;
    serverCheckCompleted = true;
    const sources = buildMusicSources(availablePlatforms);
    send(EVENT_NAMES.inited, { status: true, openDevTools: false, sources, initStatus: 'degraded' });
    log('降级模式完成，仅支持网易云、酷我');
    setTimeout(checkAutoUpdate, 3000);
  }
})();