import axios from 'axios';

async function runFullSystemUseCases() {
  const baseURL = 'http://localhost:3001';
  console.log('===============================================================');
  console.log('   FULL END-TO-END SYSTEM & USE-CASE VERIFICATION RUNNER       ');
  console.log('===============================================================\n');

  let passedTests = 0;
  let totalTests = 0;

  function assert(condition: boolean, testName: string, detail?: any) {
    totalTests++;
    if (condition) {
      passedTests++;
      console.log(`  ✅ [PASS] ${testName}`);
    } else {
      console.error(`  ❌ [FAIL] ${testName}`, detail || '');
      throw new Error(`Assertion failed for test: ${testName}`);
    }
  }

  // -------------------------------------------------------------
  // USE CASE 1: Merchant Authentication & Account Lifecycle
  // -------------------------------------------------------------
  console.log('\n--- USE CASE 1: Merchant Authentication & Account Lifecycle ---');
  const uniqueStoreName = `Apex Electronics ${Date.now()}`;
  const merchantPhone = `+26377${Math.floor(100000 + Math.random() * 900000)}`;
  const merchantEmail = `merchant_${Date.now()}@hubtest.com`;
  const merchantPassword = 'SecurePassword123!';

  // 1.1 Register
  const regRes = await axios.post(`${baseURL}/api/auth/register`, {
    businessName: uniqueStoreName,
    email: merchantEmail,
    password: merchantPassword,
    phone: merchantPhone,
    selectedPlan: 'STARTER',
  });
  assert(regRes.status === 201 || regRes.status === 200, 'Merchant Registration returns 200/201');
  assert(!!regRes.data.accessToken, 'Registration returns JWT accessToken');
  assert(regRes.data.business.name === uniqueStoreName, 'Business name is registered correctly');
  assert(regRes.data.business.subscriptionStatus === 'TRIAL', 'New merchant receives TRIAL subscription status');

  const merchantToken = regRes.data.accessToken;
  const businessId = regRes.data.business.id;
  const authHeaders = { Authorization: `Bearer ${merchantToken}` };

  // 1.2 Login with email
  const loginRes = await axios.post(`${baseURL}/api/auth/login`, {
    email: merchantEmail,
    password: merchantPassword,
  });
  assert(loginRes.status === 200, 'Merchant Login with email returns 200 OK');
  assert(!!loginRes.data.accessToken, 'Login returns valid JWT accessToken');

  // 1.3 Update Merchant Profile
  const profileRes = await axios.put(`${baseURL}/api/auth/profile`, {
    name: uniqueStoreName,
    contactPhone: merchantPhone,
    walletAddress: '0x1234567890abcdef1234567890abcdef12345678',
    latitude: -17.8252,
    longitude: 31.0335,
  }, { headers: authHeaders });
  assert(profileRes.status === 200, 'Profile update returns 200 OK');
  assert(profileRes.data.business.name === uniqueStoreName, 'Profile name updated');
  assert(profileRes.data.business.latitude === -17.8252, 'Merchant store GPS coordinates saved');

  // -------------------------------------------------------------
  // USE CASE 2: Integrations & Connector Configuration
  // -------------------------------------------------------------
  console.log('\n--- USE CASE 2: Integrations & Connector Configuration ---');

  // 2.1 Connect WhatsApp WABA Credentials
  const waInteg = await axios.post(`${baseURL}/api/integrations/connect`, {
    integrationType: 'whatsapp',
    integrationName: 'Meta Cloud WhatsApp API',
    credentials: {
      phoneNumberId: `WABA_${Date.now()}`,
      accessToken: 'EAAG_TEST_TOKEN_SECRET',
      wabaId: 'WABA_ACCT_123',
    },
  }, { headers: authHeaders });
  assert(waInteg.status === 200 || waInteg.status === 201, 'WhatsApp Integration connected');
  assert(waInteg.data.status === 'ACTIVE', 'WhatsApp Integration status is ACTIVE');

  // 2.2 Connect Paynow & Pesepay Gateways
  const paynowInteg = await axios.post(`${baseURL}/api/integrations/connect`, {
    integrationType: 'paynow',
    integrationName: 'Paynow Gateway Sandbox',
    credentials: {
      isSandbox: true,
      paynowIntegrationId: '12345',
      paynowIntegrationKey: 'mock_paynow_key',
    },
  }, { headers: authHeaders });
  assert(paynowInteg.data.status === 'ACTIVE', 'Paynow Integration connected and active');

  // 2.3 List Integrations
  const listInteg = await axios.get(`${baseURL}/api/integrations`, { headers: authHeaders });
  assert(Array.isArray(listInteg.data) && listInteg.data.length >= 2, 'Integrations listed for merchant');

  // -------------------------------------------------------------
  // USE CASE 3: Product & Catalog Management
  // -------------------------------------------------------------
  console.log('\n--- USE CASE 3: Product & Catalog Management ---');

  // 3.1 Create Category
  const catRes = await axios.post(`${baseURL}/api/categories`, {
    name: 'Smartphones & Accessories',
  }, { headers: authHeaders });
  assert(catRes.status === 201 || catRes.status === 200, 'Product Category created');
  const categoryId = catRes.data.id;

  // 3.2 Create Products
  const prod1Res = await axios.post(`${baseURL}/api/products`, {
    name: 'Samsung Galaxy A54 5G',
    description: '128GB Storage, Awesome Graphite, Super AMOLED 120Hz display.',
    sku: 'SAM-A54-128',
    price: 349.99,
    currency: 'USD',
    stockQuantity: 25,
    stockStatus: 'instock',
    imageUrl: 'https://images.unsplash.com/photo-1598327105666-5b89351aff97',
    categoryId,
  }, { headers: authHeaders });
  assert(prod1Res.status === 201 || prod1Res.status === 200, 'Product 1 (Samsung A54) created');
  const product1 = prod1Res.data;

  const prod2Res = await axios.post(`${baseURL}/api/products`, {
    name: 'Anker Fast USB-C Charger 30W',
    description: 'Compact GaN fast wall charger for smartphones and tablets.',
    sku: 'ANK-30W-CHG',
    price: 24.99,
    currency: 'USD',
    stockQuantity: 100,
    stockStatus: 'instock',
  }, { headers: authHeaders });
  assert(prod2Res.status === 201 || prod2Res.status === 200, 'Product 2 (Anker Charger) created');
  const product2 = prod2Res.data;

  // 3.3 List and Filter Products
  const prodList = await axios.get(`${baseURL}/api/products`, { headers: authHeaders });
  assert(prodList.data.length >= 2, 'Products list returns created items');

  const prodSearch = await axios.get(`${baseURL}/api/products?search=Samsung`, { headers: authHeaders });
  assert(prodSearch.data.some((p: any) => p.name.includes('Samsung')), 'Product search by keyword works');

  // -------------------------------------------------------------
  // USE CASE 4: WhatsApp Inbound Bot Commerce & Cart Flow
  // -------------------------------------------------------------
  console.log('\n--- USE CASE 4: WhatsApp Inbound Bot Commerce & Cart Flow ---');
  const customerPhone = `26377${Math.floor(100000 + Math.random() * 900000)}`;

  // 4.1 Reset and Welcome Message
  const botStep1 = await axios.post(`${baseURL}/webhooks/whatsapp/simulate`, {
    businessId,
    whatsappNumber: customerPhone,
    message: 'reset',
  });
  assert(botStep1.status === 200, 'WhatsApp simulator accepts message');
  assert(!!botStep1.data.reply, 'Bot returns welcome greeting');

  // 4.2 Webview Confirmation / Add to Cart
  const webviewRes = await axios.post(`${baseURL}/webhooks/whatsapp/webview-confirm`, {
    businessId,
    whatsappNumber: customerPhone,
    productId: product1.id,
    quantity: 2,
  });
  assert(webviewRes.status === 200 && webviewRes.data.success === true, 'Webview product added to cart');
  assert(webviewRes.data.totalQuantity === 2, 'Total quantity in cart is 2');

  // -------------------------------------------------------------
  // USE CASE 5: Order Checkout & Payment Lifecycle
  // -------------------------------------------------------------
  console.log('\n--- USE CASE 5: Order Checkout & Payment Lifecycle ---');

  // 5.1 From POST_ADD_TO_CART -> View Cart (Sends '1')
  const botViewCart = await axios.post(`${baseURL}/webhooks/whatsapp/simulate`, {
    businessId,
    whatsappNumber: customerPhone,
    message: '1', // View Cart
  });
  assert(botViewCart.status === 200, 'Bot displayed Cart summary');

  // 5.2 From CART -> Proceed to Checkout (Sends '1')
  const botStartCheckout = await axios.post(`${baseURL}/webhooks/whatsapp/simulate`, {
    businessId,
    whatsappNumber: customerPhone,
    message: '1', // Checkout
  });
  assert(botStartCheckout.status === 200, 'Bot prompted for Full Name');

  // 5.3 From CHECKOUT_NAME -> Provide Name
  const botName = await axios.post(`${baseURL}/webhooks/whatsapp/simulate`, {
    businessId,
    whatsappNumber: customerPhone,
    message: 'Tinashe Moyo',
  });
  assert(botName.status === 200, 'Customer name submitted and delivery method prompted');

  // 5.4 From CHECKOUT_DELIVERY -> Select Home Delivery (Sends '1')
  const botDelivery = await axios.post(`${baseURL}/webhooks/whatsapp/simulate`, {
    businessId,
    whatsappNumber: customerPhone,
    message: '1', // Home Delivery
  });
  assert(botDelivery.status === 200, 'Delivery option chosen and address prompted');

  // 5.5 From CHECKOUT_ADDRESS -> Provide Physical Address
  const botAddress = await axios.post(`${baseURL}/webhooks/whatsapp/simulate`, {
    businessId,
    whatsappNumber: customerPhone,
    message: '45 Samora Machel Avenue, Harare, Zimbabwe',
  });
  assert(botAddress.status === 200, 'Delivery address submitted and order confirmation summary presented');

  // 5.6 From CHECKOUT_CONFIRM -> Confirm & Pay (Sends '1')
  const botConfirmOrder = await axios.post(`${baseURL}/webhooks/whatsapp/simulate`, {
    businessId,
    whatsappNumber: customerPhone,
    message: '1', // Confirm & Pay
  });
  assert(botConfirmOrder.status === 200, 'Order successfully placed via bot');
  console.log('  Bot Order Confirmation Reply:\n', botConfirmOrder.data.reply);

  // 5.6 Verify Order Created in Database
  const ordersListRes = await axios.get(`${baseURL}/api/orders`, { headers: authHeaders });
  assert(ordersListRes.data.length >= 1, 'Merchant sees created order in orders list');
  const latestOrder = ordersListRes.data[0];
  assert(latestOrder.customerPhone === customerPhone, 'Order customerPhone matches');
  assert(latestOrder.totalAmount === 699.98, 'Order total calculated correctly (2 x $349.99)');
  assert(latestOrder.paymentStatus === 'UNPAID', 'Initial order payment status is UNPAID');

  // 5.7 Simulate Payment Gateway Webhook Confirmation
  const paymentRecord = latestOrder.payments?.[0];
  const paymentRef = paymentRecord?.paymentReference;
  assert(!!paymentRef, 'Order has associated payment reference');

  const webhookConfirmRes = await axios.post(`${baseURL}/webhooks/payments/mock`, {
    reference: paymentRef,
    status: 'SUCCESS',
    gatewayReference: `GW-MOCK-${Date.now()}`,
  });
  assert(webhookConfirmRes.status === 200, 'Payment webhook returns 200 OK');
  assert(webhookConfirmRes.data.success === true, 'Payment confirmation succeeded');

  // 5.8 Verify Order status updated to PROCESSING and paymentStatus to PAID
  const orderCheckRes = await axios.get(`${baseURL}/api/orders/${latestOrder.id}`, { headers: authHeaders });
  assert(orderCheckRes.data.paymentStatus === 'PAID', 'Order paymentStatus updated to PAID');
  assert(orderCheckRes.data.status === 'PROCESSING', 'Order status updated to PROCESSING');

  // 5.9 Verify Inventory Deducted (Original 25 - 2 = 23)
  const updatedProduct1 = await axios.get(`${baseURL}/api/products/${product1.id}`, { headers: authHeaders });
  assert(updatedProduct1.data.stockQuantity === 23, 'Product stock decremented after payment confirmation');

  // -------------------------------------------------------------
  // USE CASE 6: Public Order Tracking
  // -------------------------------------------------------------
  console.log('\n--- USE CASE 6: Public Order Tracking ---');
  const trackingRes = await axios.get(`${baseURL}/track/${latestOrder.id}`);
  assert(trackingRes.status === 200, 'Public tracking lookup returns 200 OK');
  assert(trackingRes.data.order.orderNumber === latestOrder.orderNumber, 'Public tracking order number matches');
  assert(trackingRes.data.order.status === 'PROCESSING', 'Public tracking reflects real-time status PROCESSING');
  assert(trackingRes.data.order.customerName === 'Tinashe Moyo', 'Public tracking customer name matches');
  assert(!!trackingRes.data.order.deliveryAddress, 'Public tracking delivery address present');

  // -------------------------------------------------------------
  // USE CASE 7: Subscription Tier Enforcement
  // -------------------------------------------------------------
  console.log('\n--- USE CASE 7: Subscription & Plan Tier Enforcement ---');
  const subStatusRes = await axios.get(`${baseURL}/api/subscription/status`, { headers: authHeaders });
  assert(subStatusRes.status === 200, 'Subscription status endpoint returns 200 OK');
  assert(subStatusRes.data.status === 'TRIAL', 'Subscription status matches TRIAL');
  assert(subStatusRes.data.plan === 'STARTER', 'Subscription plan matches STARTER');
  assert(typeof subStatusRes.data.usage === 'object', 'Subscription plan usage structure provided');
  assert(typeof subStatusRes.data.usage.products === 'object', 'Product usage metrics provided');

  console.log('\n===============================================================');
  console.log(`   🎉 ALL ${passedTests}/${totalTests} SYSTEM USE-CASE TESTS PASSED WITH 0 ERRORS! `);
  console.log('===============================================================\n');
}

runFullSystemUseCases().catch((err) => {
  console.error('❌ System Use Case test failed with error:');
  if (err.response) {
    console.error(`Status: ${err.response.status}`);
    console.error('Data:', JSON.stringify(err.response.data, null, 2));
  } else {
    console.error(err.stack || err.message);
  }
  process.exit(1);
});
