import { useState } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { toast } from 'sonner';
import FullCalendar from '@fullcalendar/react';
import dayGridPlugin from '@fullcalendar/daygrid';
import timeGridPlugin from '@fullcalendar/timegrid';
import interactionPlugin from '@fullcalendar/interaction';
import type { EventClickArg, DateSelectArg, EventDropArg } from '@fullcalendar/core';
import api, { getErrorMessage } from '@/lib/api';
import type { CalendarEvent } from '@/types';
import EventForm from './EventForm';

export default function CalendarPage() {
  const queryClient = useQueryClient();
  const [showForm, setShowForm] = useState(false);
  const [editingEvent, setEditingEvent] = useState<CalendarEvent | null>(null);
  const [selectedDate, setSelectedDate] = useState<string | null>(null);

  const { data: events = [] } = useQuery({
    queryKey: ['calendar-events'],
    queryFn: async () => {
      const { data } = await api.get<CalendarEvent[]>('/events');
      return data;
    },
  });

  const eventDropMutation = useMutation({
    mutationFn: async ({ id, start, end, allDay }: { id: number; start: string; end: string; allDay: boolean }) => {
      const response = await api.put(`/events/${id}`, {
        start_datetime: start,
        end_datetime: end,
        all_day: allDay,
      });
      return response.data;
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['calendar-events'] });
      toast.success('Event moved');
    },
    onError: (error) => {
      queryClient.invalidateQueries({ queryKey: ['calendar-events'] });
      toast.error(getErrorMessage(error, 'Failed to move event'));
    },
  });

  const calendarEvents = events.map((event) => ({
    id: event.id.toString(),
    title: event.title,
    start: event.start_datetime,
    end: event.end_datetime || undefined,
    allDay: event.all_day,
    backgroundColor: event.color || 'hsl(var(--accent-color))',
    borderColor: event.color || 'hsl(var(--accent-color))',
  }));

  const handleEventClick = (info: EventClickArg) => {
    const event = events.find((e) => e.id.toString() === info.event.id);
    if (event) {
      setEditingEvent(event);
      setShowForm(true);
    }
  };

  const toLocalDatetime = (d: Date): string => {
    const pad = (n: number) => n.toString().padStart(2, '0');
    return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;
  };

  const handleEventDrop = (info: EventDropArg) => {
    const id = parseInt(info.event.id);
    const start = info.event.allDay
      ? info.event.startStr
      : info.event.start ? toLocalDatetime(info.event.start) : info.event.startStr;
    const end = info.event.allDay
      ? info.event.endStr || info.event.startStr
      : info.event.end ? toLocalDatetime(info.event.end) : start;
    eventDropMutation.mutate({ id, start, end, allDay: info.event.allDay });
  };

  const handleDateSelect = (selectInfo: DateSelectArg) => {
    setSelectedDate(selectInfo.startStr);
    setShowForm(true);
  };

  const handleCloseForm = () => {
    setShowForm(false);
    setEditingEvent(null);
    setSelectedDate(null);
  };

  return (
    <div className="flex flex-col h-full">
      <div className="border-b bg-card px-6 py-4">
        <h1 className="text-3xl font-bold">Calendar</h1>
      </div>

      <div className="flex-1 overflow-y-auto p-6">
        <div className="bg-card rounded-lg border p-4">
          <FullCalendar
            plugins={[dayGridPlugin, timeGridPlugin, interactionPlugin]}
            initialView="dayGridMonth"
            headerToolbar={{
              left: 'prev,next today',
              center: 'title',
              right: 'dayGridMonth,timeGridWeek,timeGridDay',
            }}
            events={calendarEvents}
            editable={true}
            selectable={true}
            selectMirror={true}
            dayMaxEvents={true}
            weekends={true}
            eventClick={handleEventClick}
            eventDrop={handleEventDrop}
            select={handleDateSelect}
            height="auto"
          />
        </div>
      </div>

      {showForm && (
        <EventForm event={editingEvent} initialDate={selectedDate} onClose={handleCloseForm} />
      )}
    </div>
  );
}
