import type { IncomingMessage, ServerResponse } from 'http';
import fs from 'fs';
import path from 'path';

const TARGET_EXTENSIONS = ['.js', '.ts', '.jsx', '.tsx'];

async function getAllFilePaths(dirPath: string): Promise<string[]> {
  let files: string[] = [];
  try {
    const items = await fs.promises.readdir(dirPath, { withFileTypes: true });
    for (const item of items) {
      const fullPath = path.join(dirPath, item.name);
      if (item.isDirectory()) {
        files = files.concat(await getAllFilePaths(fullPath));
      } else if (item.isFile()) {
        const ext = path.extname(item.name).toLowerCase();
        if (TARGET_EXTENSIONS.includes(ext)) {
          files.push(fullPath);
        }
      }
    }
  } catch (err) {
    console.error(`读取目录失败: ${dirPath}`, err);
  }
  return files;
}

type TextReplacement = { searchText: string; replaceText: string };

async function replaceMatches(dirPath: string, searchText: string, replaceText: string): Promise<number> {
  let changedFilesCount = 0;
  const files = await getAllFilePaths(dirPath);

  for (const file of files) {
    try {
      const content = await fs.promises.readFile(file, 'utf-8');
      if (content.includes(searchText)) {
        const newContent = content.replaceAll(searchText, replaceText);
        await fs.promises.writeFile(file, newContent, 'utf-8');
        console.log(`[API] ✅ 已修改: ${file}`);
        changedFilesCount++;
      }
    } catch (err) {
      console.error(`处理文件失败: ${file}`, err);
    }
  }

  return changedFilesCount;
}

async function replaceMatchesBatch(dirPath: string, replacements: TextReplacement[]): Promise<number> {
  let changedFilesCount = 0;
  const files = await getAllFilePaths(dirPath);

  for (const file of files) {
    try {
      const content = await fs.promises.readFile(file, 'utf-8');
      let newContent = content;
      let changed = false;

      for (const { searchText, replaceText } of replacements) {
        if (!searchText) continue;
        if (newContent.includes(searchText)) {
          newContent = newContent.replaceAll(searchText, replaceText);
          changed = true;
        }
      }

      if (changed && newContent !== content) {
        await fs.promises.writeFile(file, newContent, 'utf-8');
        console.log(`[API] ✅ 已修改: ${file}`);
        changedFilesCount++;
      }
    } catch (err) {
      console.error(`处理文件失败: ${file}`, err);
    }
  }

  return changedFilesCount;
}

export function handleTextReplace(req: IncomingMessage, res: ServerResponse): boolean {
  if (req.method === 'POST' && req.url?.startsWith('/api/text-replace/replace')) {
    let body = '';
    
    req.on('data', chunk => {
      body += chunk.toString();
    });
    
    req.on('end', async () => {
      try {
        const { path: targetPath, searchText, replaceText, replacements } = JSON.parse(body);
        
        if (!targetPath || (!searchText && !Array.isArray(replacements))) {
          res.statusCode = 400;
          res.setHeader('Content-Type', 'application/json');
          res.end(JSON.stringify({ error: 'path and replacement data are required' }));
          return;
        }

        const pathParts = targetPath.split('/').filter(Boolean);
        if (pathParts.length < 2 || !['components', 'prototypes'].includes(pathParts[0])) {
          res.statusCode = 400;
          res.setHeader('Content-Type', 'application/json');
          res.end(JSON.stringify({ error: 'Invalid path format. Expected: components/xxx or prototypes/xxx' }));
          return;
        }

        const fullPath = path.resolve(process.cwd(), 'src', targetPath);
        
        if (!fs.existsSync(fullPath)) {
          res.statusCode = 404;
          res.setHeader('Content-Type', 'application/json');
          res.end(JSON.stringify({ error: 'Path not found' }));
          return;
        }

        let changedFiles = 0;
        if (Array.isArray(replacements)) {
          const cleaned = replacements
            .filter((item: any) => item && typeof item.searchText === 'string' && item.replaceText !== undefined)
            .map((item: any) => ({
              searchText: item.searchText,
              replaceText: String(item.replaceText ?? '')
            }));

          if (cleaned.length === 0) {
            res.statusCode = 400;
            res.setHeader('Content-Type', 'application/json');
            res.end(JSON.stringify({ error: 'replacements is empty' }));
            return;
          }

          changedFiles = await replaceMatchesBatch(fullPath, cleaned);
        } else {
          if (!searchText || replaceText === undefined) {
            res.statusCode = 400;
            res.setHeader('Content-Type', 'application/json');
            res.end(JSON.stringify({ error: 'searchText and replaceText are required' }));
            return;
          }

          changedFiles = await replaceMatches(fullPath, searchText, replaceText);
        }
        console.log(`[API] 替换完成: 共修改了 ${changedFiles} 个文件`);

        res.statusCode = 200;
        res.setHeader('Content-Type', 'application/json');
        res.end(JSON.stringify({ success: true, changedFiles }));
      } catch (err) {
        console.error('[API] ❌ 替换文本失败:', err);
        res.statusCode = 500;
        res.setHeader('Content-Type', 'application/json');
        res.end(JSON.stringify({ error: 'Failed to replace text' }));
      }
    });
    
    return true;
  }
  
  return false;
}
