import readline from 'readline';
import { AIAssistant } from './AIAssistant';
import dotenv from 'dotenv';
import path from 'path';
import { ExecutionOptions } from './types/execution';
import { Tool } from './types/tool';

dotenv.config({ path: path.resolve(__dirname, '../.env') });

const tools: Tool[] = [];

const executionOptions: ExecutionOptions & {
  maxHistoryLength?: number;
  initialWorkingDirectory?: string;
  providerName?: string;
  tools?: Tool[];
} = {
  maxRetries: 3,
  retryDelayMs: 1000,
  timeoutMs: 30000,
  statePersistenceDir: './state',
  maxHistoryLength: 5,
  initialWorkingDirectory: process.cwd(),
  providerName: process.env.AI_PROVIDER || 'openai',
  tools: tools
};

async function initializeAssistant(): Promise<AIAssistant> {
  const assistant = new AIAssistant(console as any, executionOptions);
  await assistant.initialize();
  return assistant;
}

async function processQuery(query: string): Promise<void> {
  const assistant = await initializeAssistant();

  try {
    const stream = await assistant.processRequestStreamWithDetails(query);
    let buffer = '';

    for await (const chunk of stream) {
      buffer += chunk;
      let parsedData;
      
      try {
        parsedData = JSON.parse(buffer);
        buffer = ''; // Reset buffer after successful parse
      } catch (e) {
        // If parsing fails, continue to next chunk
        continue;
      }

      if (parsedData.choices && parsedData.choices[0] && parsedData.choices[0].delta) {
        const delta = parsedData.choices[0].delta;
        
        if (delta.content) {
          process.stdout.write(delta.content);
        }
        
        if (delta.tool_calls) {
          for (const toolCall of delta.tool_calls) {
            process.stdout.write(`[Tool Execution: ${toolCall.function.name}]\n`);
            process.stdout.write(`Arguments: ${JSON.stringify(toolCall.function.arguments)}\n`);
          }
        }
      }
    }
  } catch (error) {
    process.stderr.write(`Error: ${error}\n`);
  }
}

async function startInteractiveMode(): Promise<void> {
  const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
  });

  rl.on('line', async (input) => {
    if (input.trim()) {
      await processQuery(input);
      rl.prompt();
    }
  });

  rl.on('close', () => {
    process.exit(0);
  });

  rl.prompt();
}

export async function main(): Promise<void> {
  const args = process.argv.slice(2);

  if (args.length > 0) {
    const query = args.join(' ');
    await processQuery(query);
  } else {
    await startInteractiveMode();
  }
}

if (require.main === module) {
  main().catch((error) => {
    process.stderr.write(`Unhandled error: ${error}\n`);
    process.exit(1);
  });
}