/**
 * Files API Routes
 *
 * 文件浏览器 API
 */

import { Hono } from 'hono';
import { readdir, stat, readFile } from 'node:fs/promises';
import { join, resolve, basename, extname, dirname } from 'node:path';
import { searchFiles as coreSearchFiles, type FileIndexEntry } from '@ai-assistant/core';

const filesRouter = new Hono();

// 工作目录 (默认为当前目录)
let workingDirectory = process.cwd();

/**
 * 设置工作目录
 */
export function setWorkingDirectory(dir: string): void {
  workingDirectory = resolve(dir);
}

/**
 * 获取工作目录
 */
export function getWorkingDirectory(): string {
  return workingDirectory;
}

/**
 * 文件/目录信息
 */
interface FileInfo {
  name: string;
  path: string;
  type: 'file' | 'directory';
  size: number;
  modified: string;
  extension?: string;
}

/**
 * 安全路径检查 - 确保路径在工作目录内
 */
function safePath(requestedPath: string): string | null {
  const resolved = resolve(workingDirectory, requestedPath);
  if (!resolved.startsWith(workingDirectory)) {
    return null;
  }
  return resolved;
}

/**
 * 获取文件类型图标提示
 */
function getFileType(name: string): string {
  const ext = extname(name).toLowerCase();
  const fileTypes: Record<string, string> = {
    '.ts': 'typescript',
    '.tsx': 'typescript',
    '.js': 'javascript',
    '.jsx': 'javascript',
    '.json': 'json',
    '.md': 'markdown',
    '.html': 'html',
    '.css': 'css',
    '.scss': 'scss',
    '.less': 'less',
    '.py': 'python',
    '.go': 'go',
    '.rs': 'rust',
    '.java': 'java',
    '.c': 'c',
    '.cpp': 'cpp',
    '.h': 'header',
    '.sh': 'shell',
    '.bash': 'shell',
    '.zsh': 'shell',
    '.yaml': 'yaml',
    '.yml': 'yaml',
    '.toml': 'toml',
    '.xml': 'xml',
    '.svg': 'svg',
    '.png': 'image',
    '.jpg': 'image',
    '.jpeg': 'image',
    '.gif': 'image',
    '.webp': 'image',
    '.ico': 'image',
    '.txt': 'text',
    '.log': 'log',
    '.env': 'env',
    '.gitignore': 'git',
    '.dockerignore': 'docker',
  };
  return fileTypes[ext] || 'file';
}

/**
 * 判断是否为文本文件
 */
function isTextFile(name: string): boolean {
  const textExtensions = [
    '.ts', '.tsx', '.js', '.jsx', '.json', '.md', '.html', '.css', '.scss',
    '.less', '.py', '.go', '.rs', '.java', '.c', '.cpp', '.h', '.sh', '.bash',
    '.zsh', '.yaml', '.yml', '.toml', '.xml', '.txt', '.log', '.env', '.sql',
    '.graphql', '.prisma', '.vue', '.svelte', '.astro',
  ];
  const ext = extname(name).toLowerCase();
  return textExtensions.includes(ext) || name.startsWith('.');
}

// ============================================================================
// GET /api/files - 获取工作目录信息
// ============================================================================
filesRouter.get('/', (c) => {
  return c.json({
    success: true,
    data: {
      workingDirectory,
      separator: '/',
    },
  });
});

// ============================================================================
// GET /api/files/list?path= - 列出目录内容
// ============================================================================
filesRouter.get('/list', async (c) => {
  const requestedPath = c.req.query('path') || '.';
  const showHidden = c.req.query('hidden') === 'true';

  const absolutePath = safePath(requestedPath);
  if (!absolutePath) {
    return c.json({ success: false, error: 'Access denied: path outside working directory' }, 403);
  }

  try {
    const stats = await stat(absolutePath);
    if (!stats.isDirectory()) {
      return c.json({ success: false, error: 'Not a directory' }, 400);
    }

    const entries = await readdir(absolutePath, { withFileTypes: true });
    const files: FileInfo[] = [];

    for (const entry of entries) {
      // 跳过隐藏文件 (除非明确请求)
      if (!showHidden && entry.name.startsWith('.')) {
        continue;
      }

      const entryPath = join(absolutePath, entry.name);
      const relativePath = entryPath.replace(workingDirectory, '').replace(/^\//, '');

      try {
        const entryStats = await stat(entryPath);
        files.push({
          name: entry.name,
          path: relativePath,
          type: entry.isDirectory() ? 'directory' : 'file',
          size: entryStats.size,
          modified: entryStats.mtime.toISOString(),
          extension: entry.isFile() ? extname(entry.name).slice(1) : undefined,
        });
      } catch {
        // 跳过无法访问的文件
      }
    }

    // 排序: 目录在前，然后按名称
    files.sort((a, b) => {
      if (a.type !== b.type) {
        return a.type === 'directory' ? -1 : 1;
      }
      return a.name.localeCompare(b.name);
    });

    return c.json({
      success: true,
      data: {
        path: requestedPath,
        absolutePath,
        parent: requestedPath === '.' ? null : dirname(requestedPath),
        files,
      },
    });
  } catch (error) {
    const message = error instanceof Error ? error.message : 'Unknown error';
    return c.json({ success: false, error: message }, 500);
  }
});

// ============================================================================
// GET /api/files/read?path= - 读取文件内容
// ============================================================================
filesRouter.get('/read', async (c) => {
  const requestedPath = c.req.query('path');
  if (!requestedPath) {
    return c.json({ success: false, error: 'Path is required' }, 400);
  }

  const absolutePath = safePath(requestedPath);
  if (!absolutePath) {
    return c.json({ success: false, error: 'Access denied: path outside working directory' }, 403);
  }

  try {
    const stats = await stat(absolutePath);
    if (stats.isDirectory()) {
      return c.json({ success: false, error: 'Cannot read directory' }, 400);
    }

    // 限制文件大小 (10MB)
    const maxSize = 10 * 1024 * 1024;
    if (stats.size > maxSize) {
      return c.json({ success: false, error: 'File too large (max 10MB)' }, 400);
    }

    const name = basename(absolutePath);
    const isText = isTextFile(name);

    if (isText) {
      const content = await readFile(absolutePath, 'utf-8');
      return c.json({
        success: true,
        data: {
          path: requestedPath,
          name,
          type: getFileType(name),
          size: stats.size,
          modified: stats.mtime.toISOString(),
          content,
          encoding: 'utf-8',
        },
      });
    } else {
      // 二进制文件返回 base64
      const buffer = await readFile(absolutePath);
      return c.json({
        success: true,
        data: {
          path: requestedPath,
          name,
          type: getFileType(name),
          size: stats.size,
          modified: stats.mtime.toISOString(),
          content: buffer.toString('base64'),
          encoding: 'base64',
        },
      });
    }
  } catch (error) {
    const message = error instanceof Error ? error.message : 'Unknown error';
    return c.json({ success: false, error: message }, 500);
  }
});

// ============================================================================
// GET /api/files/stat?path= - 获取文件/目录信息
// ============================================================================
filesRouter.get('/stat', async (c) => {
  const requestedPath = c.req.query('path');
  if (!requestedPath) {
    return c.json({ success: false, error: 'Path is required' }, 400);
  }

  const absolutePath = safePath(requestedPath);
  if (!absolutePath) {
    return c.json({ success: false, error: 'Access denied: path outside working directory' }, 403);
  }

  try {
    const stats = await stat(absolutePath);
    const name = basename(absolutePath);

    return c.json({
      success: true,
      data: {
        path: requestedPath,
        name,
        type: stats.isDirectory() ? 'directory' : 'file',
        size: stats.size,
        modified: stats.mtime.toISOString(),
        created: stats.birthtime.toISOString(),
        extension: stats.isFile() ? extname(name).slice(1) : undefined,
        fileType: stats.isFile() ? getFileType(name) : undefined,
        isText: stats.isFile() ? isTextFile(name) : undefined,
      },
    });
  } catch (error) {
    const message = error instanceof Error ? error.message : 'Unknown error';
    return c.json({ success: false, error: message }, 500);
  }
});

// ============================================================================
// GET /api/files/tree?path=&depth= - 获取目录树
// ============================================================================
filesRouter.get('/tree', async (c) => {
  const requestedPath = c.req.query('path') || '.';
  const maxDepth = parseInt(c.req.query('depth') || '3', 10);
  const showHidden = c.req.query('hidden') === 'true';

  const absolutePath = safePath(requestedPath);
  if (!absolutePath) {
    return c.json({ success: false, error: 'Access denied: path outside working directory' }, 403);
  }

  interface TreeNode {
    name: string;
    path: string;
    type: 'file' | 'directory';
    children?: TreeNode[];
  }

  async function buildTree(dir: string, depth: number): Promise<TreeNode[]> {
    if (depth <= 0) return [];

    try {
      const entries = await readdir(dir, { withFileTypes: true });
      const nodes: TreeNode[] = [];

      for (const entry of entries) {
        if (!showHidden && entry.name.startsWith('.')) continue;
        if (entry.name === 'node_modules' || entry.name === '.git') continue;

        const entryPath = join(dir, entry.name);
        const relativePath = entryPath.replace(workingDirectory, '').replace(/^\//, '');

        const node: TreeNode = {
          name: entry.name,
          path: relativePath,
          type: entry.isDirectory() ? 'directory' : 'file',
        };

        if (entry.isDirectory()) {
          node.children = await buildTree(entryPath, depth - 1);
        }

        nodes.push(node);
      }

      // 排序
      nodes.sort((a, b) => {
        if (a.type !== b.type) return a.type === 'directory' ? -1 : 1;
        return a.name.localeCompare(b.name);
      });

      return nodes;
    } catch {
      return [];
    }
  }

  try {
    const tree = await buildTree(absolutePath, maxDepth);
    return c.json({
      success: true,
      data: {
        path: requestedPath,
        tree,
      },
    });
  } catch (error) {
    const message = error instanceof Error ? error.message : 'Unknown error';
    return c.json({ success: false, error: message }, 500);
  }
});

// ============================================================================
// GET /api/files/search?query=&limit=&type= - 模糊搜索文件
// ============================================================================
filesRouter.get('/search', async (c) => {
  const query = c.req.query('query') || '';
  const limit = parseInt(c.req.query('limit') || '10', 10);
  const type = (c.req.query('type') || 'file') as 'file' | 'directory' | 'all';

  try {
    const results = await coreSearchFiles({
      query,
      limit,
      type,
      cwd: workingDirectory,
    });

    return c.json({
      success: true,
      data: {
        files: results,
        total: results.length,
      },
    });
  } catch (error) {
    const message = error instanceof Error ? error.message : 'Unknown error';
    return c.json({ success: false, error: message }, 500);
  }
});

export { filesRouter };
