const express = require('express');
const router = express.Router();
const Stripe = require('stripe');
const { supabase } = require('../config/supabase');

const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);

/**
 * POST /api/webhook/stripe
 * Handles Stripe webhook events
 *
 * IMPORTANT: This route uses raw body, configured in index.js
 */
router.post('/stripe', async (req, res) => {
  const sig = req.headers['stripe-signature'];
  const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET;

  let event;

  try {
    // If webhook secret is configured, verify signature
    if (webhookSecret) {
      event = stripe.webhooks.constructEvent(req.body, sig, webhookSecret);
    } else {
      // For local development without webhook secret
      event = JSON.parse(req.body.toString());
      console.warn('⚠️ Webhook signature verification skipped (no STRIPE_WEBHOOK_SECRET)');
    }
  } catch (err) {
    console.error('Webhook signature verification failed:', err.message);
    return res.status(400).send(`Webhook Error: ${err.message}`);
  }

  console.log(`📩 Stripe webhook received: ${event.type}`);

  try {
    switch (event.type) {
      case 'checkout.session.completed':
        await handleCheckoutComplete(event.data.object);
        break;

      case 'invoice.paid':
        await handleInvoicePaid(event.data.object);
        break;

      case 'invoice.payment_failed':
        await handlePaymentFailed(event.data.object);
        break;

      case 'customer.subscription.deleted':
        await handleSubscriptionCanceled(event.data.object);
        break;

      case 'customer.subscription.updated':
        await handleSubscriptionUpdated(event.data.object);
        break;

      default:
        console.log(`Unhandled event type: ${event.type}`);
    }

    res.json({ received: true });

  } catch (error) {
    console.error(`Error handling ${event.type}:`, error);
    res.status(500).json({ error: error.message });
  }
});

/**
 * Handle checkout.session.completed
 * Creates order and beneficiary user in database
 *
 * Architecture:
 * - Beneficiary is a USER in the users table
 * - Connection between caretaker and beneficiary is in user_access table
 * - One user can be beneficiary for multiple caretakers
 */
async function handleCheckoutComplete(session) {
  console.log('Processing checkout complete:', session.id);

  const metadata = session.metadata;
  const userId = parseInt(metadata.userId, 10);

  // 1. Create beneficiary as a new user (if email provided) or placeholder
  let beneficiaryId = null;

  // Check if beneficiary with this email already exists
  if (metadata.beneficiaryEmail) {
    const { data: existingBeneficiary } = await supabase
      .from('users')
      .select('id')
      .eq('email', metadata.beneficiaryEmail.toLowerCase())
      .single();

    if (existingBeneficiary) {
      beneficiaryId = existingBeneficiary.id;
      console.log('✓ Beneficiary already exists:', beneficiaryId);
    }
  }

  // Create new beneficiary user if not exists
  if (!beneficiaryId) {
    const beneficiaryEmail = metadata.beneficiaryEmail?.toLowerCase() ||
      `beneficiary-${Date.now()}@wellnuo.placeholder`;

    const { data: newBeneficiary, error: createError } = await supabase
      .from('users')
      .insert({
        email: beneficiaryEmail,
        first_name: metadata.beneficiaryName?.split(' ')[0] || null,
        last_name: metadata.beneficiaryName?.split(' ').slice(1).join(' ') || null,
        phone: metadata.beneficiaryPhone || null,
        address_street: metadata.beneficiaryStreet || null,
        address_city: metadata.beneficiaryCity || null,
        address_zip: metadata.beneficiaryZip || null,
        address_state: metadata.beneficiaryState || null,
        address_country: metadata.beneficiaryCountry || 'US'
      })
      .select()
      .single();

    if (createError) {
      console.error('Error creating beneficiary user:', createError);
      throw createError;
    }

    beneficiaryId = newBeneficiary.id;
    console.log('✓ Beneficiary user created:', beneficiaryId);
  }

  // 2. Create user_access record (caretaker -> beneficiary)
  // Check if access already exists
  const { data: existingAccess } = await supabase
    .from('user_access')
    .select('id')
    .eq('accessor_id', userId)
    .eq('beneficiary_id', beneficiaryId)
    .single();

  if (!existingAccess) {
    const { error: accessError } = await supabase
      .from('user_access')
      .insert({
        accessor_id: userId,
        beneficiary_id: beneficiaryId,
        role: 'owner', // Purchaser gets owner role
        granted_by: userId
      });

    if (accessError) {
      console.error('Error creating user_access:', accessError);
      throw accessError;
    }
    console.log('✓ User access created');
  }

  // 3. Parse shipping address
  let shippingAddress = {};
  try {
    if (session.shipping_details) {
      shippingAddress = session.shipping_details.address;
    } else if (metadata.shippingAddress) {
      shippingAddress = JSON.parse(metadata.shippingAddress);
    }
  } catch (e) {
    console.warn('Could not parse shipping address');
  }

  // 4. Create order (uses users table foreign keys)
  const { data: order, error: orderError } = await supabase
    .from('orders')
    .insert({
      user_id: userId,
      beneficiary_id: beneficiaryId,
      beneficiary_name: metadata.beneficiaryName,
      stripe_session_id: session.id,
      stripe_payment_intent: session.payment_intent,
      status: 'paid',
      paid_at: new Date().toISOString(),
      subtotal: session.amount_subtotal || session.amount_total,
      total_amount: session.amount_total,
      currency: session.currency?.toUpperCase() || 'USD',
      shipping_address: shippingAddress,
      items: [
        {
          sku: 'STARTER-KIT',
          name: 'WellNuo Starter Kit',
          quantity: 1,
          price: 24900
        },
        ...(metadata.includePremium === 'true' ? [{
          sku: 'PREMIUM-MONTHLY',
          name: 'Premium Subscription',
          quantity: 1,
          price: 999
        }] : [])
      ],
      notes: metadata.beneficiaryNotes || null
    })
    .select()
    .single();

  if (orderError) {
    console.error('Error creating order:', orderError);
    throw orderError;
  }

  console.log('✓ Order created:', order.order_number);

  // 5. Create subscription record if Premium selected
  if (metadata.includePremium === 'true' && session.subscription) {
    const { error: subError } = await supabase
      .from('subscriptions')
      .insert({
        user_id: userId,
        beneficiary_id: beneficiaryId,
        stripe_subscription_id: session.subscription,
        stripe_customer_id: session.customer,
        plan: 'premium',
        status: 'active',
        current_period_start: new Date().toISOString(),
        current_period_end: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString()
      });

    if (subError) {
      console.error('Error creating subscription:', subError);
    } else {
      console.log('✓ Subscription created');
    }
  }

  // 6. TODO: Send confirmation email via Brevo
  console.log('TODO: Send order confirmation email');

  return { order, beneficiaryId };
}

/**
 * Handle invoice.paid
 * Updates subscription period
 */
async function handleInvoicePaid(invoice) {
  console.log('Invoice paid:', invoice.id);

  if (invoice.subscription) {
    const { error } = await supabase
      .from('subscriptions')
      .update({
        status: 'active',
        current_period_start: new Date(invoice.period_start * 1000).toISOString(),
        current_period_end: new Date(invoice.period_end * 1000).toISOString(),
        updated_at: new Date().toISOString()
      })
      .eq('stripe_subscription_id', invoice.subscription);

    if (error) {
      console.error('Error updating subscription:', error);
    } else {
      console.log('✓ Subscription period updated');
    }
  }
}

/**
 * Handle invoice.payment_failed
 * Marks subscription as past_due and notifies user
 */
async function handlePaymentFailed(invoice) {
  console.log('Payment failed:', invoice.id);

  if (invoice.subscription) {
    const { error } = await supabase
      .from('subscriptions')
      .update({
        status: 'past_due',
        updated_at: new Date().toISOString()
      })
      .eq('stripe_subscription_id', invoice.subscription);

    if (error) {
      console.error('Error updating subscription:', error);
    }

    // TODO: Send payment failed email
    console.log('TODO: Send payment failed email');
  }
}

/**
 * Handle customer.subscription.deleted
 * Downgrades user to free plan
 */
async function handleSubscriptionCanceled(subscription) {
  console.log('Subscription canceled:', subscription.id);

  const { error } = await supabase
    .from('subscriptions')
    .update({
      status: 'canceled',
      canceled_at: new Date().toISOString(),
      updated_at: new Date().toISOString()
    })
    .eq('stripe_subscription_id', subscription.id);

  if (error) {
    console.error('Error updating subscription:', error);
  } else {
    console.log('✓ Subscription marked as canceled');
  }

  // TODO: Send cancellation email
  console.log('TODO: Send cancellation email');
}

/**
 * Handle customer.subscription.updated
 * Updates subscription status
 */
async function handleSubscriptionUpdated(subscription) {
  console.log('Subscription updated:', subscription.id);

  const { error } = await supabase
    .from('subscriptions')
    .update({
      status: subscription.status,
      current_period_start: new Date(subscription.current_period_start * 1000).toISOString(),
      current_period_end: new Date(subscription.current_period_end * 1000).toISOString(),
      cancel_at_period_end: subscription.cancel_at_period_end || false,
      updated_at: new Date().toISOString()
    })
    .eq('stripe_subscription_id', subscription.id);

  if (error) {
    console.error('Error updating subscription:', error);
  }
}

module.exports = router;
