import { Calendar as CalendarIcon } from 'lucide-react';

import { useState } from 'react';

import { Calendar } from '@/Components/ui/calendar';
import { Card, CardContent, CardHeader, CardTitle } from '@/Components/ui/card';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/Components/ui/tabs';
import { cn } from '@/lib/utils';

export interface CalendarEntry {
  id: number;
  title: string;
  description: string | null;
  due_date: string;
  scheduled_date: string | null;
  status: 'planned' | 'in_progress' | 'completed' | 'overdue';
  source_type: string | null;
  source_id: number | null;
  page_url: string | null;
  metadata: Record<string, unknown> | null;
}

type ViewMode = 'month' | 'week' | 'day';

interface CalendarViewProps {
  entries?: CalendarEntry[];
  selectedDate?: Date;
  onDateSelect?: (date: Date | undefined) => void;
  onViewChange?: (view: ViewMode) => void;
  onReschedule?: (entryId: number, newDate: string) => void;
  className?: string;
}

interface DayEntriesProps {
  date: Date;
  entries: CalendarEntry[];
  onReschedule?: (entryId: number, newDate: string) => void;
}

function DayEntries({ date, entries, onReschedule }: DayEntriesProps) {
  const dateStr = date.toISOString().split('T')[0];
  const dayEntries = entries.filter((entry) => {
    const entryDate = new Date(entry.due_date).toISOString().split('T')[0];
    return entryDate === dateStr;
  });

  const handleDragStart = (e: React.DragEvent, entryId: number) => {
    e.dataTransfer.effectAllowed = 'move';
    e.dataTransfer.setData('entryId', entryId.toString());
  };

  if (dayEntries.length === 0) {
    return null;
  }

  return (
    <div className="mt-1 space-y-1">
      {dayEntries.map((entry) => (
        <div
          key={entry.id}
          draggable={!!onReschedule}
          onDragStart={(e) => handleDragStart(e, entry.id)}
          data-testid={`calendar-entry-${entry.id}`}
          className={cn(
            'rounded px-1 py-0.5 text-xs truncate',
            onReschedule && 'cursor-move',
            entry.status === 'completed' &&
              'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200',
            entry.status === 'in_progress' &&
              'bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200',
            entry.status === 'planned' &&
              'bg-muted text-foreground',
            entry.status === 'overdue' &&
              'bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200',
          )}
        >
          {entry.title}
        </div>
      ))}
    </div>
  );
}

function MonthView({
  entries,
  selectedDate,
  onDateSelect,
}: {
  entries: CalendarEntry[];
  selectedDate: Date;
  onDateSelect: (date: Date | undefined) => void;
}) {
  return (
    <div className="space-y-4">
      <Calendar
        mode="single"
        selected={selectedDate}
        onSelect={onDateSelect}
        defaultMonth={selectedDate}
        className="rounded-md border"
      />
      {entries.length > 0 && (
        <div className="grid grid-cols-7 gap-2">
          {/* Calendar grid overlays would go here in a more advanced implementation */}
        </div>
      )}
    </div>
  );
}

function WeekView({
  entries,
  selectedDate,
  onReschedule,
}: {
  entries: CalendarEntry[];
  selectedDate: Date;
  onReschedule?: (entryId: number, newDate: string) => void;
}) {
  const [dragOverDate, setDragOverDate] = useState<string | null>(null);

  const startOfWeek = new Date(selectedDate);
  startOfWeek.setDate(selectedDate.getDate() - selectedDate.getDay());

  const weekDays = Array.from({ length: 7 }, (_, i) => {
    const day = new Date(startOfWeek);
    day.setDate(startOfWeek.getDate() + i);
    return day;
  });

  const handleDragOver = (e: React.DragEvent, dateStr: string) => {
    e.preventDefault();
    e.dataTransfer.dropEffect = 'move';
    setDragOverDate(dateStr);
  };

  const handleDragLeave = () => {
    setDragOverDate(null);
  };

  const handleDrop = (e: React.DragEvent, dateStr: string) => {
    e.preventDefault();
    setDragOverDate(null);

    const entryId = parseInt(e.dataTransfer.getData('entryId'), 10);
    if (entryId && onReschedule) {
      onReschedule(entryId, dateStr);
    }
  };

  return (
    <div className="grid grid-cols-7 gap-2">
      {weekDays.map((day, index) => {
        const dateStr = day.toISOString().split('T')[0];
        const isDragOver = dragOverDate === dateStr;

        return (
          <div
            key={index}
            data-testid={`week-day-${dateStr}`}
            onDragOver={onReschedule ? (e) => handleDragOver(e, dateStr) : undefined}
            onDragLeave={onReschedule ? handleDragLeave : undefined}
            onDrop={onReschedule ? (e) => handleDrop(e, dateStr) : undefined}
            className={cn(
              'border rounded-md p-2 transition-colors',
              isDragOver && 'bg-blue-50 dark:bg-blue-950 border-blue-300 dark:border-blue-700',
            )}
          >
            <div className="font-medium text-sm text-center mb-2">
              {day.toLocaleDateString('en-US', {
                weekday: 'short',
                month: 'short',
                day: 'numeric',
              })}
            </div>
            <DayEntries date={day} entries={entries} onReschedule={onReschedule} />
          </div>
        );
      })}
    </div>
  );
}

function DayView({ entries, selectedDate }: { entries: CalendarEntry[]; selectedDate: Date }) {
  const dateStr = selectedDate.toISOString().split('T')[0];
  const dayEntries = entries.filter((entry) => {
    const entryDate = new Date(entry.due_date).toISOString().split('T')[0];
    return entryDate === dateStr;
  });

  return (
    <div className="space-y-4">
      <div className="text-lg font-semibold">
        {selectedDate.toLocaleDateString('en-US', {
          weekday: 'long',
          year: 'numeric',
          month: 'long',
          day: 'numeric',
        })}
      </div>
      {dayEntries.length === 0 ? (
        <div className="text-center py-12 text-muted-foreground">
          No tasks scheduled for this day
        </div>
      ) : (
        <div className="space-y-3">
          {dayEntries.map((entry) => (
            <Card key={entry.id}>
              <CardContent className="p-4">
                <div className="flex items-start justify-between">
                  <div className="flex-1">
                    <div className="font-medium">{entry.title}</div>
                    {entry.description && (
                      <div className="text-sm text-muted-foreground mt-1">{entry.description}</div>
                    )}
                    {entry.page_url && (
                      <div className="text-sm text-muted-foreground mt-1 truncate">
                        {entry.page_url}
                      </div>
                    )}
                  </div>
                  <div
                    className={cn(
                      'px-2 py-1 rounded text-xs font-medium',
                      entry.status === 'completed' &&
                        'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200',
                      entry.status === 'in_progress' &&
                        'bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200',
                      entry.status === 'planned' &&
                        'bg-muted text-foreground',
                      entry.status === 'overdue' &&
                        'bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200',
                    )}
                  >
                    {entry.status.replace('_', ' ')}
                  </div>
                </div>
              </CardContent>
            </Card>
          ))}
        </div>
      )}
    </div>
  );
}

export default function CalendarView({
  entries = [],
  selectedDate: initialDate,
  onDateSelect,
  onViewChange,
  onReschedule,
  className,
}: CalendarViewProps) {
  const [selectedDate, setSelectedDate] = useState<Date>(initialDate ?? new Date());
  const [viewMode, setViewMode] = useState<ViewMode>('month');

  const handleDateSelect = (date: Date | undefined) => {
    if (date) {
      setSelectedDate(date);
      onDateSelect?.(date);
    }
  };

  const handleViewChange = (value: string) => {
    const view = value as ViewMode;
    setViewMode(view);
    onViewChange?.(view);
  };

  return (
    <Card className={cn('', className)}>
      <CardHeader>
        <div className="flex items-center justify-between">
          <CardTitle className="flex items-center gap-2">
            <CalendarIcon className="h-5 w-5" />
            SEO Calendar
          </CardTitle>
          <Tabs value={viewMode} onValueChange={handleViewChange}>
            <TabsList>
              <TabsTrigger value="month">Month</TabsTrigger>
              <TabsTrigger value="week">Week</TabsTrigger>
              <TabsTrigger value="day">Day</TabsTrigger>
            </TabsList>
          </Tabs>
        </div>
      </CardHeader>
      <CardContent>
        <Tabs value={viewMode} onValueChange={handleViewChange}>
          <TabsContent value="month" className="mt-0">
            <MonthView
              entries={entries}
              selectedDate={selectedDate}
              onDateSelect={handleDateSelect}
            />
          </TabsContent>
          <TabsContent value="week" className="mt-0">
            <WeekView entries={entries} selectedDate={selectedDate} onReschedule={onReschedule} />
          </TabsContent>
          <TabsContent value="day" className="mt-0">
            <DayView entries={entries} selectedDate={selectedDate} />
          </TabsContent>
        </Tabs>
      </CardContent>
    </Card>
  );
}
