'use client';

import { useState } from 'react';
import { useTranslations } from 'next-intl';
import { format, startOfMonth, endOfMonth, eachDayOfInterval, isSameMonth, isToday, isSameDay, addMonths, subMonths } from 'date-fns';
import { de, enUS } from 'date-fns/locale';
import { Calendar as CalendarIcon, ChevronLeft, ChevronRight } from 'lucide-react';
import { motion, AnimatePresence } from 'framer-motion';

import { cn } from '@/lib/utils';
import { Button } from '@/components/ui/button';
import { WidgetContainer } from '../widget-container';

interface CalendarEvent {
  id: string;
  title: string;
  date: Date;
  color?: string;
}

interface CalendarWidgetProps {
  id: string;
  isEditing?: boolean;
  onRemove?: () => void;
  events?: CalendarEvent[];
  locale?: string;
  className?: string;
}

/**
 * Calendar Widget - Mini calendar with event indicators
 */
export function CalendarWidget({
  id,
  isEditing = false,
  onRemove,
  events = [],
  locale = 'de',
  className,
}: CalendarWidgetProps) {
  const t = useTranslations('widgets.calendar');
  const [currentDate, setCurrentDate] = useState(new Date());
  const [selectedDate, setSelectedDate] = useState<Date | null>(null);

  const dateLocale = locale === 'de' ? de : enUS;

  const monthStart = startOfMonth(currentDate);
  const monthEnd = endOfMonth(currentDate);
  const days = eachDayOfInterval({ start: monthStart, end: monthEnd });

  // Get day names for header
  const dayNames = locale === 'de'
    ? ['Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa', 'So']
    : ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'];

  // Calculate padding days for alignment (week starts on Monday for German locale)
  const firstDayOffset = locale === 'de'
    ? (monthStart.getDay() + 6) % 7
    : monthStart.getDay();

  const paddingDays = Array.from({ length: firstDayOffset }, (_, i) => i);

  // Check if a day has events
  const getDayEvents = (date: Date) => events.filter((event) => isSameDay(event.date, date));

  const handlePrevMonth = () => setCurrentDate(subMonths(currentDate, 1));
  const handleNextMonth = () => setCurrentDate(addMonths(currentDate, 1));

  return (
    <WidgetContainer
      id={id}
      title={t('name')}
      icon={<CalendarIcon className="h-4 w-4 text-primary" />}
      isEditing={isEditing}
      onRemove={onRemove}
      className={className}
    >
      <div className="space-y-3">
        {/* Month Navigation */}
        <div className="flex items-center justify-between">
          <Button
            variant="ghost"
            size="icon"
            className="h-7 w-7"
            onClick={handlePrevMonth}
            disabled={isEditing}
          >
            <ChevronLeft className="h-4 w-4" />
          </Button>

          <AnimatePresence mode="wait">
            <motion.span
              key={format(currentDate, 'yyyy-MM')}
              initial={{ opacity: 0, y: -10 }}
              animate={{ opacity: 1, y: 0 }}
              exit={{ opacity: 0, y: 10 }}
              className="text-sm font-medium"
            >
              {format(currentDate, 'MMMM yyyy', { locale: dateLocale })}
            </motion.span>
          </AnimatePresence>

          <Button
            variant="ghost"
            size="icon"
            className="h-7 w-7"
            onClick={handleNextMonth}
            disabled={isEditing}
          >
            <ChevronRight className="h-4 w-4" />
          </Button>
        </div>

        {/* Day Names Header */}
        <div className="grid grid-cols-7 gap-1 text-center">
          {dayNames.map((day) => (
            <div key={day} className="text-xs font-medium text-muted-foreground py-1">
              {day}
            </div>
          ))}
        </div>

        {/* Calendar Grid */}
        <div className="grid grid-cols-7 gap-1">
          {/* Padding for first week alignment */}
          {paddingDays.map((i) => (
            <div key={`padding-${i}`} className="aspect-square" />
          ))}

          {/* Actual days */}
          {days.map((day) => {
            const dayEvents = getDayEvents(day);
            const hasEvents = dayEvents.length > 0;
            const isSelected = selectedDate && isSameDay(day, selectedDate);

            return (
              <button
                key={day.toISOString()}
                onClick={() => setSelectedDate(day)}
                disabled={isEditing}
                className={cn(
                  'relative aspect-square rounded-md text-xs transition-colors',
                  'hover:bg-accent focus:outline-none focus:ring-1 focus:ring-ring',
                  isToday(day) && 'bg-primary text-primary-foreground hover:bg-primary/90',
                  isSelected && !isToday(day) && 'bg-accent',
                  !isSameMonth(day, currentDate) && 'text-muted-foreground/50'
                )}
              >
                {format(day, 'd')}

                {/* Event indicator dot */}
                {hasEvents && (
                  <span
                    className={cn(
                      'absolute bottom-1 left-1/2 h-1 w-1 -translate-x-1/2 rounded-full',
                      isToday(day) ? 'bg-primary-foreground' : 'bg-primary'
                    )}
                  />
                )}
              </button>
            );
          })}
        </div>

        {/* Selected date events */}
        {selectedDate && getDayEvents(selectedDate).length > 0 && (
          <motion.div
            initial={{ opacity: 0, height: 0 }}
            animate={{ opacity: 1, height: 'auto' }}
            className="border-t pt-2"
          >
            <p className="mb-1 text-xs font-medium">
              {format(selectedDate, 'd. MMMM', { locale: dateLocale })}
            </p>
            <div className="space-y-1">
              {getDayEvents(selectedDate).slice(0, 3).map((event) => (
                <div
                  key={event.id}
                  className="flex items-center gap-2 text-xs"
                >
                  <span
                    className="h-2 w-2 rounded-full"
                    style={{ backgroundColor: event.color || 'hsl(var(--primary))' }}
                  />
                  <span className="truncate">{event.title}</span>
                </div>
              ))}
            </div>
          </motion.div>
        )}
      </div>
    </WidgetContainer>
  );
}
