import { NextRequest, NextResponse } from 'next/server';
import { prisma } from '@/lib/prisma';
import { z } from 'zod';
import { DistanceCalculator } from '@/lib/distance-calculator';
import { PriceCalculator } from '@/lib/price-calculator';
import { bookingAutomationService } from '@/lib/booking-automation';

const bookingSchema = z.object({
  locationSlug: z.string(),
  model: z.enum(['VINTAGE_SMILE', 'VINTAGE_PHOTOS', 'NOSTALGIE', 'MAGIC_MIRROR']),
  customerName: z.string().min(2),
  customerEmail: z.string().email(),
  customerPhone: z.string().min(5),
  customerAddress: z.string().optional(),
  customerCity: z.string().optional(),
  customerZip: z.string().optional(),
  invoiceType: z.enum(['PRIVATE', 'BUSINESS']),
  companyName: z.string().optional(),
  eventDate: z.string(),
  eventAddress: z.string().min(5),
  eventCity: z.string().min(2),
  eventZip: z.string().min(4),
  eventLocation: z.string().optional(),
  setupTimeStart: z.string(),
  setupTimeLatest: z.string(),
  dismantleTimeEarliest: z.string().optional(),
  dismantleTimeLatest: z.string().optional(),
  notes: z.string().optional(),
});

function generateBookingNumber(): string {
  const date = new Date();
  const year = date.getFullYear().toString().slice(-2);
  const month = String(date.getMonth() + 1).padStart(2, '0');
  const random = Math.floor(Math.random() * 10000).toString().padStart(4, '0');
  return `STM-${year}${month}-${random}`;
}

export async function POST(request: NextRequest) {
  try {
    const body = await request.json();
    const data = bookingSchema.parse(body);

    const location = await prisma.location.findUnique({
      where: { slug: data.locationSlug },
    });

    if (!location) {
      return NextResponse.json(
        { error: 'Standort nicht gefunden' },
        { status: 404 }
      );
    }

    const eventDate = new Date(data.eventDate);
    const startOfDay = new Date(eventDate);
    startOfDay.setHours(0, 0, 0, 0);
    const endOfDay = new Date(eventDate);
    endOfDay.setHours(23, 59, 59, 999);

    const availablePhotobox = await prisma.photobox.findFirst({
      where: {
        locationId: location.id,
        model: data.model,
        active: true,
        NOT: {
          bookings: {
            some: {
              eventDate: {
                gte: startOfDay,
                lte: endOfDay,
              },
              status: {
                in: ['RESERVED', 'CONFIRMED'],
              },
            },
          },
        },
      },
    });

    if (!availablePhotobox) {
      return NextResponse.json(
        { error: 'Keine Fotobox verfügbar für dieses Datum' },
        { status: 409 }
      );
    }

    const priceConfig = await prisma.priceConfig.findUnique({
      where: {
        locationId_model: {
          locationId: location.id,
          model: data.model,
        },
      },
    });

    if (!priceConfig) {
      return NextResponse.json(
        { error: 'Preiskonfiguration nicht gefunden' },
        { status: 404 }
      );
    }

    let distance: number | null = null;
    let calculatedPrice = priceConfig.basePrice;

    if (location.warehouseAddress && location.warehouseZip && location.warehouseCity) {
      const warehouseAddress = DistanceCalculator.formatAddress(
        location.warehouseAddress,
        location.warehouseZip,
        location.warehouseCity
      );
      const eventAddress = DistanceCalculator.formatAddress(
        data.eventAddress,
        data.eventZip,
        data.eventCity
      );

      const distanceResult = await DistanceCalculator.calculateDistance(
        warehouseAddress,
        eventAddress
      );

      if (distanceResult) {
        distance = distanceResult.distance;
        
        const priceBreakdown = PriceCalculator.calculateTotalPrice(
          priceConfig.basePrice,
          distance,
          {
            basePrice: priceConfig.basePrice,
            kmFlatRate: priceConfig.kmFlatRate,
            kmFlatRateUpTo: priceConfig.kmFlatRateUpTo,
            pricePerKm: priceConfig.pricePerKm,
            kmMultiplier: priceConfig.kmMultiplier,
          }
        );

        calculatedPrice = priceBreakdown.totalPrice;

        console.log('📍 Distanzberechnung:', {
          from: warehouseAddress,
          to: eventAddress,
          distance: `${distance}km`,
          breakdown: PriceCalculator.formatPriceBreakdown(priceBreakdown),
        });
      } else {
        console.warn('⚠️  Distanzberechnung fehlgeschlagen, verwende nur Grundpreis');
      }
    } else {
      console.warn('⚠️  Keine Lager-Adresse konfiguriert, verwende nur Grundpreis');
    }

    const booking = await prisma.booking.create({
      data: {
        bookingNumber: generateBookingNumber(),
        locationId: location.id,
        photoboxId: availablePhotobox.id,
        status: 'RESERVED',
        customerName: data.customerName,
        customerEmail: data.customerEmail,
        customerPhone: data.customerPhone,
        customerAddress: data.customerAddress,
        customerCity: data.customerCity,
        customerZip: data.customerZip,
        invoiceType: data.invoiceType,
        companyName: data.companyName,
        eventDate: new Date(data.eventDate),
        eventAddress: data.eventAddress,
        eventCity: data.eventCity,
        eventZip: data.eventZip,
        eventLocation: data.eventLocation,
        setupTimeStart: new Date(data.setupTimeStart),
        setupTimeLatest: new Date(data.setupTimeLatest),
        dismantleTimeEarliest: data.dismantleTimeEarliest ? new Date(data.dismantleTimeEarliest) : null,
        dismantleTimeLatest: data.dismantleTimeLatest ? new Date(data.dismantleTimeLatest) : null,
        distance,
        calculatedPrice,
        notes: data.notes,
      },
      include: {
        location: true,
        photobox: true,
      },
    });

    await prisma.notification.create({
      data: {
        type: 'NEW_BOOKING',
        title: 'Neue Buchungsanfrage',
        message: `${data.customerName} hat eine ${data.model} für ${data.eventCity} am ${eventDate.toLocaleDateString('de-DE')} angefragt.`,
        metadata: {
          bookingId: booking.id,
          bookingNumber: booking.bookingNumber,
        },
      },
    });

    // 🤖 Automatische Post-Booking Aktionen (E-Mail + Kalender)
    console.log('📢 Starte automatische Aktionen...');
    bookingAutomationService.runPostBookingActions(booking.id).catch(err => {
      console.error('⚠️  Automatische Aktionen fehlgeschlagen:', err);
    });

    return NextResponse.json({
      success: true,
      booking: {
        id: booking.id,
        bookingNumber: booking.bookingNumber,
        status: booking.status,
        eventDate: booking.eventDate,
        calculatedPrice: booking.calculatedPrice,
      },
      message: 'Buchungsanfrage erfolgreich erstellt! Wir melden uns in Kürze bei Ihnen.',
    });
  } catch (error) {
    if (error instanceof z.ZodError) {
      return NextResponse.json(
        { error: 'Ungültige Daten', details: error.errors },
        { status: 400 }
      );
    }

    console.error('Booking creation error:', error);
    return NextResponse.json(
      { error: 'Interner Serverfehler' },
      { status: 500 }
    );
  }
}

export async function GET(request: NextRequest) {
  try {
    const searchParams = request.nextUrl.searchParams;
    const status = searchParams.get('status');
    const locationSlug = searchParams.get('location');

    const where: any = {};

    if (status) {
      // Support multiple statuses separated by comma
      const statuses = status.split(',').map(s => s.trim());
      if (statuses.length > 1) {
        where.status = { in: statuses };
      } else {
        where.status = status;
      }
    }

    if (locationSlug) {
      const location = await prisma.location.findUnique({
        where: { slug: locationSlug },
      });
      if (location) {
        where.locationId = location.id;
      }
    }

    const bookings = await prisma.booking.findMany({
      where,
      include: {
        location: true,
        photobox: true,
        setupWindows: {
          orderBy: { setupDate: 'asc' },
        },
      },
      orderBy: {
        createdAt: 'desc',
      },
      take: 100,
    });

    return NextResponse.json({ bookings });
  } catch (error) {
    console.error('Bookings fetch error:', error);
    return NextResponse.json(
      { error: 'Interner Serverfehler' },
      { status: 500 }
    );
  }
}
