import { useState, useRef } from 'react';
import { useTranslation } from 'react-i18next';
import { Card } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { ChevronLeft, ChevronRight, Calendar, Edit, Timer, CheckCircle, Play, Clock, Trash2 } from 'lucide-react';
import { Task, Label } from '@shared/schema';
import { useQuery } from '@tanstack/react-query';
import { addDays, format, isSameDay, startOfWeek, subWeeks, startOfDay } from 'date-fns';
import { de, enUS } from 'date-fns/locale';
import {
  ContextMenu,
  ContextMenuContent,
  ContextMenuItem,
  ContextMenuSeparator,
  ContextMenuTrigger,
} from "@/components/ui/context-menu";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import {
  HoverCard,
  HoverCardContent,
  HoverCardTrigger,
} from "@/components/ui/hover-card";


interface CalendarViewProps {
  tasks: Task[];
  onTaskDrop?: (taskId: string, newDate: Date) => void;
  onTaskClick?: (task: Task) => void;
  onDateSelect?: (date: Date) => void;
  onTaskUpdate?: (taskId: string, updates: Partial<Task>) => void;
  onTaskEdit?: (task: Task) => void;
  onTaskDelete?: (taskId: string) => void;
  onStartTimer?: (taskId: string) => void;
  onStopTimer?: (taskId: string) => void;
}

export default function CalendarView({ tasks, onTaskDrop, onTaskClick, onDateSelect, onTaskUpdate, onTaskEdit, onTaskDelete, onStartTimer, onStopTimer }: CalendarViewProps) {
  const { t, i18n } = useTranslation();
  const [currentDate, setCurrentDate] = useState(new Date());
  const [draggedTask, setDraggedTask] = useState<string | null>(null);
  const [longPressTask, setLongPressTask] = useState<Task | null>(null);
  const longPressTimerRef = useRef<NodeJS.Timeout | null>(null);
  const [dropdownOpen, setDropdownOpen] = useState(false);
  const longPressTriggered = useRef(false);

  // Get date-fns locale based on current language
  const dateLocale = i18n.language === 'de' ? de : enUS;

  // Fetch labels to get label colors
  const { data: labels = [] } = useQuery<Label[]>({
    queryKey: ['/api/labels'],
    staleTime: 5 * 60 * 1000, // 5 minutes cache
    refetchOnWindowFocus: false,
  });

  // Get 5 weeks: 1 previous week (grayed out) + current week + 3 future weeks
  const currentWeekStart = startOfWeek(currentDate, { weekStartsOn: 1 }); // Monday = 1
  const startDate = subWeeks(currentWeekStart, 1); // Start from 1 week before current week
  const dates = Array.from({ length: 35 }, (_, i) => addDays(startDate, i));

  const getTasksForDate = (date: Date) => {
    return tasks.filter(task => {
      // Handle multi-day tasks
      if (task.startDate && task.dueDate) {
        const start = startOfDay(new Date(task.startDate));
        const end = startOfDay(new Date(task.dueDate));
        const current = startOfDay(date);
        return current >= start && current <= end;
      }

      // Handle single date tasks (dueDate or startDate)
      if (task.dueDate) {
        return isSameDay(new Date(task.dueDate), date);
      }
      if (task.startDate) { // Fallback if only start date exists
        return isSameDay(new Date(task.startDate), date);
      }
      return false;
    });
  };

  const handleDragStart = (taskId: string) => {
    setDraggedTask(taskId);
    console.log('Drag started for task:', taskId);
  };

  const handleDragEnd = () => {
    setDraggedTask(null);
  };

  const handleDrop = (date: Date) => {
    if (draggedTask) {
      onTaskDrop?.(draggedTask, date);
      console.log(`Task ${draggedTask} dropped on`, date.toLocaleDateString());
      setDraggedTask(null);
    }
  };

  const handleDragOver = (e: React.DragEvent) => {
    e.preventDefault();
  };

  const navigateWeek = (direction: 'prev' | 'next') => {
    const newDate = addDays(currentDate, direction === 'next' ? 7 : -7);
    setCurrentDate(newDate);
    console.log(`Navigating to week of ${newDate.toLocaleDateString()}`);
  };

  // Long press handlers for mobile
  const handleTouchStart = (task: Task) => {
    // Clear any existing timeout
    if (longPressTimerRef.current) {
      clearTimeout(longPressTimerRef.current);
    }

    longPressTriggered.current = false;

    longPressTimerRef.current = setTimeout(() => {
      longPressTriggered.current = true;
      setLongPressTask(task);
      setDropdownOpen(true);
      console.log('Long press detected for task:', task.title);

      // Reset after a delay to allow next click
      setTimeout(() => {
        longPressTriggered.current = false;
      }, 300);
    }, 500); // 500ms long press threshold
  };

  const handleTouchEnd = () => {
    if (longPressTimerRef.current) {
      clearTimeout(longPressTimerRef.current);
      longPressTimerRef.current = null;
    }
  };

  const handleTaskClick = (task: Task, e: React.MouseEvent | React.TouchEvent) => {
    // Prevent click when dragging
    if (draggedTask === task.id) return;

    // Skip click if long press was just triggered
    if (longPressTriggered.current) {
      e.preventDefault();
      return;
    }

    e.stopPropagation();
    onTaskClick?.(task);
    console.log('Calendar task clicked:', task.title);
  };

  // Menu content component to avoid duplication
  const TaskMenuContent = ({ task, closeMenu }: { task: Task; closeMenu?: () => void }) => (
    <>
      <ContextMenuItem
        onClick={(e) => {
          e.stopPropagation();
          onTaskEdit?.(task);
          closeMenu?.();
        }}
        data-testid={`context-menu-edit-${task.id}`}
      >
        <Edit className="w-4 h-4 mr-2" />
        {t('taskCard.editTask')}
      </ContextMenuItem>

      <ContextMenuItem
        onClick={(e) => {
          e.stopPropagation();
          if (task.isTracking) {
            onStopTimer?.(task.id);
          } else {
            onStartTimer?.(task.id);
          }
          closeMenu?.();
        }}
        data-testid={`context-menu-timer-${task.id}`}
      >
        <Timer className="w-4 h-4 mr-2" />
        {task.isTracking ? t('taskCard.stopTimer') : t('taskCard.startTimer')}
      </ContextMenuItem>

      <ContextMenuSeparator />

      {task.status !== 'done' && (
        <ContextMenuItem
          onClick={(e) => {
            e.stopPropagation();
            onTaskUpdate?.(task.id, { status: 'done' });
            closeMenu?.();
          }}
          data-testid={`context-menu-complete-${task.id}`}
        >
          <CheckCircle className="w-4 h-4 mr-2" />
          {t('taskCard.markAsDone')}
        </ContextMenuItem>
      )}

      {task.status === 'todo' && (
        <ContextMenuItem
          onClick={(e) => {
            e.stopPropagation();
            onTaskUpdate?.(task.id, { status: 'inProgress' });
            closeMenu?.();
          }}
          data-testid={`context-menu-start-${task.id}`}
        >
          <Play className="w-4 h-4 mr-2" />
          {t('taskCard.startWorking')}
        </ContextMenuItem>
      )}

      {task.status === 'inProgress' && (
        <ContextMenuItem
          onClick={(e) => {
            e.stopPropagation();
            onTaskUpdate?.(task.id, { status: 'todo' });
            closeMenu?.();
          }}
          data-testid={`context-menu-todo-${task.id}`}
        >
          <Clock className="w-4 h-4 mr-2" />
          {t('taskCard.moveToTodo')}
        </ContextMenuItem>
      )}

      {task.status === 'done' && (
        <ContextMenuItem
          onClick={(e) => {
            e.stopPropagation();
            onTaskUpdate?.(task.id, { status: 'inProgress' });
            closeMenu?.();
          }}
          data-testid={`context-menu-reopen-${task.id}`}
        >
          <Play className="w-4 h-4 mr-2" />
          {t('taskCard.reopenTask')}
        </ContextMenuItem>
      )}

      <ContextMenuSeparator />

      {onTaskDelete && (
        <ContextMenuItem
          onClick={(e) => {
            e.stopPropagation();
            onTaskDelete(task.id);
            closeMenu?.();
          }}
          className="text-destructive"
          data-testid={`context-menu-delete-${task.id}`}
        >
          <Trash2 className="w-4 h-4 mr-2" />
          {t('taskCard.deleteTask')}
        </ContextMenuItem>
      )}
    </>
  );

  return (
    <div className="space-y-4">
      {/* Header */}
      <div className="sticky top-0 z-40 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60 border-b pb-2 sm:pb-3 mb-3 sm:mb-4 pt-4">
        <div className="flex items-center justify-between">
          <div className="flex items-center gap-2">
            <Calendar className="w-4 h-4 sm:w-5 sm:h-5 text-primary" />
            <h2 className="text-base sm:text-lg font-semibold" data-testid="text-calendar-title">
              {t('calendar.title')}
            </h2>
            <Badge variant="outline" className="ml-2 text-xs font-normal text-muted-foreground inline-flex">
              {t('analytics.cw')} {format(currentDate, 'w', { locale: dateLocale })}
            </Badge>
          </div>

          <div className="flex items-center gap-2">
            <Button
              variant="outline"
              size="icon"
              onClick={() => navigateWeek('prev')}
              data-testid="button-prev-week"
              className="h-11 w-11"
            >
              <ChevronLeft className="w-4 h-4" />
            </Button>

            <Button
              variant="outline"
              size="icon"
              onClick={() => navigateWeek('next')}
              data-testid="button-next-week"
              className="h-11 w-11"
            >
              <ChevronRight className="w-4 h-4" />
            </Button>
          </div>
        </div>
      </div>

      {/* Calendar Grid */}
      <div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-5 lg:grid-cols-7 gap-2 sm:gap-3">
        {dates.map((date, index) => {
          const dayTasks = getTasksForDate(date);
          const isToday = isSameDay(date, new Date());
          const isWeekend = date.getDay() === 0 || date.getDay() === 6;
          const isMonday = date.getDay() === 1;
          const isPreviousWeek = index < 7; // First 7 days are the previous week

          return (
            <Card
              key={index}
              className={`p-2 sm:p-3 min-h-[100px] sm:min-h-[120px] hover-elevate active-elevate-2 transition-all ${isToday ? 'ring-2 ring-primary' : ''
                } ${isWeekend ? 'bg-muted/30' : ''
                } ${isPreviousWeek ? 'opacity-50 bg-muted/60' : ''
                }`}
              onDragOver={handleDragOver}
              onDrop={() => handleDrop(date)}
              onClick={() => {
                onDateSelect?.(date);
                console.log('Date selected:', date.toLocaleDateString());
              }}
              data-testid={`calendar-date-${format(date, 'yyyy-MM-dd')}`}
            >
              <div className="text-center mb-2 relative">
                {isMonday && (
                  <span className="absolute left-0 top-0 text-[10px] text-muted-foreground/70 font-mono">
                    {t('analytics.cw')} {format(date, 'w', { locale: dateLocale })}
                  </span>
                )}
                <div className={`text-xs font-medium ${isPreviousWeek ? 'text-muted-foreground/60' : 'text-muted-foreground'
                  }`}>
                  {format(date, 'EEE', { locale: dateLocale })}
                </div>
                <div className={`text-sm font-semibold ${isToday ? 'text-primary' : isPreviousWeek ? 'text-muted-foreground/60' : ''
                  }`}>
                  {format(date, 'd', { locale: dateLocale })}
                </div>
              </div>

              <div className="space-y-1">
                {dayTasks.slice(0, 3).map((task, taskIndex) => {
                  // Find the label for this task
                  const taskLabel = task.labelId && labels.length > 0 ? labels.find(label => label.id === task.labelId) : null;

                  return (
                    <ContextMenu key={task.id}>
                      <ContextMenuTrigger asChild>
                        <div
                          draggable
                          onDragStart={() => handleDragStart(task.id)}
                          onDragEnd={handleDragEnd}
                          onTouchStart={() => handleTouchStart(task)}
                          onTouchEnd={handleTouchEnd}
                          onTouchMove={handleTouchEnd}
                          onClick={(e) => handleTaskClick(task, e)}
                          className={`cursor-pointer hover-elevate ${draggedTask === task.id ? 'opacity-50' : ''}`}
                          data-testid={`calendar-task-${task.id}`}
                        >
                          <Badge
                            variant="outline"
                            className="w-full justify-start text-xs p-1 h-auto"
                            style={taskLabel ? {
                              borderColor: taskLabel.color,
                              borderWidth: '2px',
                              borderStyle: 'solid'
                            } : {}}
                          >
                            <div className="truncate flex-1 text-left pointer-events-none">
                              {task.title}
                            </div>
                          </Badge>
                        </div>
                      </ContextMenuTrigger>
                      <ContextMenuContent>
                        <TaskMenuContent task={task} />
                      </ContextMenuContent>
                    </ContextMenu>
                  );
                })}

                {dayTasks.length > 3 && (
                  <HoverCard openDelay={0} closeDelay={100}>
                    <HoverCardTrigger asChild>
                      <Badge variant="secondary" className="w-full justify-center text-xs cursor-pointer hover:bg-secondary/80">
                        {t('calendar.moreItems', { count: dayTasks.length - 3 })}
                      </Badge>
                    </HoverCardTrigger>
                    <HoverCardContent className="w-72 p-0">
                      <div className="p-3 border-b bg-muted/30">
                        <h4 className="font-semibold text-xs text-muted-foreground flex items-center justify-between">
                          <span>{t('calendar.moreItems', { count: dayTasks.length - 3 })}</span>
                          <span className="text-[10px] font-normal opacity-75">Click to edit</span>
                        </h4>
                      </div>
                      <div className="max-h-[300px] overflow-y-auto p-2 space-y-1">
                        {dayTasks.slice(3).map(task => {
                          const taskLabel = task.labelId && labels.length > 0 ? labels.find(label => label.id === task.labelId) : null;
                          return (
                            <div
                              key={task.id}
                              className="p-2 border rounded hover:bg-accent cursor-pointer flex items-center justify-between group transition-colors"
                              onClick={(e) => {
                                e.stopPropagation();
                                onTaskEdit?.(task);
                              }}
                            >
                              <div className="min-w-0 flex-1 mr-2">
                                <div className="text-xs font-medium truncate">{task.title}</div>
                                {taskLabel && (
                                  <div className="flex items-center gap-1 mt-1">
                                    <div className="w-2 h-2 rounded-full" style={{ backgroundColor: taskLabel.color }} />
                                    <span className="text-[10px] text-muted-foreground truncate max-w-[100px]">{taskLabel.name}</span>
                                  </div>
                                )}
                              </div>
                              <Button size="icon" variant="ghost" className="h-6 w-6 opacity-0 group-hover:opacity-100 shrink-0" onClick={(e) => {
                                e.stopPropagation();
                                onTaskEdit?.(task);
                              }}>
                                <Edit className="w-3 h-3" />
                              </Button>
                            </div>
                          )
                        })}
                      </div>
                    </HoverCardContent>
                  </HoverCard>
                )}
              </div>
            </Card>
          );
        })}
      </div>

      {/* Legend */}
      <div className="flex items-center gap-4 text-xs text-muted-foreground">
        <div className="flex items-center gap-2">
          <div className="w-3 h-3 rounded-full bg-primary"></div>
          <span>{t('calendar.today')}</span>
        </div>
        <div className="flex items-center gap-2">
          <div className="w-3 h-3 rounded-full bg-muted"></div>
          <span>{t('calendar.weekend')}</span>
        </div>
        <div className="flex items-center gap-2">
          <div className="w-3 h-3 rounded-full bg-muted opacity-50"></div>
          <span>{t('calendar.previousWeek')}</span>
        </div>
      </div>

      {/* Mobile long-press fallback menu */}
      {longPressTask && (
        <DropdownMenu
          open={dropdownOpen}
          onOpenChange={(open) => {
            setDropdownOpen(open);
            if (!open) {
              setLongPressTask(null);
            }
          }}
        >
          <DropdownMenuTrigger className="hidden" />
          <DropdownMenuContent>
            <DropdownMenuItem
              onClick={(e) => {
                e.stopPropagation();
                onTaskEdit?.(longPressTask);
                setDropdownOpen(false);
              }}
              data-testid={`dropdown-menu-edit-${longPressTask.id}`}
            >
              <Edit className="w-4 h-4 mr-2" />
              {t('taskCard.editTask')}
            </DropdownMenuItem>

            <DropdownMenuItem
              onClick={(e) => {
                e.stopPropagation();
                if (longPressTask.isTracking) {
                  onStopTimer?.(longPressTask.id);
                } else {
                  onStartTimer?.(longPressTask.id);
                }
                setDropdownOpen(false);
              }}
              data-testid={`dropdown-menu-timer-${longPressTask.id}`}
            >
              <Timer className="w-4 h-4 mr-2" />
              {longPressTask.isTracking ? t('taskCard.stopTimer') : t('taskCard.startTimer')}
            </DropdownMenuItem>

            <DropdownMenuSeparator />

            {longPressTask.status !== 'done' && (
              <DropdownMenuItem
                onClick={(e) => {
                  e.stopPropagation();
                  onTaskUpdate?.(longPressTask.id, { status: 'done' });
                  setDropdownOpen(false);
                }}
                data-testid={`dropdown-menu-complete-${longPressTask.id}`}
              >
                <CheckCircle className="w-4 h-4 mr-2" />
                {t('taskCard.markAsDone')}
              </DropdownMenuItem>
            )}

            {longPressTask.status === 'todo' && (
              <DropdownMenuItem
                onClick={(e) => {
                  e.stopPropagation();
                  onTaskUpdate?.(longPressTask.id, { status: 'inProgress' });
                  setDropdownOpen(false);
                }}
                data-testid={`dropdown-menu-start-${longPressTask.id}`}
              >
                <Play className="w-4 h-4 mr-2" />
                {t('taskCard.startWorking')}
              </DropdownMenuItem>
            )}

            {longPressTask.status === 'inProgress' && (
              <DropdownMenuItem
                onClick={(e) => {
                  e.stopPropagation();
                  onTaskUpdate?.(longPressTask.id, { status: 'todo' });
                  setDropdownOpen(false);
                }}
                data-testid={`dropdown-menu-todo-${longPressTask.id}`}
              >
                <Clock className="w-4 h-4 mr-2" />
                {t('taskCard.moveToTodo')}
              </DropdownMenuItem>
            )}

            {longPressTask.status === 'done' && (
              <DropdownMenuItem
                onClick={(e) => {
                  e.stopPropagation();
                  onTaskUpdate?.(longPressTask.id, { status: 'inProgress' });
                  setDropdownOpen(false);
                }}
                data-testid={`dropdown-menu-reopen-${longPressTask.id}`}
              >
                <Play className="w-4 h-4 mr-2" />
                {t('taskCard.reopenTask')}
              </DropdownMenuItem>
            )}

            <DropdownMenuSeparator />

            {onTaskDelete && (
              <DropdownMenuItem
                onClick={(e) => {
                  e.stopPropagation();
                  onTaskDelete(longPressTask.id);
                  setDropdownOpen(false);
                }}
                className="text-destructive"
                data-testid={`dropdown-menu-delete-${longPressTask.id}`}
              >
                <Trash2 className="w-4 h-4 mr-2" />
                {t('taskCard.deleteTask')}
              </DropdownMenuItem>
            )}
          </DropdownMenuContent>
        </DropdownMenu>
      )}
    </div>
  );
}