// 支付处理模块

const fs = require('fs');
const path = require('path');
const { promisify } = require('util');
const { getDatabase } = require('./sql');

const copyFile = promisify(fs.copyFile);
const mkdir = promisify(fs.mkdir);
const access = promisify(fs.access);
const readdir = promisify(fs.readdir);
const stat = promisify(fs.stat);

// 用户数据根目录
const USERS_DIR = path.join(__dirname, 'users');
// 商店资源目录
const STORE_DIR = path.join(__dirname, 'market_data');
// 购买记录文件
const PURCHASE_RECORDS_FILE = path.join(__dirname, 'purchase-records.json');

// 确保目录存在
async function ensureDir(dirPath) {
  try {
    await access(dirPath);
  } catch (error) {
    await mkdir(dirPath, { recursive: true });
  }
}

// 读取购买记录
async function getPurchaseRecords() {
  try {
    const data = await fs.promises.readFile(PURCHASE_RECORDS_FILE, 'utf-8');
    return JSON.parse(data);
  } catch (error) {
    // 如果文件不存在，返回空对象
    return {};
  }
}

// 保存购买记录
async function savePurchaseRecords(records) {
  await fs.promises.writeFile(PURCHASE_RECORDS_FILE, JSON.stringify(records, null, 2), 'utf-8');
}

// 检查用户是否已购买过该资源
async function hasUserPurchased(username, resourcePath) {
  const records = await getPurchaseRecords();
  const normalizedUsername = username.toLowerCase();
  const userPurchases = records[normalizedUsername] || [];
  return userPurchases.includes(resourcePath);
}

// 记录用户购买
async function recordPurchase(username, resourcePath) {
  const records = await getPurchaseRecords();
  const normalizedUsername = username.toLowerCase();
  
  if (!records[normalizedUsername]) {
    records[normalizedUsername] = [];
  }
  
  // 如果还没有记录，则添加
  if (!records[normalizedUsername].includes(resourcePath)) {
    records[normalizedUsername].push(resourcePath);
    await savePurchaseRecords(records);
    console.log(`[Pay] 已记录购买: ${normalizedUsername} -> ${resourcePath}`);
  }
}

// 获取用户网盘目录
function getUserDiskDir(username) {
  const normalizedUsername = username.toLowerCase();
  return path.join(USERS_DIR, normalizedUsername, 'disk_data');
}

// 递归复制目录
async function copyDirectory(src, dest) {
  console.log(`[Pay]     [copyDirectory] 创建目标目录: ${dest}`);
  await ensureDir(dest);
  
  console.log(`[Pay]     [copyDirectory] 读取源目录: ${src}`);
  const entries = await readdir(src);
  console.log(`[Pay]     [copyDirectory] 找到 ${entries.length} 个项目`);
  
  for (let i = 0; i < entries.length; i++) {
    const entry = entries[i];
    const srcPath = path.join(src, entry);
    const destPath = path.join(dest, entry);
    
    console.log(`[Pay]     [copyDirectory] [${i + 1}/${entries.length}] 处理: ${entry}`);
    
    try {
      const stats = await stat(srcPath);
      
      if (stats.isDirectory()) {
        console.log(`[Pay]     [copyDirectory]   类型: 目录，递归复制`);
        await copyDirectory(srcPath, destPath);
        console.log(`[Pay]     [copyDirectory]   ✓ 目录复制完成: ${entry}`);
      } else {
        console.log(`[Pay]     [copyDirectory]   类型: 文件，大小: ${stats.size} 字节`);
        await copyFile(srcPath, destPath);
        console.log(`[Pay]     [copyDirectory]   ✓ 文件复制完成: ${entry}`);
      }
    } catch (entryError) {
      console.error(`[Pay]     [copyDirectory]   ✗ 处理失败: ${entry}`, entryError);
      throw entryError;
    }
  }
  
  console.log(`[Pay]     [copyDirectory] ✓ 目录复制完成: ${src} -> ${dest}`);
}

// 处理购买请求
async function handlePurchaseRequest(req, res) {
  let body = '';
  
  req.on('data', chunk => {
    body += chunk.toString();
  });
  
  req.on('end', async () => {
    try {
      console.log('\n========== [Pay] 收到购买请求 ==========');
      console.log('[Pay] 原始请求体:', body);
      
      const data = JSON.parse(body);
      const { username, resourcePath, categoryDir, itemName, price, points } = data;
      // 兼容 price 和 points 两种参数名
      const finalPrice = price !== undefined ? price : (points !== undefined ? points : 0);
      
      console.log('[Pay] 解析后的参数:');
      console.log('  - username:', username);
      console.log('  - resourcePath:', resourcePath);
      console.log('  - categoryDir:', categoryDir);
      console.log('  - itemName:', itemName);
      console.log('  - price:', price);
      console.log('  - points:', points);
      console.log('  - finalPrice:', finalPrice);
      
      if (!username) {
        res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' });
        res.end(JSON.stringify({
          success: false,
          message: '缺少用户名参数'
        }));
        return;
      }
      
      if (!resourcePath || !categoryDir) {
        res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' });
        res.end(JSON.stringify({
          success: false,
          message: '缺少资源路径参数'
        }));
        return;
      }
      
      // 构建源路径（商店资源路径）
      // resourcePath 格式为 "categoryDir/itemName"，例如 "charactor/player_0001"
      let sourcePath;
      if (resourcePath && resourcePath.includes('/')) {
        // resourcePath 已经包含分类目录
        sourcePath = path.join(STORE_DIR, resourcePath);
      } else if (categoryDir && resourcePath) {
        // resourcePath 只是资源名称，需要拼接分类目录
        sourcePath = path.join(STORE_DIR, categoryDir, resourcePath);
      } else {
        res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' });
        res.end(JSON.stringify({
          success: false,
          message: '资源路径格式错误'
        }));
        return;
      }
      
      console.log(`[Pay] 构建源路径: STORE_DIR=${STORE_DIR}, resourcePath=${resourcePath}, categoryDir=${categoryDir}, sourcePath=${sourcePath}`);
      
      // 检查源文件/文件夹是否存在
      try {
        await access(sourcePath);
      } catch (error) {
        console.error(`[Pay] 资源不存在: ${sourcePath}`, error);
        res.writeHead(404, { 'Content-Type': 'application/json; charset=utf-8' });
        res.end(JSON.stringify({
          success: false,
          message: `资源不存在: ${sourcePath}`
        }));
        return;
      }
      
      // 获取用户网盘目录
      console.log('[Pay] 步骤1: 获取用户网盘目录');
      const userDiskDir = getUserDiskDir(username);
      console.log('[Pay]   用户网盘目录:', userDiskDir);
      
      console.log('[Pay] 步骤2: 确保用户网盘目录存在');
      await ensureDir(userDiskDir);
      console.log('[Pay]   ✓ 用户网盘目录已存在或已创建');
      
      // 目标路径（用户网盘根目录）
      // resourcePath 格式为 "categoryDir/itemName"，例如 "角色/player_0001"
      // 只取最后一级目录名（资源名），直接放到根目录
      const resourceName = itemName || path.basename(resourcePath);
      
      // 生成唯一的文件名（如果已存在，自动添加（1）、（2）等后缀）
      console.log('[Pay] 步骤3: 生成唯一的目标路径');
      let finalResourceName = resourceName;
      let destPath = path.join(userDiskDir, finalResourceName);
      let counter = 0;
      
      // 检查目标路径是否已存在，如果存在则生成新名称
      while (true) {
        try {
          await access(destPath);
          // 文件/文件夹已存在，生成新名称
          counter++;
          // 检查是否是文件夹（没有扩展名）还是文件
          const parsed = path.parse(resourceName);
          if (parsed.ext) {
            // 是文件，保留扩展名
            finalResourceName = `${parsed.name}（${counter}）${parsed.ext}`;
          } else {
            // 是文件夹，直接添加后缀
            finalResourceName = `${resourceName}（${counter}）`;
          }
          destPath = path.join(userDiskDir, finalResourceName);
          console.log(`[Pay]   名称冲突，尝试新名称: ${finalResourceName}`);
        } catch (error) {
          // 文件/文件夹不存在，可以使用这个名称
          console.log(`[Pay]   ✓ 找到可用名称: ${finalResourceName}`);
          break;
        }
      }
      
      console.log(`[Pay]   最终资源名称: ${finalResourceName}`);
      console.log(`[Pay]   最终目标路径: ${destPath}`);
      
      // 检查并扣除用户点数
      console.log('[Pay] 步骤4: 检查并扣除用户点数');
      if (finalPrice && finalPrice > 0) {
        const db = await getDatabase();
        const currentPoints = db.getUserPoints(username);
        console.log(`[Pay]   当前点数: ${currentPoints}, 需要点数: ${finalPrice}`);
        
        if (currentPoints < finalPrice) {
          console.log('[Pay]   ✗ 点数不足');
          res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' });
          res.end(JSON.stringify({
            success: false,
            message: '点数不足'
          }));
          return;
        }
        
        // 扣除点数
        const deducted = db.deductPoints(username, finalPrice);
        if (!deducted) {
          console.log('[Pay]   ✗ 扣除点数失败');
          res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' });
          res.end(JSON.stringify({
            success: false,
            message: '扣除点数失败'
          }));
          return;
        }
        
        console.log(`[Pay]   ✓ 用户 ${username} 扣除 ${finalPrice} 点数成功`);
      } else {
        console.log('[Pay]   免费资源，跳过点数检查');
      }
      
      // 复制文件/文件夹到用户网盘
      console.log('[Pay] 步骤5: 检查源路径类型');
      const sourceStats = await stat(sourcePath);
      console.log(`[Pay]   源路径类型: ${sourceStats.isDirectory() ? '目录' : '文件'}`);
      console.log(`[Pay]   源路径大小: ${sourceStats.size} 字节`);
      
      try {
        if (sourceStats.isDirectory()) {
          // 复制文件夹
          console.log('[Pay] 步骤6: 开始复制文件夹');
          console.log(`[Pay]   源文件夹: ${sourcePath}`);
          console.log(`[Pay]   目标文件夹: ${destPath}`);
          
          // 先确保目标目录的父目录存在
          const destParentDir = path.dirname(destPath);
          console.log(`[Pay]   确保父目录存在: ${destParentDir}`);
          await ensureDir(destParentDir);
          console.log(`[Pay]   ✓ 父目录已存在或已创建`);
          
          console.log(`[Pay]   开始递归复制...`);
          await copyDirectory(sourcePath, destPath);
          console.log(`[Pay]   ✓ 文件夹复制完成`);
          
          // 验证复制是否成功
          console.log('[Pay] 步骤9: 验证复制结果');
          try {
            const destStats = await stat(destPath);
            console.log(`[Pay]   ✓ 目标文件夹存在: ${destPath}`);
            console.log(`[Pay]   目标文件夹类型: ${destStats.isDirectory() ? '目录' : '文件'}`);
            
            // 检查文件夹内容
            const destFiles = await readdir(destPath);
            console.log(`[Pay]   目标文件夹包含 ${destFiles.length} 个项目`);
            if (destFiles.length > 0) {
              console.log(`[Pay]   前5个项目: ${destFiles.slice(0, 5).join(', ')}`);
            }
          } catch (verifyError) {
            console.error(`[Pay]   ✗ 验证失败，目标文件夹不存在: ${destPath}`);
            console.error(`[Pay]   错误详情:`, verifyError);
            throw new Error('复制失败：目标文件夹未创建');
          }
        } else {
          // 复制文件
          console.log('[Pay] 步骤6: 开始复制文件');
          const destParentDir = path.dirname(destPath);
          console.log(`[Pay]   确保父目录存在: ${destParentDir}`);
          await ensureDir(destParentDir);
          console.log(`[Pay]   ✓ 父目录已存在或已创建`);
          
          console.log(`[Pay]   源文件: ${sourcePath}`);
          console.log(`[Pay]   目标文件: ${destPath}`);
          console.log(`[Pay]   开始复制文件...`);
          await copyFile(sourcePath, destPath);
          console.log(`[Pay]   ✓ 文件复制完成`);
          
          // 验证复制是否成功
          console.log('[Pay] 步骤7: 验证复制结果');
          try {
            const destStats = await stat(destPath);
            console.log(`[Pay]   ✓ 目标文件存在: ${destPath}`);
            console.log(`[Pay]   目标文件大小: ${destStats.size} 字节`);
          } catch (verifyError) {
            console.error(`[Pay]   ✗ 验证失败，目标文件不存在: ${destPath}`);
            console.error(`[Pay]   错误详情:`, verifyError);
            throw new Error('复制失败：目标文件未创建');
          }
        }
      } catch (copyError) {
        console.error(`[Pay] ✗ 复制过程出错:`);
        console.error(`[Pay]   错误类型: ${copyError.constructor.name}`);
        console.error(`[Pay]   错误消息: ${copyError.message}`);
        console.error(`[Pay]   错误堆栈:`, copyError.stack);
        throw copyError;
      }
      
      // 记录购买（即使文件被删除，购买记录也会保留）
      console.log('[Pay] 步骤8: 记录购买');
      await recordPurchase(username, resourcePath);
      console.log(`[Pay]   ✓ 购买记录已保存`);
      
      // 返回成功
      console.log('[Pay] 步骤9: 返回成功响应');
      console.log(`[Pay] ✓ 购买成功！资源已添加到用户网盘`);
      console.log(`[Pay]   用户名: ${username}`);
      console.log(`[Pay]   资源路径: ${resourcePath}`);
      console.log(`[Pay]   目标路径: ${destPath}`);
      console.log('========== [Pay] 购买请求处理完成 ==========\n');
      
      res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
      res.end(JSON.stringify({
        success: true,
        message: '购买成功，文件已添加到网盘',
        itemName: itemName,
        price: finalPrice,
        destPath: destPath
      }));
      
    } catch (error) {
      console.error('\n========== [Pay] 购买请求处理失败 ==========');
      console.error('[Pay] 错误类型:', error.constructor.name);
      console.error('[Pay] 错误消息:', error.message);
      console.error('[Pay] 错误堆栈:', error.stack);
      console.error('========== [Pay] 错误信息结束 ==========\n');
      
      res.writeHead(500, { 'Content-Type': 'application/json; charset=utf-8' });
      res.end(JSON.stringify({
        success: false,
        message: '购买失败: ' + error.message
      }));
    }
  });
}

// 检查资源是否已存在于用户网盘根目录或购买记录中
async function checkResourceExists(username, resourcePath) {
  try {
    // 首先检查购买记录（即使文件被删除，购买记录仍然保留）
    const hasPurchased = await hasUserPurchased(username, resourcePath);
    if (hasPurchased) {
      console.log(`[Pay] 资源在购买记录中: ${username} -> ${resourcePath}`);
      return true; // 已购买过，即使文件不存在也返回true
    }
    
    // 然后检查文件是否存在
    const userDiskDir = getUserDiskDir(username);
    // 只使用资源名，检查根目录
    const resourceName = path.basename(resourcePath);
    const destPath = path.join(userDiskDir, resourceName);
    
    try {
      await access(destPath);
      return true; // 资源已存在
    } catch (error) {
      return false; // 资源不存在
    }
  } catch (error) {
    console.error(`[Pay] 检查资源是否存在失败:`, error);
    return false;
  }
}

// 处理检查资源是否存在的请求
async function handleCheckResourceRequest(req, res) {
  const parsedUrl = require('url').parse(req.url, true);
  const { username, resourcePath } = parsedUrl.query;
  
  if (!username || !resourcePath) {
    res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' });
    res.end(JSON.stringify({
      success: false,
      message: '缺少参数'
    }));
    return;
  }
  
  try {
    const exists = await checkResourceExists(username, resourcePath);
    res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
    res.end(JSON.stringify({
      success: true,
      exists: exists
    }));
  } catch (error) {
    console.error('[Pay] 检查资源失败:', error);
    res.writeHead(500, { 'Content-Type': 'application/json; charset=utf-8' });
    res.end(JSON.stringify({
      success: false,
      message: '检查失败: ' + error.message
    }));
  }
}

// 获取用户购买记录（包含资源详细信息）
async function getUserPurchaseHistory(username) {
  try {
    const records = await getPurchaseRecords();
    const normalizedUsername = username.toLowerCase();
    const userPurchases = records[normalizedUsername] || [];
    
    // 获取资源详细信息
    const StoreManager = require('./store/store');
    const storeManager = new StoreManager();
    
    const purchaseHistory = [];
    for (const resourcePath of userPurchases) {
      try {
        // resourcePath 格式为 "分类/资源名"，例如 "角色/player_0001"
        const parts = resourcePath.split('/');
        if (parts.length === 2) {
          const [categoryDir, resourceName] = parts;
          const resourcePath_full = path.join(STORE_DIR, resourcePath);
          
          // 检查资源是否存在
          try {
            await access(resourcePath_full);
            
            // 获取预览图
            const previewInfo = await storeManager.getFirstFrame(resourcePath_full);
            
            // 获取资源价格
            const price = await storeManager.getResourcePrice(resourcePath);
            
            purchaseHistory.push({
              name: resourceName,
              category: categoryDir,
              path: resourcePath,
              previewUrl: previewInfo.hasPreview 
                ? `/api/store/preview?category=${encodeURIComponent(categoryDir)}&folder=${encodeURIComponent(resourceName)}&file=${encodeURIComponent(previewInfo.previewFile)}`
                : null,
              points: price
            });
          } catch (error) {
            // 资源文件不存在，但仍然显示在购买记录中（可能被删除）
            purchaseHistory.push({
              name: resourceName,
              category: categoryDir,
              path: resourcePath,
              previewUrl: null,
              points: 0,
              deleted: true // 标记为已删除
            });
          }
        }
      } catch (error) {
        console.error(`[Pay] 获取购买记录资源信息失败: ${resourcePath}`, error);
      }
    }
    
    return purchaseHistory;
  } catch (error) {
    console.error('[Pay] 获取购买记录失败:', error);
    return [];
  }
}

// 处理获取购买记录请求
async function handleGetPurchaseHistory(req, res) {
  try {
    const url = new URL(req.url, `http://${req.headers.host}`);
    const username = url.searchParams.get('username');
    
    if (!username) {
      res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' });
      res.end(JSON.stringify({
        success: false,
        message: '缺少用户名参数'
      }));
      return;
    }
    
    const history = await getUserPurchaseHistory(username);
    
    res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
    res.end(JSON.stringify({
      success: true,
      history: history
    }));
  } catch (error) {
    console.error('[Pay] 获取购买记录失败:', error);
    res.writeHead(500, { 'Content-Type': 'application/json; charset=utf-8' });
    res.end(JSON.stringify({
      success: false,
      message: '获取购买记录失败: ' + error.message
    }));
  }
}

module.exports = {
  handlePurchaseRequest,
  checkResourceExists,
  handleCheckResourceRequest,
  handleGetPurchaseHistory
};

