'use client';

import React, { useState, useEffect, useMemo } from 'react';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { Calendar, Clock, Users, ChevronDown, ChevronRight, Activity, AlertCircle, CheckCircle } from 'lucide-react';
import { TimelineEvent, TimelineView as TimelineViewType } from '@/lib/types/analytics';
import { cn } from '@/lib/utils';

interface TimelineViewProps {
  events: TimelineEvent[];
  timeRange: 'hour' | 'day' | 'week' | 'month';
  onTimeRangeChange: (range: 'hour' | 'day' | 'week' | 'month') => void;
  loading?: boolean;
  className?: string;
}

export function TimelineView({ 
  events, 
  timeRange, 
  onTimeRangeChange, 
  loading = false,
  className 
}: TimelineViewProps) {
  const [expandedSections, setExpandedSections] = useState<Set<string>>(new Set());
  const [selectedEvent, setSelectedEvent] = useState<TimelineEvent | null>(null);

  // Group events by time period based on timeRange
  const groupedEvents = useMemo(() => {
    const groups = new Map<string, TimelineEvent[]>();
    
    events.forEach(event => {
      const eventDate = new Date(event.timestamp);
      let groupKey: string;
      
      switch (timeRange) {
        case 'hour':
          groupKey = eventDate.toISOString().substring(0, 13); // YYYY-MM-DDTHH
          break;
        case 'day':
          groupKey = eventDate.toISOString().substring(0, 10); // YYYY-MM-DD
          break;
        case 'week':
          const weekStart = new Date(eventDate);
          weekStart.setDate(eventDate.getDate() - eventDate.getDay());
          groupKey = `Week of ${weekStart.toISOString().substring(0, 10)}`;
          break;
        case 'month':
          groupKey = eventDate.toISOString().substring(0, 7); // YYYY-MM
          break;
        default:
          groupKey = eventDate.toISOString().substring(0, 10);
      }
      
      if (!groups.has(groupKey)) {
        groups.set(groupKey, []);
      }
      groups.get(groupKey)!.push(event);
    });
    
    // Sort events within each group by timestamp
    groups.forEach(group => {
      group.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
    });
    
    return groups;
  }, [events, timeRange]);

  // Calculate summary statistics
  const summary = useMemo(() => {
    const humanActivities = events.filter(e => e.isHumanActivity).length;
    const systemActivities = events.filter(e => !e.isHumanActivity).length;
    const totalHours = events.reduce((sum, e) => sum + (e.duration || 0), 0);
    const averageScore = events.length > 0 
      ? events.reduce((sum, e) => sum + (e.score || 0), 0) / events.length 
      : 0;
    
    return {
      totalEvents: events.length,
      humanActivities,
      systemActivities,
      totalHours,
      averageScore,
    };
  }, [events]);

  const toggleSection = (sectionKey: string) => {
    const newExpanded = new Set(expandedSections);
    if (newExpanded.has(sectionKey)) {
      newExpanded.delete(sectionKey);
    } else {
      newExpanded.add(sectionKey);
    }
    setExpandedSections(newExpanded);
  };

  const getEventIcon = (event: TimelineEvent) => {
    switch (event.type) {
      case 'key_moment':
        return <AlertCircle className="h-4 w-4 text-red-500" />;
      case 'milestone':
        return <CheckCircle className="h-4 w-4 text-green-500" />;
      case 'time_entry':
      default:
        if (event.isHumanActivity) {
          return <Users className="h-4 w-4 text-blue-500" />;
        } else {
          return <Activity className="h-4 w-4 text-gray-500" />;
        }
    }
  };

  const getImportanceColor = (importance: string) => {
    switch (importance) {
      case 'critical':
        return 'bg-red-100 text-red-800 border-red-200';
      case 'high':
        return 'bg-orange-100 text-orange-800 border-orange-200';
      case 'medium':
        return 'bg-yellow-100 text-yellow-800 border-yellow-200';
      case 'low':
      default:
        return 'bg-gray-100 text-gray-800 border-gray-200';
    }
  };

  const formatGroupTitle = (groupKey: string) => {
    switch (timeRange) {
      case 'hour':
        return new Date(groupKey + ':00:00').toLocaleString('en-US', {
          month: 'short',
          day: 'numeric',
          hour: 'numeric',
          hour12: true,
        });
      case 'day':
        return new Date(groupKey).toLocaleDateString('en-US', {
          weekday: 'long',
          month: 'long',
          day: 'numeric',
        });
      case 'week':
        return groupKey;
      case 'month':
        return new Date(groupKey + '-01').toLocaleDateString('en-US', {
          month: 'long',
          year: 'numeric',
        });
      default:
        return groupKey;
    }
  };

  if (loading) {
    return (
      <Card className={className}>
        <CardHeader>
          <CardTitle className="flex items-center gap-2">
            <Clock className="h-5 w-5" />
            Timeline View
          </CardTitle>
        </CardHeader>
        <CardContent>
          <div className="flex items-center justify-center h-64">
            <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600"></div>
          </div>
        </CardContent>
      </Card>
    );
  }

  return (
    <Card className={className}>
      <CardHeader>
        <div className="flex items-center justify-between">
          <CardTitle className="flex items-center gap-2">
            <Clock className="h-5 w-5" />
            Timeline View
          </CardTitle>
          
          <Select value={timeRange} onValueChange={onTimeRangeChange}>
            <SelectTrigger className="w-32">
              <SelectValue />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="hour">Hour</SelectItem>
              <SelectItem value="day">Day</SelectItem>
              <SelectItem value="week">Week</SelectItem>
              <SelectItem value="month">Month</SelectItem>
            </SelectContent>
          </Select>
        </div>
        
        {/* Summary Statistics */}
        <div className="grid grid-cols-2 md:grid-cols-5 gap-4 mt-4">
          <div className="text-center">
            <div className="text-2xl font-bold text-blue-600">{summary.totalEvents}</div>
            <div className="text-sm text-gray-600">Total Events</div>
          </div>
          <div className="text-center">
            <div className="text-2xl font-bold text-green-600">{summary.humanActivities}</div>
            <div className="text-sm text-gray-600">Human Activities</div>
          </div>
          <div className="text-center">
            <div className="text-2xl font-bold text-gray-600">{summary.systemActivities}</div>
            <div className="text-sm text-gray-600">System Activities</div>
          </div>
          <div className="text-center">
            <div className="text-2xl font-bold text-purple-600">{Number(summary.totalHours).toFixed(1)}</div>
            <div className="text-sm text-gray-600">Total Hours</div>
          </div>
          <div className="text-center">
            <div className="text-2xl font-bold text-orange-600">
              {(summary.averageScore * 100).toFixed(0)}%
            </div>
            <div className="text-sm text-gray-600">Avg Score</div>
          </div>
        </div>
      </CardHeader>
      
      <CardContent className="space-y-4">
        {groupedEvents.size === 0 ? (
          <div className="text-center py-8 text-gray-500">
            <Calendar className="h-12 w-12 mx-auto mb-4 opacity-50" />
            <p>No events found for the selected time range</p>
          </div>
        ) : (
          Array.from(groupedEvents.entries())
            .sort(([a], [b]) => b.localeCompare(a)) // Sort by date descending
            .map(([groupKey, groupEvents]) => (
              <Collapsible
                key={groupKey}
                open={expandedSections.has(groupKey)}
                onOpenChange={() => toggleSection(groupKey)}
              >
                <CollapsibleTrigger asChild>
                  <Button
                    variant="ghost"
                    className="w-full justify-between p-4 h-auto hover:bg-gray-50"
                  >
                    <div className="flex items-center gap-3">
                      {expandedSections.has(groupKey) ? (
                        <ChevronDown className="h-4 w-4" />
                      ) : (
                        <ChevronRight className="h-4 w-4" />
                      )}
                      <span className="font-medium">{formatGroupTitle(groupKey)}</span>
                      <Badge variant="secondary">{groupEvents.length} events</Badge>
                    </div>
                    
                    <div className="flex items-center gap-2 text-sm text-gray-600">
                      <span>
                        {groupEvents.filter(e => e.isHumanActivity).length} human
                      </span>
                      <span>•</span>
                      <span>
                        {groupEvents.reduce((sum, e) => sum + (Number(e.duration) || 0), 0).toFixed(1)}h
                      </span>
                    </div>
                  </Button>
                </CollapsibleTrigger>
                
                <CollapsibleContent className="space-y-2 px-4 pb-4">
                  {groupEvents.map((event) => (
                    <div
                      key={event.id}
                      className={cn(
                        "flex items-start gap-3 p-3 rounded-lg border transition-colors cursor-pointer",
                        selectedEvent?.id === event.id 
                          ? "border-blue-300 bg-blue-50" 
                          : "border-gray-200 hover:border-gray-300 hover:bg-gray-50",
                        !event.isHumanActivity && "opacity-60"
                      )}
                      onClick={() => setSelectedEvent(event)}
                    >
                      <div className="mt-0.5">
                        {getEventIcon(event)}
                      </div>
                      
                      <div className="flex-1 min-w-0">
                        <div className="flex items-center gap-2 mb-1">
                          <h4 className="font-medium truncate">{event.title}</h4>
                          <Badge 
                            variant="outline" 
                            className={cn("text-xs", getImportanceColor(event.importance))}
                          >
                            {event.importance}
                          </Badge>
                        </div>
                        
                        {event.description && (
                          <p className="text-sm text-gray-600 mb-2 line-clamp-2">
                            {event.description}
                          </p>
                        )}
                        
                        <div className="flex items-center gap-4 text-xs text-gray-500">
                          <span className="flex items-center gap-1">
                            <Clock className="h-3 w-3" />
                            {new Date(event.timestamp).toLocaleTimeString()}
                          </span>
                          
                          {event.duration && (
                            <span className="flex items-center gap-1">
                              <Activity className="h-3 w-3" />
                              {event.duration}h
                            </span>
                          )}
                          
                          {event.score && (
                            <span className="flex items-center gap-1">
                              <div className="w-8 h-2 bg-gray-200 rounded-full overflow-hidden">
                                <div 
                                  className="h-full bg-green-500"
                                  style={{ width: `${event.score * 100}%` }}
                                />
                              </div>
                              {(event.score * 100).toFixed(0)}%
                            </span>
                          )}
                        </div>
                      </div>
                    </div>
                  ))}
                </CollapsibleContent>
              </Collapsible>
            ))
        )}
      </CardContent>
    </Card>
  );
}
