import { NextResponse } from 'next/server';
import { createClient } from '@/lib/supabase/server';
import { getProducts, getCategories } from '@/lib/actions/products';
import { buildCustomerSnapshot, buildOrderSnapshot } from '@/lib/license-transform';
import { sendMail } from '@/utils/mail';
import { createHash } from 'crypto';
import { renderToBuffer } from '@react-pdf/renderer';
import React from 'react';
import { InvoicePDF } from '@/components/invoice-pdf';

function generateOrderNumber(prefix: 'BE' | 'AE' = 'AE'): string {
  const year = new Date().getFullYear();
  const rand = Math.floor(10000 + Math.random() * 90000);
  return `${prefix}-${year}-${rand}`;
}

function hashOrderSnapshot(snapshot: object): string {
  return createHash('sha256').update(JSON.stringify(snapshot)).digest('hex');
}

export async function POST(request: Request) {
  try {
    const supabase = await createClient();
    const { data: { user } } = await supabase.auth.getUser();

    if (!user) {
      return NextResponse.json({ error: 'Not authenticated' }, { status: 401 });
    }

    const { data: dbUser } = await supabase
      .from('users')
      .select('role, company_id')
      .eq('id', user.id)
      .single();

    const isAdminUser = dbUser?.role === 'admin';
    if (!isAdminUser && !dbUser?.company_id) {
      return NextResponse.json({ error: 'Firma erforderlich' }, { status: 403 });
    }

    const body = await request.json();
    const { items, customerProfile, endCustomerId, endCustomer } = body;

    if (!items || !Array.isArray(items) || items.length === 0) {
      return NextResponse.json({ error: 'Warenkorb leer' }, { status: 400 });
    }

    const products = await getProducts();
    const categories = await getCategories();

    // Split items into purchase and subscription
    const purchaseItems = items.filter(
      (item: any) => item.billingInterval === 'one_time' || item.billingType === 'purchase'
    );
    const subscriptionItems = items.filter(
      (item: any) => item.billingInterval === 'monthly' || item.billingType === 'subscription'
    );

    const createdOrders: any[] = [];

    const processOrderGroup = async (groupItems: any[], type: 'purchase' | 'subscription', paymentMethod: string) => {
      if (groupItems.length === 0) return;

      // Build consolidated snapshots
      // For the multi-item support, we combine the order snapshots of each item in the group
      const customerSnapshot = buildCustomerSnapshot(customerProfile, endCustomer);
      
      const orderItemsList: any[] = [];
      let total = 0;

      for (const item of groupItems) {
        const itemSnapshot = buildOrderSnapshot(
          item.selections,
          products,
          categories,
          type === 'purchase' ? 'one_time' : 'monthly',
          item.moduleQuantities
        );
        const itemsWithDevice = itemSnapshot.items.map(i => ({
          ...i,
          device_name: item.deviceName
        }));
        orderItemsList.push(...itemsWithDevice);
        total += itemSnapshot.total;
      }

      const orderSnapshot = {
        schema_version: 1,
        billing_cycle: type === 'purchase' ? 'one_time' : 'monthly',
        items: orderItemsList,
        total: total,
        tax_rate: 19, // default
        tax_amount: Math.round(total * 0.19 * 100) / 100,
        subtotal: Math.round((total / 1.19) * 100) / 100
      };

      const orderHash = hashOrderSnapshot(orderSnapshot);
      const orderNumber = generateOrderNumber(type === 'purchase' ? 'AE' : 'BE');

      const { data: order, error: orderError } = await supabase
        .from('orders')
        .insert([{
          user_id: user.id,
          company_id: dbUser?.company_id || null,
          order_number: orderNumber,
          order_hash: orderHash,
          end_customer_id: endCustomerId || null,
          total_price: total,
          customer_data: customerSnapshot,
          order_data: orderSnapshot,
          type: type,
          payment_method: paymentMethod,
          status: 'pending'
        }])
        .select()
        .single();

      if (orderError) throw orderError;

      // Trigger PDF generation & storage upload
      try {
        const buffer = await renderToBuffer(
          React.createElement(InvoicePDF, {
            order,
            customer: customerSnapshot,
            orderSnapshot,
          })
        );

        const fileName = `ab_${order.id}.pdf`;
        const { error: uploadError } = await supabase
          .storage
          .from('invoices')
          .upload(fileName, buffer, { contentType: 'application/pdf', upsert: true });

        if (!uploadError) {
          await supabase.from('orders').update({ pdf_url: fileName }).eq('id', order.id);
          order.pdf_url = fileName;
        }
      } catch (pdfErr) {
        console.error('PDF error for order ' + order.id, pdfErr);
      }

      // Trigger E-Mail notifications
      if (user.email) {
        try {
          await sendMail({
            to: user.email,
            subject: `Bestätigung Ihrer CASPOS-Anfrage ${order.order_number}`,
            text: `Vielen Dank für Ihre Anfrage ${order.order_number}.`,
            html: `<p>Vielen Dank für Ihre Anfrage <strong>${order.order_number}</strong>.</p>`
          });
        } catch (mailErr) {
          console.error('Mail error for order ' + order.id, mailErr);
        }
      }

      createdOrders.push(order);
    };

    await processOrderGroup(purchaseItems, 'purchase', 'invoice');
    await processOrderGroup(subscriptionItems, 'subscription', 'sepa');

    return NextResponse.json({ success: true, orders: createdOrders });
  } catch (error: any) {
    console.error('Checkout error:', error);
    return NextResponse.json({ error: error.message || 'Internal server error' }, { status: 500 });
  }
}
