import { NextRequest, NextResponse } from 'next/server';
import { createClient } from '@/lib/auth/server';
import type { PatientOverzicht, PatientOverzichtResponse } from '@/lib/types/overdracht';

export async function GET(request: NextRequest) {
  try {
    const { searchParams } = new URL(request.url);
    const dateParam = searchParams.get('date');

    // Use provided date or today
    const targetDate = dateParam || new Date().toISOString().split('T')[0];

    // Validate date format
    if (!/^\d{4}-\d{2}-\d{2}$/.test(targetDate)) {
      return NextResponse.json(
        { error: 'date moet in YYYY-MM-DD formaat zijn' },
        { status: 400 }
      );
    }

    const supabase = await createClient();

    // Get start and end of day for date filtering
    const dayStart = `${targetDate}T00:00:00.000Z`;
    const dayEnd = `${targetDate}T23:59:59.999Z`;

    // 1. Get patients with encounters today
    const { data: encounterData, error: encounterError } = await supabase
      .from('encounters')
      .select(`
        patient_id,
        patients!inner (
          id,
          name_given,
          name_family,
          birth_date,
          gender
        )
      `)
      .gte('period_start', dayStart)
      .lte('period_start', dayEnd)
      .in('status', ['planned', 'in-progress', 'completed']);

    if (encounterError) {
      console.error('Error fetching encounters:', encounterError);
      return NextResponse.json(
        { error: 'Fout bij ophalen patiënten', details: encounterError.message },
        { status: 500 }
      );
    }

    // Deduplicate patients (one patient may have multiple encounters)
    const patientMap = new Map<string, {
      id: string;
      name_given: string[];
      name_family: string;
      birth_date: string;
      gender: string;
    }>();

    for (const encounter of encounterData || []) {
      const patient = encounter.patients as unknown as {
        id: string;
        name_given: string[];
        name_family: string;
        birth_date: string;
        gender: string;
      };
      if (patient && !patientMap.has(patient.id)) {
        patientMap.set(patient.id, patient);
      }
    }

    const patientIds = Array.from(patientMap.keys());

    if (patientIds.length === 0) {
      const response: PatientOverzichtResponse = {
        patients: [],
        total: 0,
        date: targetDate,
      };
      return NextResponse.json(response);
    }

    // 2. Get alert counts in parallel
    const [
      { data: risksData },
      { data: vitalsData },
      { data: logsData },
      { data: incidentReportsData },
    ] = await Promise.all([
      // High risk assessments (via intakes)
      supabase
        .from('risk_assessments')
        .select('id, intakes!inner(patient_id)')
        .in('intakes.patient_id', patientIds)
        .in('risk_level', ['hoog', 'zeer_hoog']),

      // Abnormal vitals today
      supabase
        .from('observations')
        .select('id, patient_id, interpretation_code')
        .in('patient_id', patientIds)
        .eq('category', 'vital-signs')
        .gte('effective_datetime', dayStart)
        .lte('effective_datetime', dayEnd)
        .in('interpretation_code', ['H', 'L', 'HH', 'LL']),

      // Marked reports (type=verpleegkundig) for handover
      supabase
        .from('reports')
        .select('id, patient_id')
        .in('patient_id', patientIds)
        .eq('type', 'verpleegkundig')
        .eq('shift_date', targetDate)
        .eq('include_in_handover', true)
        .is('deleted_at', null),

      // Incident reports today (type='incident' OR verpleegkundig with category='incident')
      supabase
        .from('reports')
        .select('id, patient_id, type, structured_data')
        .in('patient_id', patientIds)
        .gte('created_at', dayStart)
        .lte('created_at', dayEnd)
        .is('deleted_at', null),
    ]);

    // Count alerts per patient
    const alertCounts = new Map<string, {
      high_risk_count: number;
      abnormal_vitals_count: number;
      marked_logs_count: number;
      incident_count: number;
    }>();

    // Initialize all patients with zero counts
    for (const patientId of patientIds) {
      alertCounts.set(patientId, {
        high_risk_count: 0,
        abnormal_vitals_count: 0,
        marked_logs_count: 0,
        incident_count: 0,
      });
    }

    // Count high risks
    for (const risk of risksData || []) {
      const intake = risk.intakes as unknown as { patient_id: string };
      if (intake?.patient_id) {
        const counts = alertCounts.get(intake.patient_id);
        if (counts) counts.high_risk_count++;
      }
    }

    // Count abnormal vitals
    for (const vital of vitalsData || []) {
      if (vital.patient_id) {
        const counts = alertCounts.get(vital.patient_id);
        if (counts) counts.abnormal_vitals_count++;
      }
    }

    // Count marked logs
    for (const log of logsData || []) {
      if (log.patient_id) {
        const counts = alertCounts.get(log.patient_id);
        if (counts) counts.marked_logs_count++;
      }
    }

    // Count incidents (type='incident' OR type='crisis' OR verpleegkundig with category='incident')
    for (const report of incidentReportsData || []) {
      if (!report.patient_id) continue;
      const counts = alertCounts.get(report.patient_id);
      if (!counts) continue;

      // Direct incident/crisis type
      if (report.type === 'incident' || report.type === 'crisis') {
        counts.incident_count++;
        continue;
      }

      // Verpleegkundig report with incident category
      if (report.type === 'verpleegkundig' && report.structured_data) {
        const data = report.structured_data as { category?: string };
        if (data.category === 'incident') {
          counts.incident_count++;
        }
      }
    }

    // 3. Build response
    const patients: PatientOverzicht[] = Array.from(patientMap.values()).map(
      (patient) => {
        const alerts = alertCounts.get(patient.id) || {
          high_risk_count: 0,
          abnormal_vitals_count: 0,
          marked_logs_count: 0,
          incident_count: 0,
        };

        return {
          id: patient.id,
          name_given: patient.name_given,
          name_family: patient.name_family,
          birth_date: patient.birth_date,
          gender: patient.gender,
          alerts: {
            ...alerts,
            total:
              alerts.high_risk_count +
              alerts.abnormal_vitals_count +
              alerts.marked_logs_count +
              alerts.incident_count,
          },
        };
      }
    );

    // Sort by total alerts (descending), then by name
    patients.sort((a, b) => {
      if (b.alerts.total !== a.alerts.total) {
        return b.alerts.total - a.alerts.total;
      }
      return a.name_family.localeCompare(b.name_family);
    });

    const response: PatientOverzichtResponse = {
      patients,
      total: patients.length,
      date: targetDate,
    };

    return NextResponse.json(response);
  } catch (error) {
    console.error('Unexpected error in GET /api/overdracht/patients:', error);
    return NextResponse.json(
      { error: 'Onverwachte serverfout' },
      { status: 500 }
    );
  }
}
