/**
 * Example usage of the BODS JavaScript Client
 * 
 * This file demonstrates various ways to use the BODS API client
 * to access UK bus data including timetables, fares, real-time locations,
 * and service disruptions.
 */

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

/**
 * Initialize the BODS client with your API key
 * Get your API key from: https://data.bus-data.dft.gov.uk/account/
 */
const client = new BODSClient({
  apiKey: 'your-api-key-here', // Replace with your actual API key
  timeout: 30000 // Optional: 30 second timeout
});

/**
 * Example 1: Search for timetables
 */
async function searchTimetables() {
  try {
    // Find all published timetables for Stagecoach Manchester
    const timetables = await client.timetables.search({
      noc: ['SCMN'], // Stagecoach Manchester
      status: 'published',
      limit: 10
    });

    console.log(`Found ${timetables.count} timetables`);
    timetables.results.forEach(timetable => {
      console.log(`- ${timetable.operatorName}: ${timetable.name}`);
      console.log(`  Lines: ${timetable.lines.join(', ')}`);
      console.log(`  Quality: ${timetable.dqRag} (${timetable.dqScore})`);
    });

    // Get a specific timetable by ID
    if (timetables.results.length > 0) {
      const firstTimetable = await client.timetables.getById(timetables.results[0]!.id);
      console.log('Detailed timetable:', firstTimetable);
    }
  } catch (error) {
    console.error('Error fetching timetables:', error);
  }
}

/**
 * Example 2: Search for fares by geographic area
 */
async function searchFaresByArea() {
  try {
    // Get fares for the Manchester area
    const manchesterBox = UK_CITIES.MANCHESTER;
    const fares = await client.fares.getByArea(manchesterBox);

    console.log(`Found ${fares.count} fare datasets in Manchester area`);
    fares.results.forEach(fare => {
      console.log(`- ${fare.operatorName}: ${fare.name}`);
      console.log(`  Fare zones: ${fare.numOfFareZones}`);
      console.log(`  Products: ${fare.numOfFareProducts}`);
    });

    // Create custom bounding box for Liverpool city center (5km radius)
    const liverpoolBox = createBoundingBox(53.4084, -2.9916, 5);
    const liverpoolFares = await client.fares.getByArea(liverpoolBox);
    console.log(`Liverpool fares: ${liverpoolFares.count}`);
  } catch (error) {
    console.error('Error fetching fares:', error);
  }
}

/**
 * Example 3: Get real-time vehicle locations
 */
async function getVehicleLocations() {
  try {
    // Get real-time locations for specific operators in SIRI-VM format
    const vehicles = await client.avl.getSIRIVM({
      operatorRef: ['SCMN', 'SCGH'], // Stagecoach operators
      boundingBox: UK_CITIES.MANCHESTER
    });

    console.log('Vehicle locations (SIRI-VM XML):');
    console.log(vehicles.xmlData.substring(0, 500) + '...');

    // Get vehicles for a specific bus line
    const lineVehicles = await client.avl.getByLine('85A');
    console.log('Line 85A vehicles:', lineVehicles.xmlData.length > 0 ? 'Data received' : 'No data');

    // Get vehicles in GTFS-RT format (binary protobuf)
    const gtfsVehicles = await client.avl.getGTFSRT({
      boundingBox: createBoundingBox(53.4808, -2.2426, 10) // Manchester, 10km radius
    });
    console.log('GTFS-RT data size:', gtfsVehicles.protobufData.byteLength, 'bytes');
  } catch (error) {
    console.error('Error fetching vehicle locations:', error);
  }
}

/**
 * Example 4: Get service disruptions
 */
async function getDisruptions() {
  try {
    // Get all current disruptions
    const disruptions = await client.disruptions.getCurrent();
    console.log('Raw disruptions XML length:', disruptions.xmlData.length);

    // Parse disruptions to extract useful information
    const parsed = await client.disruptions.getCurrentParsed();
    console.log(`Found ${parsed.length} parsed disruptions`);

    parsed.forEach(disruption => {
      console.log(`\n${disruption.planned ? 'PLANNED' : 'UNPLANNED'} DISRUPTION:`);
      console.log(`Summary: ${disruption.summary}`);
      console.log(`Authority: ${disruption.participantRef}`);
      console.log(`Severity: ${disruption.severity}`);
      if (disruption.startTime) {
        console.log(`Start: ${new Date(disruption.startTime).toLocaleString()}`);
      }
      if (disruption.description) {
        console.log(`Description: ${disruption.description.substring(0, 100)}...`);
      }
    });

    // Filter for unplanned disruptions only
    const unplanned = client.disruptions.filterDisruptions(parsed, { planned: false });
    console.log(`\nUnplanned disruptions: ${unplanned.length}`);
  } catch (error) {
    console.error('Error fetching disruptions:', error);
  }
}

/**
 * Example 5: Advanced searches and filtering
 */
async function advancedExamples() {
  try {
    // Get high-quality, BODS-compliant timetables
    const qualityTimetables = await client.timetables.getHighQuality({
      bodsCompliance: true,
      adminArea: ['060'] // Cheshire East
    });
    console.log(`High-quality timetables in Cheshire East: ${qualityTimetables.count}`);

    // Get recently modified timetables (last 7 days)
    const lastWeek = new Date();
    lastWeek.setDate(lastWeek.getDate() - 7);
    const recentTimetables = await client.timetables.getRecentlyModified(lastWeek);
    console.log(`Recently modified timetables: ${recentTimetables.count}`);

    // Get published fares only
    const publishedFares = await client.fares.getPublished({
      noc: ['SCMN'],
      limit: 5
    });
    console.log(`Published Stagecoach Manchester fares: ${publishedFares.count}`);

    // Test API connectivity
    const isConnected = await client.testConnection();
    console.log(`API connection test: ${isConnected ? 'SUCCESS' : 'FAILED'}`);
  } catch (error) {
    console.error('Error in advanced examples:', error);
  }
}

/**
 * Example 6: Error handling and validation
 */
async function errorHandlingExample() {
  try {
    // This will fail if API key is invalid
    await client.timetables.search({ limit: 1 });
    console.log('API key is valid');
  } catch (error) {
    if (error instanceof Error) {
      console.error('API Error:', error.message);
      
      // Check if it's an HTTP error with specific status
      if ('status' in error) {
        const httpError = error as any;
        switch (httpError.status) {
          case 401:
            console.error('Unauthorized - check your API key');
            break;
          case 403:
            console.error('Forbidden - API key may not have required permissions');
            break;
          case 429:
            console.error('Rate limited - too many requests');
            break;
          default:
            console.error(`HTTP ${httpError.status}: ${httpError.message}`);
        }
      }
    }
  }
}

/**
 * Run all examples
 */
async function runAllExamples() {
  console.log('🚌 BODS JavaScript Client Examples\n');
  console.log('='.repeat(50));

  console.log('\n📅 Example 1: Timetables');
  await searchTimetables();

  console.log('\n🎟️ Example 2: Fares by Area');
  await searchFaresByArea();

  console.log('\n🚌 Example 3: Real-time Vehicle Locations');
  await getVehicleLocations();

  console.log('\n⚠️ Example 4: Service Disruptions');
  await getDisruptions();

  console.log('\n🔍 Example 5: Advanced Searches');
  await advancedExamples();

  console.log('\n❌ Example 6: Error Handling');
  await errorHandlingExample();

  console.log('\n✅ Examples completed!');
}

// Run examples if this file is executed directly
if (import.meta.main) {
  runAllExamples().catch(console.error);
}

export {
  searchTimetables,
  searchFaresByArea,
  getVehicleLocations,
  getDisruptions,
  advancedExamples,
  errorHandlingExample,
  runAllExamples
};
