import { NextRequest, NextResponse } from 'next/server'
import { supabaseAdmin } from '@/lib/supabase/admin'

/**
 * @description Fetches comprehensive dashboard data including bookings, top performers, and activity feed
 */
export async function GET(request: NextRequest) {
  try {
    const { searchParams } = new URL(request.url)
    const locationId = searchParams.get('location_id')
    const startDate = searchParams.get('start_date')
    const endDate = searchParams.get('end_date')
    const staffId = searchParams.get('staff_id')
    const status = searchParams.get('status')
    const includeCustomers = searchParams.get('include_customers') === 'true'
    const includeTopPerformers = searchParams.get('include_top_performers') === 'true'
    const includeActivity = searchParams.get('include_activity') === 'true'

    // Get basic bookings data first
    let query = supabaseAdmin
      .from('bookings')
      .select('id, short_id, status, start_time_utc, end_time_utc, is_paid, created_at, customer_id, service_id, staff_id, resource_id')
      .order('start_time_utc', { ascending: true })

    if (locationId) {
      query = query.eq('location_id', locationId)
    }

    if (startDate) {
      query = query.gte('start_time_utc', startDate)
    }

    if (endDate) {
      query = query.lte('end_time_utc', endDate)
    }

    if (staffId) {
      query = query.eq('staff_id', staffId)
    }

    if (status) {
      query = query.in('status', status.split(','))
    }

    const { data: bookings, error } = await query
    if (error) {
      console.error('Aperture dashboard GET error:', error)
      return NextResponse.json(
        { error: error.message },
        { status: 500 }
      )
    }

    // Fetch related data for bookings
    const customerIds = bookings?.map(b => b.customer_id).filter(Boolean) || []
    const serviceIds = bookings?.map(b => b.service_id).filter(Boolean) || []
    const staffIds = bookings?.map(b => b.staff_id).filter(Boolean) || []
    const resourceIds = bookings?.map(b => b.resource_id).filter(Boolean) || []

    const [customers, services, staff, resources] = await Promise.all([
      customerIds.length > 0 ? supabaseAdmin.from('customers').select('id, first_name, last_name, email').in('id', customerIds) : Promise.resolve({ data: [] }),
      serviceIds.length > 0 ? supabaseAdmin.from('services').select('id, name, duration_minutes, base_price').in('id', serviceIds) : Promise.resolve({ data: [] }),
      staffIds.length > 0 ? supabaseAdmin.from('staff').select('id, display_name').in('id', staffIds) : Promise.resolve({ data: [] }),
      resourceIds.length > 0 ? supabaseAdmin.from('resources').select('id, name, type').in('id', resourceIds) : Promise.resolve({ data: [] })
    ])

    const customerMap = new Map(customers.data?.map(c => [c.id, c]) || [])
    const serviceMap = new Map(services.data?.map(s => [s.id, s]) || [])
    const staffMap = new Map(staff.data?.map(s => [s.id, s]) || [])
    const resourceMap = new Map(resources.data?.map(r => [r.id, r]) || [])

    // Combine bookings with related data
    const bookingsWithRelations = bookings?.map(booking => ({
      ...booking,
      customer: customerMap.get(booking.customer_id),
      service: serviceMap.get(booking.service_id),
      staff: staffMap.get(booking.staff_id),
      resource: resourceMap.get(booking.resource_id)
    })) || []

    const response: any = {
      success: true,
      bookings: bookingsWithRelations
    }

    if (includeCustomers) {
      const { count: totalCustomers } = await supabaseAdmin
        .from('customers')
        .select('*', { count: 'exact', head: true })

      const now = new Date()
      const todayStart = new Date(now.getFullYear(), now.getMonth(), now.getDate())
      const monthStart = new Date(now.getFullYear(), now.getMonth(), 1)

      const { count: newCustomersToday } = await supabaseAdmin
        .from('customers')
        .select('*', { count: 'exact', head: true })
        .gte('created_at', todayStart.toISOString())

      const { count: newCustomersMonth } = await supabaseAdmin
        .from('customers')
        .select('*', { count: 'exact', head: true })
        .gte('created_at', monthStart.toISOString())

      response.customers = {
        total: totalCustomers || 0,
        newToday: newCustomersToday || 0,
        newMonth: newCustomersMonth || 0
      }
    }

    if (includeTopPerformers) {
      const monthStart = new Date(new Date().getFullYear(), new Date().getMonth(), 1)

      // Get bookings data
      const { data: bookingsData } = await supabaseAdmin
        .from('bookings')
        .select('staff_id, total_amount, start_time_utc, end_time_utc')
        .eq('status', 'completed')
        .gte('end_time_utc', monthStart.toISOString())

      // Get staff data separately
      const { data: staffData } = await supabaseAdmin
        .from('staff')
        .select('id, display_name, role')

      const staffMap = new Map(staffData?.map(s => [s.id, s]) || [])

      const staffPerformance = new Map()

      bookingsData?.forEach((booking: any) => {
        const staffId = booking.staff_id
        const staff = staffMap.get(staffId)

        if (!staffPerformance.has(staffId)) {
          staffPerformance.set(staffId, {
            staffId,
            displayName: staff?.display_name || 'Unknown',
            role: staff?.role || 'Unknown',
            totalBookings: 0,
            totalRevenue: 0,
            totalHours: 0
          })
        }

        const perf = staffPerformance.get(staffId)
        perf.totalBookings += 1
        perf.totalRevenue += booking.total_amount || 0

        const duration = booking.end_time_utc && booking.start_time_utc
          ? (new Date(booking.end_time_utc).getTime() - new Date(booking.start_time_utc).getTime()) / (1000 * 60 * 60)
          : 0
        perf.totalHours += duration
      })

      response.topPerformers = Array.from(staffPerformance.values())
        .sort((a: any, b: any) => b.totalRevenue - a.totalRevenue)
        .slice(0, 10)
    }

    if (includeActivity) {
      // Get recent bookings
      const { data: recentBookings } = await supabaseAdmin
        .from('bookings')
        .select('id, short_id, status, start_time_utc, end_time_utc, created_at, customer_id, service_id, staff_id')
        .order('created_at', { ascending: false })
        .limit(10)

      // Get related data
      const customerIds = recentBookings?.map(b => b.customer_id).filter(Boolean) || []
      const serviceIds = recentBookings?.map(b => b.service_id).filter(Boolean) || []
      const staffIds = recentBookings?.map(b => b.staff_id).filter(Boolean) || []

      const [customers, services, staff] = await Promise.all([
        customerIds.length > 0 ? supabaseAdmin.from('customers').select('id, first_name, last_name').in('id', customerIds) : Promise.resolve({ data: [] }),
        serviceIds.length > 0 ? supabaseAdmin.from('services').select('id, name').in('id', serviceIds) : Promise.resolve({ data: [] }),
        staffIds.length > 0 ? supabaseAdmin.from('staff').select('id, display_name').in('id', staffIds) : Promise.resolve({ data: [] })
      ])

      const customerMap = new Map(customers.data?.map(c => [c.id, c]) || [])
      const serviceMap = new Map(services.data?.map(s => [s.id, s]) || [])
      const staffMap = new Map(staff.data?.map(s => [s.id, s]) || [])

      const activityFeed = recentBookings?.map((booking: any) => {
        const customer = customerMap.get(booking.customer_id)
        const service = serviceMap.get(booking.service_id)
        const staffMember = staffMap.get(booking.staff_id)

        return {
          id: booking.id,
          type: 'booking',
          action: booking.status === 'completed' ? 'completed' :
                   booking.status === 'confirmed' ? 'confirmed' :
                   booking.status === 'cancelled' ? 'cancelled' : 'created',
          timestamp: booking.created_at,
          bookingShortId: booking.short_id,
          customerName: customer ? `${customer.first_name || ''} ${customer.last_name || ''}`.trim() : 'Unknown',
          serviceName: service?.name || 'Unknown',
          staffName: staffMember?.display_name || 'Unknown'
        }
      })

      response.activityFeed = activityFeed
    }

    return NextResponse.json(response)
  } catch (error) {
    console.error('Aperture dashboard GET error:', error)
    return NextResponse.json(
      { error: 'Internal server error' },
      { status: 500 }
    )
  }
}
