import axios from 'axios';
import { app, dialog, ipcMain, Notification, protocol, shell } from 'electron';
import Store from 'electron-store';
import * as fs from 'fs';
import * as http from 'http';
import * as https from 'https';
import * as NodeID3 from 'node-id3';
import * as path from 'path';
import * as os from 'os';
import * as mm from 'music-metadata';
import { fileTypeFromFile } from 'file-type';

import { getStore } from './config';

const MAX_CONCURRENT_DOWNLOADS = 3;
const downloadQueue: { url: string; filename: string; songInfo: any; type?: string }[] = [];
let activeDownloads = 0;

// 创建一个store实例用于存储下载历史
const downloadStore = new Store({
  name: 'downloads',
  defaults: {
    history: []
  }
});

// 创建一个store实例用于存储音频缓存
const audioCacheStore = new Store({
  name: 'audioCache',
  defaults: {
    cache: {}
  }
});

// 保存已发送通知的文件，避免重复通知
const sentNotifications = new Map();

/**
 * 初始化文件管理相关的IPC监听
 */
export function initializeFileManager() {
  // 注册本地文件协议
  protocol.registerFileProtocol('local', (request, callback) => {
    try {
      let url = request.url;
      // local://C:/Users/xxx.mp3
      let filePath = decodeURIComponent(url.replace('local:///', ''));
      
      // 兼容 local:///C:/Users/xxx.mp3 这种情况
      if (/^\/[a-zA-Z]:\//.test(filePath)) {
        filePath = filePath.slice(1);
      }
      
      // 还原为系统路径格式
      filePath = path.normalize(filePath);
      
      // 检查文件是否存在
      if (!fs.existsSync(filePath)) {
        console.error('File not found:', filePath);
        callback({ error: -6 }); // net::ERR_FILE_NOT_FOUND
        return;
      }

      callback({ path: filePath });
    } catch (error) {
      console.error('Error handling local protocol:', error);
      callback({ error: -2 }); // net::FAILED
    }
  });

  // 检查文件是否存在
  ipcMain.handle('check-file-exists', (_, filePath) => {
    try {
      return fs.existsSync(filePath);
    } catch (error) {
      console.error('Error checking if file exists:', error);
      return false;
    }
  });

  // 获取支持的音频格式列表
  ipcMain.handle('get-supported-audio-formats', () => {
    return {
      formats: [
        { ext: 'mp3', name: 'MP3' },
        { ext: 'm4a', name: 'M4A/AAC' },
        { ext: 'flac', name: 'FLAC' },
        { ext: 'wav', name: 'WAV' },
        { ext: 'ogg', name: 'OGG Vorbis' },
        { ext: 'aac', name: 'AAC' }
      ],
      default: 'mp3'
    };
  });

  // 通用的选择目录处理
  ipcMain.handle('select-directory', async () => {
    const result = await dialog.showOpenDialog({
      properties: ['openDirectory'],
      title: '选择目录'
    });
    return result;
  });

  // 通用的打开目录处理
  ipcMain.on('open-directory', (_, filePath) => {
    try {
      // 验证文件路径
      if (!filePath) {
        console.error('无效的文件路径: 路径为空');
        return;
      }

      // 统一处理路径分隔符
      const normalizedPath = path.normalize(filePath);

      if (fs.statSync(normalizedPath).isDirectory()) {
        shell.openPath(normalizedPath);
      } else {
        shell.showItemInFolder(normalizedPath);
      }
    } catch (error) {
      console.error('打开路径失败:', error);
    }
  });

  // 获取默认下载路径
  ipcMain.handle('get-downloads-path', () => {
    return app.getPath('downloads');
  });
  
  // 获取存储的配置值
  ipcMain.handle('get-store-value', (_, key) => {
    const store = new Store();
    return store.get(key);
  });
  
  // 设置存储的配置值
  ipcMain.on('set-store-value', (_, key, value) => {
    const store = new Store();
    store.set(key, value);
  });

  // 下载音乐处理
  ipcMain.on('download-music', handleDownloadRequest);

  // 检查文件是否已下载
  ipcMain.handle('check-music-downloaded', (_, filename: string) => {
    const store = new Store();
    const downloadPath = (store.get('set.downloadPath') as string) || app.getPath('downloads');
    const filePath = path.join(downloadPath, `${filename}.mp3`);
    return fs.existsSync(filePath);
  });

  // 删除已下载的音乐
  ipcMain.handle('delete-downloaded-music', async (_, filePath: string) => {
    try {
      if (fs.existsSync(filePath)) {
        // 先删除文件
        try {
          await fs.promises.unlink(filePath);
        } catch (error) {
          console.error('Error deleting file:', error);
        }

        // 删除对应的歌曲信息
        const store = new Store();
        const songInfos = store.get('downloadedSongs', {}) as Record<string, any>;
        delete songInfos[filePath];
        store.set('downloadedSongs', songInfos);

        return true;
      }
      return false;
    } catch (error) {
      console.error('Error deleting file:', error);
      return false;
    }
  });

  // 获取已下载音乐列表
  ipcMain.handle('get-downloaded-music', async () => {
    try {
      const store = new Store();
      const songInfos = store.get('downloadedSongs', {}) as Record<string, any>;

      // 异步处理文件存在性检查
      const entriesArray = Object.entries(songInfos);
      const validEntriesPromises = await Promise.all(
        entriesArray.map(async ([path, info]) => {
          try {
            const exists = await fs.promises.access(path)
              .then(() => true)
              .catch(() => false);
            return exists ? info : null;
          } catch (error) {
            console.error('Error checking file existence:', error);
            return null;
          }
        })
      );

      // 过滤有效的歌曲并排序
      const validSongs = validEntriesPromises
        .filter(song => song !== null)
        .sort((a, b) => (b.downloadTime || 0) - (a.downloadTime || 0));

      // 更新存储，移除不存在的文件记录
      const newSongInfos = validSongs.reduce((acc, song) => {
        if (song && song.path) {
          acc[song.path] = song;
        }
        return acc;
      }, {});
      store.set('downloadedSongs', newSongInfos);

      return validSongs;
    } catch (error) {
      console.error('Error getting downloaded music:', error);
      return [];
    }
  });

  // 检查歌曲是否已下载并返回本地路径
  ipcMain.handle('check-song-downloaded', (_, songId: number) => {
    const store = new Store();
    const songInfos = store.get('downloadedSongs', {}) as Record<string, any>;

    // 通过ID查找已下载的歌曲
    for (const [path, info] of Object.entries(songInfos)) {
      if (info.id === songId && fs.existsSync(path)) {
        return {
          isDownloaded: true,
          localPath: `local://${path}`,
          songInfo: info
        };
      }
    }

    return {
      isDownloaded: false,
      localPath: '',
      songInfo: null
    };
  });

  // 添加清除下载历史的处理函数
  ipcMain.on('clear-downloads-history', () => {
    downloadStore.set('history', []);
  });

  // 添加清除已下载音乐记录的处理函数
  ipcMain.handle('clear-downloaded-music', () => {
    const store = new Store();
    store.set('downloadedSongs', {});
    return true;
  });

  // 添加清除音频缓存的处理函数
  ipcMain.on('clear-audio-cache', () => {
    audioCacheStore.set('cache', {});
    // 清除临时音频文件目录
    const tempDir = path.join(app.getPath('userData'), 'AudioCache');
    if (fs.existsSync(tempDir)) {
      try {
        fs.readdirSync(tempDir).forEach((file) => {
          const filePath = path.join(tempDir, file);
          if (file.endsWith('.mp3') || file.endsWith('.m4a')) {
            fs.unlinkSync(filePath);
          }
        });
      } catch (error) {
        console.error('清除音频缓存文件失败:', error);
      }
    }
  });
}

/**
 * 处理下载请求
 */
function handleDownloadRequest(
  event: Electron.IpcMainEvent,
  {
    url,
    filename,
    songInfo,
    type
  }: { url: string; filename: string; songInfo?: any; type?: string }
) {
  // 检查是否已经在队列中或正在下载
  if (downloadQueue.some((item) => item.filename === filename)) {
    event.reply('music-download-error', {
      filename,
      error: '该歌曲已在下载队列中'
    });
    return;
  }

  // 检查是否已下载
  const store = new Store();
  const songInfos = store.get('downloadedSongs', {}) as Record<string, any>;

  // 检查是否已下载（通过ID）
  const isDownloaded =
    songInfo?.id && Object.values(songInfos).some((info: any) => info.id === songInfo.id);

  if (isDownloaded) {
    event.reply('music-download-error', {
      filename,
      error: '该歌曲已下载'
    });
    return;
  }

  // 添加到下载队列
  downloadQueue.push({ url, filename, songInfo, type });
  event.reply('music-download-queued', {
    filename,
    songInfo
  });

  // 尝试开始下载
  processDownloadQueue(event);
}

/**
 * 处理下载队列
 */
async function processDownloadQueue(event: Electron.IpcMainEvent) {
  if (activeDownloads >= MAX_CONCURRENT_DOWNLOADS || downloadQueue.length === 0) {
    return;
  }

  const { url, filename, songInfo, type } = downloadQueue.shift()!;
  activeDownloads++;

  try {
    await downloadMusic(event, { url, filename, songInfo, type });
  } finally {
    activeDownloads--;
    processDownloadQueue(event);
  }
}

/**
 * 清理文件名中的非法字符
 */
function sanitizeFilename(filename: string): string {
  // 替换 Windows 和 Unix 系统中的非法字符
  return filename
    .replace(/[<>:"/\\|?*]/g, '_') // 替换特殊字符为下划线
    .replace(/\s+/g, ' ') // 将多个空格替换为单个空格
    .trim(); // 移除首尾空格
}

/**
 * 下载音乐和歌词
 */
async function downloadMusic(
  event: Electron.IpcMainEvent,
  {
    url,
    filename,
    songInfo,
    type = 'mp3'
  }: { url: string; filename: string; songInfo: any; type?: string }
) {
  let finalFilePath = '';
  let writer: fs.WriteStream | null = null;
  let tempFilePath = '';

  try {
    // 使用配置Store来获取设置
    const configStore = getStore();
    const downloadPath =
      (configStore.get('set.downloadPath') as string) || app.getPath('downloads');
    const apiPort = configStore.get('set.musicApiPort') || 30488;
    
    // 获取文件名格式设置
    const nameFormat = 
      (configStore.get('set.downloadNameFormat') as string) || '{songName} - {artistName}';

    // 根据格式创建文件名
    let formattedFilename = filename;
    if (songInfo) {
      // 准备替换变量
      const artistName = songInfo.ar?.map((a: any) => a.name).join('/') || '未知艺术家';
      const songName = songInfo.name || filename;
      const albumName = songInfo.al?.name || '未知专辑';
      
      // 应用自定义格式
      formattedFilename = nameFormat
        .replace(/\{songName\}/g, songName)
        .replace(/\{artistName\}/g, artistName)
        .replace(/\{albumName\}/g, albumName);
    }

    // 清理文件名中的非法字符
    const sanitizedFilename = sanitizeFilename(formattedFilename);

    // 创建临时文件路径 (在系统临时目录中创建)
    const tempDir = path.join(os.tmpdir(), 'AlgerMusicPlayerTemp');
    
    // 确保临时目录存在
    if (!fs.existsSync(tempDir)) {
      fs.mkdirSync(tempDir, { recursive: true });
    }
    
    tempFilePath = path.join(tempDir, `${Date.now()}_${sanitizedFilename}.tmp`);

    // 先获取文件大小
    const headResponse = await axios.head(url);
    const totalSize = parseInt(headResponse.headers['content-length'] || '0', 10);

    // 开始下载到临时文件
    const response = await axios({
      url,
      method: 'GET',
      responseType: 'stream',
      timeout: 30000, // 30秒超时
      httpAgent: new http.Agent({ keepAlive: true }),
      httpsAgent: new https.Agent({ keepAlive: true })
    });

    writer = fs.createWriteStream(tempFilePath);
    let downloadedSize = 0;

    // 使用 data 事件来跟踪下载进度
    response.data.on('data', (chunk: Buffer) => {
      downloadedSize += chunk.length;
      const progress = Math.round((downloadedSize / totalSize) * 100);
      event.reply('music-download-progress', {
        filename,
        progress,
        loaded: downloadedSize,
        total: totalSize,
        path: tempFilePath,
        status: progress === 100 ? 'completed' : 'downloading',
        songInfo: songInfo || {
          name: filename,
          ar: [{ name: '本地音乐' }],
          picUrl: '/images/default_cover.png'
        }
      });
    });

    // 等待下载完成
    await new Promise((resolve, reject) => {
      writer!.on('finish', () => resolve(undefined));
      writer!.on('error', (error) => reject(error));
      response.data.pipe(writer!);
    });

    // 验证文件是否完整下载
    const stats = fs.statSync(tempFilePath);
    if (stats.size !== totalSize) {
      throw new Error('文件下载不完整');
    }

    // 检测文件类型
    let fileExtension = '';
    
    try {
      // 首先尝试使用file-type库检测
      const fileType = await fileTypeFromFile(tempFilePath);
      if (fileType && fileType.ext) {
        fileExtension = `.${fileType.ext}`;
        console.log(`文件类型检测结果: ${fileType.mime}, 扩展名: ${fileExtension}`);
      } else {
        // 如果file-type无法识别，尝试使用music-metadata
        const metadata = await mm.parseFile(tempFilePath);
        if (metadata && metadata.format) {
          // 根据format.container或codec判断扩展名
          const formatInfo = metadata.format;
          const container = formatInfo.container || '';
          const codec = formatInfo.codec || '';
          
          // 音频格式映射表
          const formatMap = {
            'mp3': ['MPEG', 'MP3', 'mp3'],
            'aac': ['AAC'],
            'flac': ['FLAC'],
            'ogg': ['Ogg', 'Vorbis'],
            'wav': ['WAV', 'PCM'],
            'm4a': ['M4A', 'MP4']
          };
          
          // 查找匹配的格式
          const format = Object.entries(formatMap).find(([_, keywords]) => 
            keywords.some(keyword => container.includes(keyword) || codec.includes(keyword))
          );
          
          // 设置文件扩展名，如果没找到则默认为mp3
          fileExtension = format ? `.${format[0]}` : '.mp3';
          
          console.log(`music-metadata检测结果: 容器:${container}, 编码:${codec}, 扩展名: ${fileExtension}`);
        } else {
          // 两种方法都失败，使用传入的type或默认mp3
          fileExtension = type ? `.${type}` : '.mp3';
          console.log(`无法检测文件类型，使用默认扩展名: ${fileExtension}`);
        }
      }
    } catch (err) {
      console.error('检测文件类型失败:', err);
      // 检测失败，使用传入的type或默认mp3
      fileExtension = type ? `.${type}` : '.mp3';
    }

    // 使用检测到的文件扩展名创建最终文件路径
    const filePath = path.join(downloadPath, `${sanitizedFilename}${fileExtension}`);

    // 检查文件是否已存在，如果存在则添加序号
    finalFilePath = filePath;
    let counter = 1;
    while (fs.existsSync(finalFilePath)) {
      const ext = path.extname(filePath);
      const nameWithoutExt = filePath.slice(0, -ext.length);
      finalFilePath = `${nameWithoutExt} (${counter})${ext}`;
      counter++;
    }

    // 将临时文件移动到最终位置
    fs.copyFileSync(tempFilePath, finalFilePath);
    fs.unlinkSync(tempFilePath); // 删除临时文件

    // 下载歌词
    let lyricData = null;
    let lyricsContent = '';
    try {
      if (songInfo?.id) {
        // 下载歌词，使用配置的端口
        const lyricsResponse = await axios.get(
          `http://localhost:${apiPort}/lyric?id=${songInfo.id}`
        );
        if (lyricsResponse.data && (lyricsResponse.data.lrc || lyricsResponse.data.tlyric)) {
          lyricData = lyricsResponse.data;

          // 处理歌词内容
          if (lyricsResponse.data.lrc && lyricsResponse.data.lrc.lyric) {
            lyricsContent = lyricsResponse.data.lrc.lyric;

            // 如果有翻译歌词，合并到主歌词中
            if (lyricsResponse.data.tlyric && lyricsResponse.data.tlyric.lyric) {
              // 解析原歌词和翻译
              const originalLyrics = parseLyrics(lyricsResponse.data.lrc.lyric);
              const translatedLyrics = parseLyrics(lyricsResponse.data.tlyric.lyric);

              // 合并歌词
              const mergedLyrics = mergeLyrics(originalLyrics, translatedLyrics);
              lyricsContent = mergedLyrics;
            }
          }

          console.log('歌词已准备好，将写入元数据');
        }
      }
    } catch (lyricError) {
      console.error('下载歌词失败:', lyricError);
      // 继续处理，不影响音乐下载
    }

    // 下载封面
    let coverImageBuffer: Buffer | null = null;
    try {
      if (songInfo?.picUrl || songInfo?.al?.picUrl) {
        const picUrl = songInfo.picUrl || songInfo.al?.picUrl;
        if (picUrl && picUrl !== '/images/default_cover.png') {
          const coverResponse = await axios({
            url: picUrl.replace('http://', 'https://'),
            method: 'GET',
            responseType: 'arraybuffer',
            timeout: 10000
          });

          // 获取封面图片的buffer
          coverImageBuffer = Buffer.from(coverResponse.data);
          console.log('封面已准备好，将写入元数据');
        }
      }
    } catch (coverError) {
      console.error('下载封面失败:', coverError);
      // 继续处理，不影响音乐下载
    }

    const fileFormat = fileExtension.toLowerCase();
    const artistNames =
      (songInfo?.ar || songInfo?.song?.artists)?.map((a: any) => a.name).join('/ ') || '未知艺术家';

    // 根据文件类型处理元数据
    if (['.mp3'].includes(fileFormat)) {
      // 对MP3文件使用NodeID3处理ID3标签
      try {
        // 在写入ID3标签前，先移除可能存在的旧标签
        NodeID3.removeTags(finalFilePath);
        
        const tags = {
          title: filename,
          artist: artistNames,
          TPE1: artistNames,
          TPE2: artistNames,
          album: songInfo?.al?.name || songInfo?.song?.album?.name || songInfo?.name || filename,
          APIC: {
            // 专辑封面
            imageBuffer: coverImageBuffer,
            type: {
              id: 3,
              name: 'front cover'
            },
            description: 'Album cover',
            mime: 'image/jpeg'
          },
          USLT: {
            // 歌词
            language: 'chi',
            description: 'Lyrics',
            text: lyricsContent || ''
          },
          trackNumber: songInfo?.no || undefined,
          year: songInfo?.publishTime
            ? new Date(songInfo.publishTime).getFullYear().toString()
            : undefined
        };

        const success = NodeID3.write(tags, finalFilePath);
        if (!success) {
          console.error('Failed to write ID3 tags');
        } else {
          console.log('ID3 tags written successfully');
        }
      } catch (err) {
        console.error('Error writing ID3 tags:', err);
      }
    } else {
      // 对于非MP3文件，使用music-metadata来写入元数据可能需要专门的库
      // 或者根据不同文件类型使用专用工具，暂时只记录但不处理
      console.log(`文件类型 ${fileFormat} 不支持使用NodeID3写入标签，跳过元数据写入`);
    }

    // 保存下载信息
    try {
      const songInfos = configStore.get('downloadedSongs', {}) as Record<string, any>;
      const defaultInfo = {
        name: filename,
        ar: [{ name: '本地音乐' }],
        picUrl: '/images/default_cover.png'
      };

      const newSongInfo = {
        id: songInfo?.id || 0,
        name: songInfo?.name || filename,
        filename,
        picUrl: songInfo?.picUrl || songInfo?.al?.picUrl || defaultInfo.picUrl,
        ar: songInfo?.ar || defaultInfo.ar,
        al: songInfo?.al || {
          picUrl: songInfo?.picUrl || defaultInfo.picUrl,
          name: songInfo?.name || filename
        },
        size: totalSize,
        path: finalFilePath,
        downloadTime: Date.now(),
        type: fileExtension.substring(1), // 去掉前面的点号，只保留扩展名
        lyric: lyricData
      };

      // 保存到下载记录
      songInfos[finalFilePath] = newSongInfo;
      configStore.set('downloadedSongs', songInfos);

      // 添加到下载历史
      const history = downloadStore.get('history', []) as any[];
      history.unshift(newSongInfo);
      downloadStore.set('history', history);

      // 避免重复发送通知
      const notificationId = `download-${finalFilePath}`;
      if (!sentNotifications.has(notificationId)) {
        sentNotifications.set(notificationId, true);
        
        // 发送桌面通知
        try {
          const artistNames =
            (songInfo?.ar || songInfo?.song?.artists)?.map((a: any) => a.name).join('/') ||
            '未知艺术家';
          const notification = new Notification({
            title: '下载完成',
            body: `${songInfo?.name || filename} - ${artistNames}`,
            silent: false
          });
  
          notification.on('click', () => {
            shell.showItemInFolder(finalFilePath);
          });
  
          notification.show();
          
          // 60秒后清理通知记录，释放内存
          setTimeout(() => {
            sentNotifications.delete(notificationId);
          }, 60000);
        } catch (notifyError) {
          console.error('发送通知失败:', notifyError);
        }
      }

      // 发送下载完成事件，确保只发送一次
      event.reply('music-download-complete', {
        success: true,
        path: finalFilePath,
        filename,
        size: totalSize,
        songInfo: newSongInfo
      });
    } catch (error) {
      console.error('Error saving download info:', error);
      throw new Error('保存下载信息失败');
    }
  } catch (error: any) {
    console.error('Download error:', error);

    // 清理未完成的下载
    if (writer) {
      writer.end();
    }
    
    // 清理临时文件
    if (tempFilePath && fs.existsSync(tempFilePath)) {
      try {
        fs.unlinkSync(tempFilePath);
      } catch (e) {
        console.error('Failed to delete temporary file:', e);
      }
    }
    
    // 清理未完成的最终文件
    if (finalFilePath && fs.existsSync(finalFilePath)) {
      try {
        fs.unlinkSync(finalFilePath);
      } catch (e) {
        console.error('Failed to delete incomplete download:', e);
      }
    }

    event.reply('music-download-complete', {
      success: false,
      error: error.message || '下载失败',
      filename
    });
  }
}

// 辅助函数 - 解析歌词文本成时间戳和内容的映射
function parseLyrics(lyricsText: string): Map<string, string> {
  const lyricMap = new Map<string, string>();
  const lines = lyricsText.split('\n');

  for (const line of lines) {
    // 匹配时间标签，形如 [00:00.000]
    const timeTagMatches = line.match(/\[\d{2}:\d{2}(\.\d{1,3})?\]/g);
    if (!timeTagMatches) continue;

    // 提取歌词内容（去除时间标签）
    const content = line.replace(/\[\d{2}:\d{2}(\.\d{1,3})?\]/g, '').trim();
    if (!content) continue;

    // 将每个时间标签与歌词内容关联
    for (const timeTag of timeTagMatches) {
      lyricMap.set(timeTag, content);
    }
  }

  return lyricMap;
}

// 辅助函数 - 合并原文歌词和翻译歌词
function mergeLyrics(
  originalLyrics: Map<string, string>,
  translatedLyrics: Map<string, string>
): string {
  const mergedLines: string[] = [];

  // 对每个时间戳，组合原始歌词和翻译
  for (const [timeTag, originalContent] of originalLyrics.entries()) {
    const translatedContent = translatedLyrics.get(timeTag);

    // 添加原始歌词行
    mergedLines.push(`${timeTag}${originalContent}`);

    // 如果有翻译，添加翻译行（时间戳相同，这样可以和原歌词同步显示）
    if (translatedContent) {
      mergedLines.push(`${timeTag}${translatedContent}`);
    }
  }

  // 按时间顺序排序
  mergedLines.sort((a, b) => {
    const timeA = a.match(/\[\d{2}:\d{2}(\.\d{1,3})?\]/)?.[0] || '';
    const timeB = b.match(/\[\d{2}:\d{2}(\.\d{1,3})?\]/)?.[0] || '';
    return timeA.localeCompare(timeB);
  });

  return mergedLines.join('\n');
}
