// CLI Command System for AeThex Studio

export interface CLICommand {
  name: string;
  description: string;
  usage: string;
  aliases?: string[];
  execute: (args: string[], context: CLIContext) => Promise<CLIResult>;
}

export interface CLIContext {
  currentCode: string;
  currentFile?: string;
  files: any[];
  setCode?: (code: string) => void;
  addLog?: (message: string, type?: 'log' | 'warn' | 'error' | 'info') => void;
}

export interface CLIResult {
  success: boolean;
  output: string;
  type?: 'log' | 'warn' | 'error' | 'info';
}

// Built-in CLI commands
export const commands: Record<string, CLICommand> = {
  help: {
    name: 'help',
    description: 'Display available commands',
    usage: 'help [command]',
    execute: async (args) => {
      if (args.length > 0) {
        const cmd = commands[args[0]] || Object.values(commands).find(c => c.aliases?.includes(args[0]));
        if (cmd) {
          return {
            success: true,
            output: `${cmd.name} - ${cmd.description}\nUsage: ${cmd.usage}${cmd.aliases ? `\nAliases: ${cmd.aliases.join(', ')}` : ''}`,
            type: 'info',
          };
        }
        return {
          success: false,
          output: `Command not found: ${args[0]}`,
          type: 'error',
        };
      }

      const commandList = Object.values(commands)
        .map(cmd => `  ${cmd.name.padEnd(15)} - ${cmd.description}`)
        .join('\n');

      return {
        success: true,
        output: `Available Commands:\n${commandList}\n\nType 'help <command>' for more info`,
        type: 'info',
      };
    },
  },

  clear: {
    name: 'clear',
    description: 'Clear the terminal',
    usage: 'clear',
    aliases: ['cls'],
    execute: async () => {
      return {
        success: true,
        output: '__CLEAR__',
        type: 'info',
      };
    },
  },

  run: {
    name: 'run',
    description: 'Execute current Lua script',
    usage: 'run',
    aliases: ['execute', 'exec'],
    execute: async (args, context) => {
      if (!context.currentCode || context.currentCode.trim() === '') {
        return {
          success: false,
          output: 'No code to execute',
          type: 'error',
        };
      }

      try {
        // Simulate script execution
        return {
          success: true,
          output: `Executing script...\n${context.currentFile || 'Untitled'}\n\nScript executed successfully (simulated)`,
          type: 'info',
        };
      } catch (error) {
        return {
          success: false,
          output: `Execution failed: ${error}`,
          type: 'error',
        };
      }
    },
  },

  check: {
    name: 'check',
    description: 'Check current script for syntax errors',
    usage: 'check',
    aliases: ['lint', 'validate'],
    execute: async (args, context) => {
      if (!context.currentCode || context.currentCode.trim() === '') {
        return {
          success: false,
          output: 'No code to check',
          type: 'warn',
        };
      }

      // Simple Lua syntax checks
      const issues: string[] = [];
      const lines = context.currentCode.split('\n');

      lines.forEach((line, i) => {
        // Check for common syntax issues
        if (line.includes('end)') && !line.includes('function')) {
          issues.push(`Line ${i + 1}: Possible syntax error - 'end)' found`);
        }
        if ((line.match(/\(/g) || []).length !== (line.match(/\)/g) || []).length) {
          issues.push(`Line ${i + 1}: Unbalanced parentheses`);
        }
      });

      if (issues.length === 0) {
        return {
          success: true,
          output: `✓ No syntax errors found (${lines.length} lines checked)`,
          type: 'info',
        };
      }

      return {
        success: false,
        output: `Found ${issues.length} potential issue(s):\n${issues.join('\n')}`,
        type: 'warn',
      };
    },
  },

  count: {
    name: 'count',
    description: 'Count lines, words, or characters in current script',
    usage: 'count [lines|words|chars]',
    execute: async (args, context) => {
      if (!context.currentCode) {
        return {
          success: false,
          output: 'No code to count',
          type: 'error',
        };
      }

      const lines = context.currentCode.split('\n').length;
      const words = context.currentCode.split(/\s+/).filter(w => w.length > 0).length;
      const chars = context.currentCode.length;

      const type = args[0]?.toLowerCase();

      switch (type) {
        case 'lines':
          return { success: true, output: `Lines: ${lines}`, type: 'info' };
        case 'words':
          return { success: true, output: `Words: ${words}`, type: 'info' };
        case 'chars':
        case 'characters':
          return { success: true, output: `Characters: ${chars}`, type: 'info' };
        default:
          return {
            success: true,
            output: `Lines: ${lines} | Words: ${words} | Characters: ${chars}`,
            type: 'info',
          };
      }
    },
  },

  api: {
    name: 'api',
    description: 'Search Roblox API documentation',
    usage: 'api <service|class>',
    execute: async (args) => {
      if (args.length === 0) {
        return {
          success: false,
          output: 'Usage: api <service|class>\nExample: api Players, api Workspace',
          type: 'warn',
        };
      }

      const query = args.join(' ');
      const commonAPIs = {
        'Players': 'Service for managing player instances',
        'Workspace': 'Container for 3D objects in the game',
        'ReplicatedStorage': 'Storage for replicated objects',
        'ServerStorage': 'Server-only storage',
        'Instance': 'Base class for all Roblox objects',
        'Part': 'Basic building block',
        'Script': 'Server-side Lua code',
        'LocalScript': 'Client-side Lua code',
      };

      const match = Object.keys(commonAPIs).find(
        key => key.toLowerCase() === query.toLowerCase()
      );

      if (match) {
        return {
          success: true,
          output: `${match}: ${commonAPIs[match as keyof typeof commonAPIs]}\n\nDocs: https://create.roblox.com/docs/reference/engine/classes/${match}`,
          type: 'info',
        };
      }

      return {
        success: true,
        output: `Search: https://create.roblox.com/docs/reference/engine/classes/${query}`,
        type: 'info',
      };
    },
  },

  template: {
    name: 'template',
    description: 'List or load code templates',
    usage: 'template [list|<name>]',
    execute: async (args, context) => {
      if (args.length === 0 || args[0] === 'list') {
        return {
          success: true,
          output: `Available templates:
  - basic       : Basic Roblox script structure
  - playeradded : PlayerAdded event handler
  - datastore   : DataStore usage example
  - remote      : RemoteEvent/RemoteFunction
  - gui         : GUI scripting basics

Usage: template <name>`,
          type: 'info',
        };
      }

      return {
        success: true,
        output: `Template '${args[0]}' - Use Templates panel (Ctrl+T) to load templates into editor`,
        type: 'info',
      };
    },
  },

  export: {
    name: 'export',
    description: 'Export current script to file',
    usage: 'export [filename]',
    execute: async (args, context) => {
      const filename = args[0] || 'script.lua';
      const code = context.currentCode || '';

      try {
        const blob = new Blob([code], { type: 'text/plain' });
        const url = URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url;
        a.download = filename.endsWith('.lua') ? filename : `${filename}.lua`;
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
        URL.revokeObjectURL(url);

        return {
          success: true,
          output: `Exported to ${a.download}`,
          type: 'info',
        };
      } catch (error) {
        return {
          success: false,
          output: `Export failed: ${error}`,
          type: 'error',
        };
      }
    },
  },

  echo: {
    name: 'echo',
    description: 'Print text to terminal',
    usage: 'echo <text>',
    execute: async (args) => {
      return {
        success: true,
        output: args.join(' '),
        type: 'log',
      };
    },
  },

  info: {
    name: 'info',
    description: 'Display system information',
    usage: 'info',
    execute: async (args, context) => {
      return {
        success: true,
        output: `AeThex Studio v1.0.0
Environment: Browser-based IDE
Platform: Roblox Lua
Files: ${context.files?.length || 0}
Current File: ${context.currentFile || 'Untitled'}
Code Size: ${context.currentCode?.length || 0} characters`,
        type: 'info',
      };
    },
  },
};

export function executeCommand(
  input: string,
  context: CLIContext
): Promise<CLIResult> {
  const parts = input.trim().split(/\s+/);
  const commandName = parts[0].toLowerCase();
  const args = parts.slice(1);

  // Find command by name or alias
  const command = commands[commandName] ||
    Object.values(commands).find(cmd =>
      cmd.aliases?.includes(commandName)
    );

  if (!command) {
    return Promise.resolve({
      success: false,
      output: `Command not found: ${commandName}\nType 'help' for available commands`,
      type: 'error',
    });
  }

  return command.execute(args, context);
}
