import React from "react";
import { format, parseISO, isWithinInterval, addMinutes, subMinutes } from "date-fns";
import { Alert, AlertDescription } from "@/components/ui/alert";
import { Badge } from "@/components/ui/badge";
import { AlertTriangle, X, Users, MapPin, Clock } from "lucide-react";
import { Button } from "@/components/ui/button";

/**
 * Conflict Detection System
 * Detects and alerts users to overlapping event bookings
 */

// Parse time string (HH:MM or HH:MM AM/PM) to minutes since midnight
const parseTimeToMinutes = (timeStr) => {
  if (!timeStr) return 0;
  
  // Handle 24-hour format
  if (timeStr.includes(':') && !timeStr.includes('AM') && !timeStr.includes('PM')) {
    const [hours, minutes] = timeStr.split(':').map(Number);
    return hours * 60 + minutes;
  }
  
  // Handle 12-hour format
  const [time, period] = timeStr.split(' ');
  let [hours, minutes] = time.split(':').map(Number);
  if (period === 'PM' && hours !== 12) hours += 12;
  if (period === 'AM' && hours === 12) hours = 0;
  return hours * 60 + minutes;
};

// Check if two time ranges overlap (considering buffer)
export const detectTimeOverlap = (start1, end1, start2, end2, bufferMinutes = 0) => {
  const s1 = parseTimeToMinutes(start1) - bufferMinutes;
  const e1 = parseTimeToMinutes(end1) + bufferMinutes;
  const s2 = parseTimeToMinutes(start2);
  const e2 = parseTimeToMinutes(end2);
  
  return s1 < e2 && s2 < e1;
};

// Check if two dates are the same or overlap (for multi-day events)
export const detectDateOverlap = (event1, event2) => {
  const e1Start = event1.is_multi_day ? parseISO(event1.multi_day_start_date) : parseISO(event1.date);
  const e1End = event1.is_multi_day ? parseISO(event1.multi_day_end_date) : parseISO(event1.date);
  const e2Start = event2.is_multi_day ? parseISO(event2.multi_day_start_date) : parseISO(event2.date);
  const e2End = event2.is_multi_day ? parseISO(event2.multi_day_end_date) : parseISO(event2.date);
  
  return isWithinInterval(e1Start, { start: e2Start, end: e2End }) ||
         isWithinInterval(e1End, { start: e2Start, end: e2End }) ||
         isWithinInterval(e2Start, { start: e1Start, end: e1End }) ||
         isWithinInterval(e2End, { start: e1Start, end: e1End });
};

// Detect staff conflicts
export const detectStaffConflicts = (event, allEvents) => {
  const conflicts = [];
  
  if (!event.assigned_staff || event.assigned_staff.length === 0) {
    return conflicts;
  }
  
  const eventTimes = event.shifts?.[0]?.roles?.[0] || {};
  const bufferBefore = event.buffer_time_before || 0;
  const bufferAfter = event.buffer_time_after || 0;
  
  for (const staff of event.assigned_staff) {
    for (const otherEvent of allEvents) {
      if (otherEvent.id === event.id) continue;
      if (otherEvent.status === 'Canceled' || otherEvent.status === 'Completed') continue;
      
      // Check if same staff is assigned
      const staffInOther = otherEvent.assigned_staff?.find(s => s.staff_id === staff.staff_id);
      if (!staffInOther) continue;
      
      // Check date overlap
      if (!detectDateOverlap(event, otherEvent)) continue;
      
      // Check time overlap
      const otherTimes = otherEvent.shifts?.[0]?.roles?.[0] || {};
      const hasOverlap = detectTimeOverlap(
        eventTimes.start_time,
        eventTimes.end_time,
        otherTimes.start_time,
        otherTimes.end_time,
        bufferBefore + bufferAfter
      );
      
      if (hasOverlap) {
        conflicts.push({
          conflict_type: 'staff_overlap',
          severity: 'high',
          description: `${staff.staff_name} is double-booked with "${otherEvent.event_name}"`,
          conflicting_event_id: otherEvent.id,
          conflicting_event_name: otherEvent.event_name,
          staff_id: staff.staff_id,
          staff_name: staff.staff_name,
          detected_at: new Date().toISOString(),
        });
      }
    }
  }
  
  return conflicts;
};

// Detect venue conflicts
export const detectVenueConflicts = (event, allEvents) => {
  const conflicts = [];
  
  if (!event.event_location && !event.hub) {
    return conflicts;
  }
  
  const eventLocation = event.event_location || event.hub;
  const eventTimes = event.shifts?.[0]?.roles?.[0] || {};
  const bufferBefore = event.buffer_time_before || 0;
  const bufferAfter = event.buffer_time_after || 0;
  
  for (const otherEvent of allEvents) {
    if (otherEvent.id === event.id) continue;
    if (otherEvent.status === 'Canceled' || otherEvent.status === 'Completed') continue;
    
    const otherLocation = otherEvent.event_location || otherEvent.hub;
    if (!otherLocation) continue;
    
    // Check if same location
    if (eventLocation.toLowerCase() !== otherLocation.toLowerCase()) continue;
    
    // Check date overlap
    if (!detectDateOverlap(event, otherEvent)) continue;
    
    // Check time overlap
    const otherTimes = otherEvent.shifts?.[0]?.roles?.[0] || {};
    const hasOverlap = detectTimeOverlap(
      eventTimes.start_time,
      eventTimes.end_time,
      otherTimes.start_time,
      otherTimes.end_time,
      bufferBefore + bufferAfter
    );
    
    if (hasOverlap) {
      conflicts.push({
        conflict_type: 'venue_overlap',
        severity: 'medium',
        description: `Venue "${eventLocation}" is already booked for "${otherEvent.event_name}"`,
        conflicting_event_id: otherEvent.id,
        conflicting_event_name: otherEvent.event_name,
        location: eventLocation,
        detected_at: new Date().toISOString(),
      });
    }
  }
  
  return conflicts;
};

// Detect buffer time violations
export const detectBufferViolations = (event, allEvents) => {
  const conflicts = [];
  
  if (!event.buffer_time_before && !event.buffer_time_after) {
    return conflicts;
  }
  
  const eventTimes = event.shifts?.[0]?.roles?.[0] || {};
  
  for (const otherEvent of allEvents) {
    if (otherEvent.id === event.id) continue;
    if (otherEvent.status === 'Canceled' || otherEvent.status === 'Completed') continue;
    
    // Check if events share staff
    const sharedStaff = event.assigned_staff?.filter(s => 
      otherEvent.assigned_staff?.some(os => os.staff_id === s.staff_id)
    ) || [];
    
    if (sharedStaff.length === 0) continue;
    
    // Check date overlap
    if (!detectDateOverlap(event, otherEvent)) continue;
    
    // Check if buffer time is violated
    const otherTimes = otherEvent.shifts?.[0]?.roles?.[0] || {};
    const eventStart = parseTimeToMinutes(eventTimes.start_time);
    const eventEnd = parseTimeToMinutes(eventTimes.end_time);
    const otherStart = parseTimeToMinutes(otherTimes.start_time);
    const otherEnd = parseTimeToMinutes(otherTimes.end_time);
    
    const bufferBefore = event.buffer_time_before || 0;
    const bufferAfter = event.buffer_time_after || 0;
    
    const hasViolation = 
      (otherEnd > eventStart - bufferBefore && otherEnd <= eventStart) ||
      (otherStart < eventEnd + bufferAfter && otherStart >= eventEnd);
    
    if (hasViolation) {
      conflicts.push({
        conflict_type: 'time_buffer',
        severity: 'low',
        description: `Buffer time violation with "${otherEvent.event_name}" (${sharedStaff.length} shared staff)`,
        conflicting_event_id: otherEvent.id,
        conflicting_event_name: otherEvent.event_name,
        buffer_required: `${bufferBefore + bufferAfter} minutes`,
        detected_at: new Date().toISOString(),
      });
    }
  }
  
  return conflicts;
};

// Main conflict detection function
export const detectAllConflicts = (event, allEvents) => {
  if (!event.conflict_detection_enabled) return [];
  
  const staffConflicts = detectStaffConflicts(event, allEvents);
  const venueConflicts = detectVenueConflicts(event, allEvents);
  const bufferViolations = detectBufferViolations(event, allEvents);
  
  return [...staffConflicts, ...venueConflicts, ...bufferViolations];
};

// Conflict Alert Component
export function ConflictAlert({ conflicts, onDismiss }) {
  if (!conflicts || conflicts.length === 0) return null;
  
  const getSeverityColor = (severity) => {
    switch (severity) {
      case 'critical': return 'border-red-600 bg-red-50';
      case 'high': return 'border-orange-500 bg-orange-50';
      case 'medium': return 'border-amber-500 bg-amber-50';
      case 'low': return 'border-blue-500 bg-blue-50';
      default: return 'border-slate-300 bg-slate-50';
    }
  };
  
  const getSeverityIcon = (severity) => {
    switch (severity) {
      case 'critical':
      case 'high': return <AlertTriangle className="w-5 h-5 text-red-600" />;
      case 'medium': return <AlertTriangle className="w-5 h-5 text-amber-600" />;
      case 'low': return <Clock className="w-5 h-5 text-blue-600" />;
      default: return <AlertTriangle className="w-5 h-5 text-slate-600" />;
    }
  };
  
  const getConflictIcon = (type) => {
    switch (type) {
      case 'staff_overlap': return <Users className="w-4 h-4" />;
      case 'venue_overlap': return <MapPin className="w-4 h-4" />;
      case 'time_buffer': return <Clock className="w-4 h-4" />;
      default: return null;
    }
  };
  
  return (
    <div className="space-y-3">
      {conflicts.map((conflict, idx) => (
        <Alert key={idx} className={`${getSeverityColor(conflict.severity)} border-2 relative`}>
          <div className="flex items-start gap-3">
            <div className="flex-shrink-0 mt-0.5">
              {getSeverityIcon(conflict.severity)}
            </div>
            <div className="flex-1">
              <div className="flex items-center gap-2 mb-1">
                {getConflictIcon(conflict.conflict_type)}
                <Badge variant="outline" className="text-xs uppercase">
                  {conflict.conflict_type.replace('_', ' ')}
                </Badge>
                <Badge className={`text-xs ${
                  conflict.severity === 'critical' || conflict.severity === 'high' 
                    ? 'bg-red-600 text-white' 
                    : conflict.severity === 'medium' 
                    ? 'bg-amber-600 text-white' 
                    : 'bg-blue-600 text-white'
                }`}>
                  {conflict.severity.toUpperCase()}
                </Badge>
              </div>
              <AlertDescription className="font-medium text-slate-900 text-sm">
                {conflict.description}
              </AlertDescription>
              {conflict.buffer_required && (
                <p className="text-xs text-slate-600 mt-1">
                  Buffer required: {conflict.buffer_required}
                </p>
              )}
            </div>
            {onDismiss && (
              <Button
                variant="ghost"
                size="icon"
                className="h-6 w-6 flex-shrink-0"
                onClick={() => onDismiss(idx)}
              >
                <X className="w-4 h-4" />
              </Button>
            )}
          </div>
        </Alert>
      ))}
    </div>
  );
}

export default {
  detectTimeOverlap,
  detectDateOverlap,
  detectStaffConflicts,
  detectVenueConflicts,
  detectBufferViolations,
  detectAllConflicts,
  ConflictAlert,
};