#!/usr/bin/env node

/**
 * BODS CLI Tool
 * 
 * Simple command-line interface for testing BODS API functionality
 * 
 * Usage:
 *   bun run cli.ts --help
 *   bun run cli.ts timetables --noc SCMN
 *   bun run cli.ts fares --area manchester
 *   bun run cli.ts vehicles --operator SCMN
 *   bun run cli.ts disruptions
 */

import { BODSClient, UK_CITIES } from './index.js';

const API_KEY = process.env.BODS_API_KEY;

if (!API_KEY) {
  console.error('❌ Please set BODS_API_KEY environment variable');
  console.log('Example: BODS_API_KEY=your-api-key bun run cli.ts --help');
  process.exit(1);
}

const client = new BODSClient({ apiKey: API_KEY });

function showHelp() {
  console.log(`
🚌 BODS CLI Tool

Usage: bun run cli.ts <command> [options]

Commands:
  timetables     Search timetables
  fares          Search fares
  vehicles       Get vehicle locations
  disruptions    Get service disruptions
  test           Test API connectivity

Options:
  --noc <codes>     National Operator Codes (comma-separated)
  --area <city>     Predefined city area (manchester, london, etc.)
  --bbox <coords>   Custom bounding box (minLng,minLat,maxLng,maxLat)
  --line <ref>      Line reference
  --limit <num>     Limit results (default: 10)
  --help           Show this help

Examples:
  bun run cli.ts timetables --noc SCMN --limit 5
  bun run cli.ts fares --area manchester
  bun run cli.ts vehicles --noc SCMN --area liverpool
  bun run cli.ts disruptions
  `);
}

async function handleTimetables(args: Record<string, any>) {
  console.log('🔍 Searching timetables...\n');
  
  const params: any = {
    limit: parseInt(args.limit) || 10
  };
  
  if (args.noc) {
    params.noc = args.noc.split(',');
  }
  
  try {
    const result = await client.timetables.search(params);
    console.log(`Found ${result.count} timetables (showing ${result.results.length}):\n`);
    
    result.results.forEach((timetable: any, i: number) => {
      console.log(`${i + 1}. ${timetable.operatorName}`);
      console.log(`   Name: ${timetable.name}`);
      console.log(`   Lines: ${timetable.lines.join(', ')}`);
      console.log(`   Quality: ${timetable.dqRag} (${timetable.dqScore})`);
      console.log(`   Status: ${timetable.status}`);
      console.log('');
    });
  } catch (error) {
    console.error('❌ Error:', error);
  }
}

async function handleFares(args: Record<string, any>) {
  console.log('🔍 Searching fares...\n');
  
  const params: any = {
    limit: parseInt(args.limit) || 10
  };
  
  if (args.noc) {
    params.noc = args.noc.split(',');
  }
  
  if (args.area && args.area.toUpperCase() in UK_CITIES) {
    params.boundingBox = UK_CITIES[args.area.toUpperCase() as keyof typeof UK_CITIES];
  } else if (args.bbox) {
    params.boundingBox = args.bbox.split(',').map(Number);
  }
  
  try {
    const result = await client.fares.search(params);
    console.log(`Found ${result.count} fare datasets (showing ${result.results.length}):\n`);
    
    result.results.forEach((fare: any, i: number) => {
      console.log(`${i + 1}. ${fare.operatorName}`);
      console.log(`   Name: ${fare.name}`);
      console.log(`   Fare zones: ${fare.numOfFareZones}`);
      console.log(`   Products: ${fare.numOfFareProducts}`);
      console.log(`   Status: ${fare.status}`);
      console.log('');
    });
  } catch (error) {
    console.error('❌ Error:', error);
  }
}

async function handleVehicles(args: Record<string, any>) {
  console.log('🔍 Getting vehicle locations...\n');
  
  const params: any = {};
  
  if (args.noc) {
    params.operatorRef = args.noc.split(',');
  }
  
  if (args.line) {
    params.lineRef = args.line;
  }
  
  if (args.area && args.area.toUpperCase() in UK_CITIES) {
    params.boundingBox = UK_CITIES[args.area.toUpperCase() as keyof typeof UK_CITIES];
  } else if (args.bbox) {
    params.boundingBox = args.bbox.split(',').map(Number);
  }
  
  try {
    const result = await client.avl.getSIRIVM(params);
    console.log(`SIRI-VM Data received: ${result.xmlData.length} characters`);
    console.log(`First 500 characters:\n${result.xmlData.substring(0, 500)}...`);
  } catch (error) {
    console.error('❌ Error:', error);
  }
}

async function handleDisruptions() {
  console.log('🔍 Getting service disruptions...\n');
  
  try {
    const parsed = await client.disruptions.getCurrentParsed();
    console.log(`Found ${parsed.length} disruptions:\n`);
    
    parsed.forEach((disruption: any, i: number) => {
      console.log(`${i + 1}. ${disruption.planned ? '[PLANNED]' : '[UNPLANNED]'} ${disruption.participantRef}`);
      console.log(`   Summary: ${disruption.summary}`);
      console.log(`   Severity: ${disruption.severity}`);
      if (disruption.startTime) {
        console.log(`   Start: ${new Date(disruption.startTime).toLocaleString()}`);
      }
      console.log('');
    });
  } catch (error) {
    console.error('❌ Error:', error);
  }
}

async function handleTest() {
  console.log('🔍 Testing API connectivity...\n');
  
  try {
    const isConnected = await client.testConnection();
    console.log(`API Status: ${isConnected ? '✅ Connected' : '❌ Failed'}`);
    
    if (isConnected) {
      const config = client.getConfig();
      console.log(`Base URL: ${config.baseUrl}`);
      console.log(`Timeout: ${config.timeout}ms`);
    }
  } catch (error) {
    console.error('❌ Error:', error);
  }
}

function parseArgs(): { command: string; args: Record<string, any> } {
  const argv = process.argv.slice(2);
  const command = argv[0] || 'help';
  const args: Record<string, any> = {};
  
  for (let i = 1; i < argv.length; i += 2) {
    const arg = argv[i];
    if (arg?.startsWith('--')) {
      const key = arg.substring(2);
      const value = argv[i + 1];
      args[key] = value;
    }
  }
  
  return { command, args };
}

async function main() {
  const { command, args } = parseArgs();
  
  if (command === 'help' || args.help) {
    showHelp();
    return;
  }
  
  console.log('🚌 BODS CLI Tool\n');
  
  switch (command) {
    case 'timetables':
      await handleTimetables(args);
      break;
    case 'fares':
      await handleFares(args);
      break;
    case 'vehicles':
      await handleVehicles(args);
      break;
    case 'disruptions':
      await handleDisruptions();
      break;
    case 'test':
      await handleTest();
      break;
    default:
      console.error(`❌ Unknown command: ${command}`);
      showHelp();
      process.exit(1);
  }
}

if (import.meta.main) {
  main().catch(console.error);
}
