/**
 * File System Agent
 * Handles: file-read, file-write, file-tree, browse-dirs, validate-path, create-folder
 */
import { promises as fsPromises } from 'fs';
import os from 'os';
import path from 'path';
import {
  buildFileTree,
  resolveTildePath,
  isBlockedPath,
  BLOCKED_READ_PATTERNS,
  BLOCKED_WRITE_PATTERNS,
} from './utils.js';

export default {
  name: 'files',
  actions: {
    'file-read': async (params) => {
      let { filePath, encoding } = params;
      if (!filePath || typeof filePath !== 'string') throw new Error('Invalid file path');

      filePath = resolveTildePath(filePath);
      const normalizedPath = path.resolve(filePath);
      if (isBlockedPath(normalizedPath, BLOCKED_READ_PATTERNS)) throw new Error('Access denied');

      const content = await fsPromises.readFile(normalizedPath, encoding === 'base64' ? null : 'utf8');
      const result = encoding === 'base64' ? content.toString('base64') : content;
      return { content: result };
    },

    'file-write': async (params) => {
      let { filePath, content } = params;
      if (!filePath || typeof filePath !== 'string') throw new Error('Invalid file path');

      filePath = resolveTildePath(filePath);
      const normalizedPath = path.resolve(filePath);
      if (isBlockedPath(normalizedPath, BLOCKED_WRITE_PATTERNS)) throw new Error('Access denied');

      const parentDir = path.dirname(normalizedPath);
      await fsPromises.mkdir(parentDir, { recursive: true }).catch(() => {});
      await fsPromises.writeFile(normalizedPath, content, 'utf8');
      return { success: true };
    },

    'file-tree': async (params) => {
      const { dirPath, depth, maxDepth } = params;
      const treeDepth = depth || maxDepth || 3;
      const resolvedDir = dirPath ? path.resolve(dirPath) : process.cwd();
      const tree = await buildFileTree(resolvedDir, treeDepth, 0, {
        maxEntries: 200,
        includeStats: true,
        skipDotfilesAtRoot: true,
      });
      return { files: tree };
    },

    'browse-dirs': async (params) => {
      const { dirPath: browsePath } = params;
      let targetDir = resolveTildePath(browsePath);
      targetDir = path.resolve(targetDir);

      let drives = [];
      // On Windows, detect available drives
      if (process.platform === 'win32') {
        try {
          const { execSync } = await import('child_process');
          const wmicOut = execSync('wmic logicaldisk get name', { encoding: 'utf8', timeout: 5000 });
          drives = wmicOut.split('\n')
            .map(l => l.trim())
            .filter(l => /^[A-Z]:$/.test(l))
            .map(d => ({ name: d + '\\', path: d + '\\', type: 'drive' }));
        } catch { /* wmic not available */ }
      }

      const entries = await fsPromises.readdir(targetDir, { withFileTypes: true });
      const dirs = entries
        .filter(e => e.isDirectory() && !e.name.startsWith('.'))
        .map(e => ({ name: e.name, path: path.join(targetDir, e.name), type: 'directory' }))
        .sort((a, b) => a.name.localeCompare(b.name));

      return { path: targetDir, suggestions: dirs, drives, homedir: os.homedir() };
    },

    'validate-path': async (params) => {
      const { targetPath } = params;
      const checkPath = resolveTildePath(targetPath);
      const resolved = path.resolve(checkPath);

      try {
        const stats = await fsPromises.stat(resolved);
        return { exists: true, isDirectory: stats.isDirectory(), resolvedPath: resolved };
      } catch {
        return { exists: false, resolvedPath: resolved };
      }
    },

    'create-folder': async (params) => {
      const { folderPath } = params;
      const mkPath = path.resolve(resolveTildePath(folderPath));
      await fsPromises.mkdir(mkPath, { recursive: true });
      return { success: true, path: mkPath };
    },
  },
};
