/**
 * Basic Usage Examples
 * 
 * This file demonstrates the most common use cases for the HANA Query API client.
 */

import { 
  HanaQueryClient, 
  createClient,
  ENVIRONMENT_CONFIGS,
  type SalesParams,
  type Plan
} from '../index.ts';

// ============================================================================
// Example 1: Basic Client Usage
// ============================================================================

async function basicClientUsage() {
  console.log('=== Basic Client Usage ===');
  
  // Create a client with explicit configuration
  const client = new HanaQueryClient({ baseUrl: 'http://localhost:3001' });
  
  try {
    // Test the connection first
    console.log('Testing API connection...');
    const isOnline = await client.testConnection();
    
    if (!isOnline) {
      console.error('❌ API is not reachable');
      return;
    }
    
    console.log('✅ API is online');
    
    // Get health status
    const health = await client.getHealth();
    console.log(`Server status: ${health.data.status}`);
    console.log(`Server uptime: ${Math.round(health.data.uptime / 60)} minutes`);
    
    // Get API documentation
    const docs = await client.getDocs();
    console.log(`API: ${docs.data.name} v${docs.data.version}`);
    console.log(`Available endpoints: ${Object.keys(docs.data.endpoints).length}`);
    
  } catch (error: unknown) {
    if (error instanceof Error) {
      console.error('Error in basic usage:', error.message);
    } else {
      console.error('Unknown error in basic usage:', error);
    }
  }
}

// ============================================================================
// Example 2: Working with Items
// ============================================================================

async function workingWithItems() {
  console.log('\\n=== Working with Items ===');
  
  const client = new HanaQueryClient({ baseUrl: 'http://localhost:3001' });
  
  try {
    // Get all items (using default date range)
    console.log('Fetching all items...');
    const allItems = await client.getItems();
    console.log(`Total items: ${allItems.metadata.count}`);
    
    // Get sales for a specific date range
    const params: SalesParams = {
      from: '2025-01-01',
      to: '2025-06-30'
    };
    
    console.log('Fetching sales for date range...');
    const salesData = await client.getSales(params);
    console.log(`Sales found: ${salesData.metadata.count}`);
    console.log(`Date range: ${salesData.metadata.from} to ${salesData.metadata.to}`);
    
    // Analyze some items from allItems
    const items = allItems.data.items.slice(0, 5); // First 5 items
    console.log('\\nSample items:');
    
    items.forEach((item: any) => {
      const stockStatus = item.onhand >= item.min ? '✅' : '⚠️';
      console.log(`${stockStatus} ${item.itemcode}: ${item.onhand}/${item.min} - ${item.description}`);
    });
    
    // Get item hierarchies
    console.log('\\nFetching item hierarchies...');
    const hierarchies = await client.getItemHierarchies();
    console.log(`Total hierarchy relationships: ${hierarchies.metadata.count}`);
    
    // Show some hierarchy examples
    const sampleHierarchies = hierarchies.data.hierarchies.slice(0, 3);
    console.log('\\nSample hierarchies:');
    sampleHierarchies.forEach(h => {
      const parentInfo = h.parent ? `Parent: ${h.parent}` : 'Root item';
      console.log(`  ${h.node} (${parentInfo}) - Qty: ${h.quantity}, Rank: ${h.rank}`);
    });
    
  } catch (error: unknown) {
    if (error instanceof Error) {
      console.error('Error working with items:', error.message);
    } else {
      console.error('Unknown error working with items:', error);
    }
  }
}

// ============================================================================
// Example 3: Production Planning Workflow
// ============================================================================

async function productionPlanningWorkflow() {
  console.log('\\n=== Production Planning Workflow ===');
  
  const client = new HanaQueryClient({ baseUrl: 'http://localhost:3001' });
  
  try {
    // Get all production plans
    console.log('Fetching production plans...');
    const plansResponse = await client.getPlans();
    const plans = plansResponse.data.plans;
    
    console.log(`Found ${plans.length} production plans`);
    
    // Analyze plan statuses
    const statusCounts = plans.reduce((acc, plan) => {
      acc[plan.plan_status] = (acc[plan.plan_status] || 0) + 1;
      return acc;
    }, {} as Record<string, number>);
    
    console.log('\\nPlan status distribution:');
    Object.entries(statusCounts).forEach(([status, count]) => {
      console.log(`  ${status}: ${count} plans`);
    });
    
    // Get detailed information for the first few plans
    const samplePlans = plans.slice(0, 3);
    
    for (const plan of samplePlans) {
      console.log(`\\n--- Plan ${plan.plan_id} Details ---`);
      console.log(`Status: ${plan.plan_status}`);
      console.log(`Created by: ${plan.plan_username} on ${new Date(plan.plan_createdate).toLocaleDateString()}`);
      console.log(`Products: ${plan.products_total} total, ${plan.products_released} released, ${plan.products_closed} closed`);
      
      try {
        // Get plan products
        const products = await client.getPlanProducts(plan.plan_id);
        console.log(`Products in plan: ${products.metadata.count}`);
        
        if (products.data.products.length > 0) {
          console.log('Sample products:');
          products.data.products.slice(0, 3).forEach(product => {
            console.log(`  - ${product.itemcode}: ${product.quantity} units`);
          });
        }
        
        // Try to get work orders (may not exist for all plans)
        try {
          const workOrders = await client.getPlanWorkOrders(plan.plan_id);
          console.log(`Work orders: ${workOrders.metadata.count}`);
          
          if (workOrders.data.workOrders.length > 0) {
            const totalPlanned = workOrders.data.workOrders.reduce((sum, wo) => sum + wo.order_plannedqty, 0);
            const totalCompleted = workOrders.data.workOrders.reduce((sum, wo) => sum + wo.order_completedqty, 0);
            const completionRate = totalPlanned > 0 ? (totalCompleted / totalPlanned * 100) : 0;
            
            console.log(`Completion rate: ${completionRate.toFixed(1)}%`);
          }
        } catch (error: unknown) {
          console.log('No work orders found for this plan');
        }
        
      } catch (error: unknown) {
        if (error instanceof Error) {
          console.error(`Error getting details for plan ${plan.plan_id}:`, error.message);
        } else {
          console.error(`Unknown error getting details for plan ${plan.plan_id}:`, error);
        }
      }
    }
    
  } catch (error: unknown) {
    if (error instanceof Error) {
      console.error('Error in production planning workflow:', error.message);
    } else {
      console.error('Unknown error in production planning workflow:', error);
    }
  }
}

// ============================================================================
// Example 4: Using Environment-Specific Clients
// ============================================================================

async function environmentSpecificClients() {
  console.log('\\n=== Environment-Specific Clients ===');
  
  // Development client (with debug logging)
  const devClient = createClient({
    ...ENVIRONMENT_CONFIGS.development,
    enableLogging: true,
    logLevel: 'debug'
  });
  
  // Production client (minimal logging)
  const prodClient = createClient({
    ...ENVIRONMENT_CONFIGS.production,
    enableLogging: true,
    logLevel: 'error'
  });
  
  // Custom client
  const customClient = createClient({
    baseUrl: 'http://localhost:3001',
    timeout: 60000,
    retries: 5,
    enableLogging: true,
    logLevel: 'info'
  });
  
  console.log('Created environment-specific clients:');
  console.log(`- Development client: ${ENVIRONMENT_CONFIGS.development.baseUrl}`);
  console.log(`- Production client: ${ENVIRONMENT_CONFIGS.production.baseUrl}`);
  console.log(`- Custom client: http://localhost:3001`);
  
  try {
    // Test with development client
    const health = await devClient.getHealth();
    console.log(`Development API status: ${health.data.status}`);
  } catch (error: unknown) {
    if (error instanceof Error) {
      console.log('Development API not available:', error.message);
    } else {
      console.log('Development API not available:', error);
    }
  }
}

// ============================================================================
// Example 5: Using Utility Functions
// ============================================================================

async function usingUtilityFunctions() {
  console.log('\\n=== Using Utility Functions ===');
  
  const client = createClient({ baseUrl: 'http://localhost:3001' });
  
  try {
    // Test connection using utility
    const isOnline = await client.testConnection();
    console.log(`API connection test: ${isOnline ? '✅ Online' : '❌ Offline'}`);
    
    if (!isOnline) {
      return;
    }
    
    // Get all plan IDs
    const plansResponse = await client.getPlans();
    const planIds = plansResponse.data.plans.map((plan: Plan) => plan.plan_id);
    console.log(`Available plan IDs: ${planIds.join(', ')}`);
    
    // Get complete plan data (if plans exist)
    if (planIds.length > 0) {
      const firstPlanId = planIds[0];
      console.log(`\\nGetting complete data for plan ${firstPlanId}...`);
      
      // Manual implementation of getCompletePlanData utility
      const [plan, products, workOrders] = await Promise.allSettled([
        client.getPlan(firstPlanId),
        client.getPlanProducts(firstPlanId),
        client.getPlanWorkOrders(firstPlanId)
      ]);
      
      const completePlan = {
        plan: plan.status === 'fulfilled' ? plan.value.data.plan : null,
        products: products.status === 'fulfilled' ? products.value.data.products : [],
        workOrders: workOrders.status === 'fulfilled' ? workOrders.value.data.workOrders : [],
        errors: {
          plan: plan.status === 'rejected' ? plan.reason : null,
          products: products.status === 'rejected' ? products.reason : null,
          workOrders: workOrders.status === 'rejected' ? workOrders.reason : null
        }
      };
      
      console.log('Complete plan data:');
      console.log(`- Plan: ${completePlan.plan ? '✅ Available' : '❌ Not found'}`);
      console.log(`- Products: ${completePlan.products.length} items`);
      console.log(`- Work orders: ${completePlan.workOrders.length} orders`);
      
      if (completePlan.errors.plan) {
        console.log(`- Plan error: ${(completePlan.errors.plan as Error).message}`);
      }
      if (completePlan.errors.products) {
        console.log(`- Products error: ${(completePlan.errors.products as Error).message}`);
      }
      if (completePlan.errors.workOrders) {
        console.log(`- Work orders error: ${(completePlan.errors.workOrders as Error).message}`);
      }
    }
    
    // Search for items containing "pump" in the name
    console.log('\\nSearching for items containing "pump"...');
    const itemsResponse = await client.getItems();
    const searchTerm = 'pump'.toLowerCase();
    const pumpItems = itemsResponse.data.items.filter((item: any) => 
      item.itemcode.toLowerCase().includes(searchTerm) ||
      item.description.toLowerCase().includes(searchTerm) ||
      item.itemgroup.toLowerCase().includes(searchTerm)
    );
    console.log(`Found ${pumpItems.length} items containing "pump"`);
    
    pumpItems.slice(0, 3).forEach((item: any) => {
      console.log(`  - ${item.itemcode}: ${item.description}`);
    });
    
    // Get low stock items
    console.log('\\nChecking for low stock items...');
    const lowStockItems = itemsResponse.data.items.filter((item: any) => item.onhand < item.min);
    console.log(`Found ${lowStockItems.length} items with low stock`);
    
    lowStockItems.slice(0, 5).forEach((item: any) => {
      console.log(`  ⚠️  ${item.itemcode}: ${item.onhand}/${item.min} (${item.description})`);
    });
    
  } catch (error: unknown) {
    if (error instanceof Error) {
      console.error('Error using utility functions:', error.message);
    } else {
      console.error('Unknown error using utility functions:', error);
    }
  }
}

// ============================================================================
// Example 6: Static Endpoint Functions
// ============================================================================

async function staticEndpointFunctions() {
  console.log('\\n=== Client Instance Functions ===');
  
  const client = createClient({ baseUrl: 'http://localhost:3001' });
  
  try {
    // Use client instance functions
    const health = await client.getHealth();
    console.log(`Health check: ${health.data.status}`);
    
    const plans = await client.getPlans();
    console.log(`Plans query: ${plans.metadata.count} plans`);
    
    const items = await client.getItems();
    console.log(`Items query: ${items.metadata.count} items`);
    
    // Get sales data with date range
    const sales = await client.getSales({
      from: '2025-01-01',
      to: '2025-03-31'
    });
    console.log(`Sales query: ${sales.metadata.count} sales`);
    
    // Get user information
    try {
      const user = await client.getUser('USER001');
      console.log(`User lookup: User ID ${user.data.userId} for username ${user.metadata.username}`);
    } catch (error: unknown) {
      if (error instanceof Error) {
        console.log('User lookup failed (user may not exist):', error.message);
      } else {
        console.log('User lookup failed (user may not exist):', error);
      }
    }
    
  } catch (error: unknown) {
    if (error instanceof Error) {
      console.error('Error using client functions:', error.message);
    } else {
      console.error('Unknown error using client functions:', error);
    }
  }
}

// ============================================================================
// Main Execution
// ============================================================================

async function runAllExamples() {
  console.log('🚀 HANA Query API Client - Basic Usage Examples');
  console.log('='.repeat(60));
  
  try {
    await basicClientUsage();
    await workingWithItems();
    await productionPlanningWorkflow();
    await environmentSpecificClients();
    await usingUtilityFunctions();
    await staticEndpointFunctions();
    
    console.log('\\n✅ All examples completed successfully!');
    
  } catch (error: unknown) {
    if (error instanceof Error) {
      console.error('\\n❌ Example execution failed:', error);
    } else {
      console.error('\\n❌ Example execution failed:', error);
    }
  }
}

// Run examples if this file is executed directly
if (import.meta.url === `file://${process.argv[1]}`) {
  runAllExamples().catch(console.error);
}

export {
  basicClientUsage,
  workingWithItems,
  productionPlanningWorkflow,
  environmentSpecificClients,
  usingUtilityFunctions,
  staticEndpointFunctions,
  runAllExamples
};