import { useState, useEffect, useCallback } from "react";
import {
  format,
  addMonths,
  subMonths,
  addWeeks,
  subWeeks,
  addDays,
  subDays,
  startOfMonth,
  endOfMonth,
  startOfWeek,
  endOfWeek,
} from "date-fns";
import type { Calendar, CalendarEvent, ViewMode } from "../types";
import { api } from "../api";
import MonthView from "../components/MonthView";
import WeekView from "../components/WeekView";
import DayView from "../components/DayView";
import EventModal from "../components/EventModal";
import CalendarModal from "../components/CalendarModal";
import AddCalendarUrlModal from "../components/AddCalendarUrlModal";
import MiniCalendar from "../components/MiniCalendar";
import { useAuth } from "../context/AuthContext";
import { useTheme } from "../context/ThemeContext";

export default function CalendarPage() {
  const { user, logout } = useAuth();
  const { theme, toggle } = useTheme();
  const [currentDate, setCurrentDate] = useState(new Date());
  const [viewMode, setViewMode] = useState<ViewMode>("month");
  const [calendars, setCalendars] = useState<Calendar[]>([]);
  const [events, setEvents] = useState<CalendarEvent[]>([]);
  const [visibleCalendarIds, setVisibleCalendarIds] = useState<Set<string>>(
    new Set(),
  );
  const [sidebarOpen, setSidebarOpen] = useState(true);
  const [eventModalOpen, setEventModalOpen] = useState(false);
  const [calendarModalOpen, setCalendarModalOpen] = useState(false);
  const [addUrlModalOpen, setAddUrlModalOpen] = useState(false);
  const [selectedEvent, setSelectedEvent] = useState<CalendarEvent | null>(null);
  const [editingCalendar, setEditingCalendar] = useState<Calendar | null>(null);
  const [defaultEventDate, setDefaultEventDate] = useState<Date | undefined>();
  const [userMenuOpen, setUserMenuOpen] = useState(false);
  const [loading, setLoading] = useState(true);

  const loadCalendars = useCallback(async () => {
    try {
      const data = await api.listCalendars();
      const cals = data.items || [];
      setCalendars(cals);
      setVisibleCalendarIds((prev) => {
        if (prev.size === 0) return new Set(cals.map((c) => c.id));
        // Add newly added calendars (e.g. from URL) to visible by default
        const next = new Set(prev);
        for (const c of cals) {
          if (!prev.has(c.id)) next.add(c.id);
        }
        return next;
      });
    } catch {}
  }, []);

  const loadEvents = useCallback(async () => {
    const rangeStart =
      viewMode === "month"
        ? startOfWeek(startOfMonth(currentDate))
        : viewMode === "week"
          ? startOfWeek(currentDate)
          : currentDate;
    const rangeEnd =
      viewMode === "month"
        ? endOfWeek(endOfMonth(currentDate))
        : viewMode === "week"
          ? endOfWeek(currentDate)
          : currentDate;

    const start = new Date(rangeStart);
    start.setDate(start.getDate() - 1);
    const end = new Date(rangeEnd);
    end.setDate(end.getDate() + 1);

    try {
      const data = await api.listEvents({
        start: start.toISOString(),
        end: end.toISOString(),
      });
      setEvents(data.items || []);
    } catch {}
    setLoading(false);
  }, [currentDate, viewMode]);

  useEffect(() => {
    loadCalendars();
  }, [loadCalendars]);

  useEffect(() => {
    if (calendars.length > 0) loadEvents();
  }, [loadEvents, calendars]);

  const navigate = (dir: -1 | 1) => {
    if (viewMode === "month")
      setCurrentDate((d) => (dir === 1 ? addMonths(d, 1) : subMonths(d, 1)));
    else if (viewMode === "week")
      setCurrentDate((d) => (dir === 1 ? addWeeks(d, 1) : subWeeks(d, 1)));
    else
      setCurrentDate((d) => (dir === 1 ? addDays(d, 1) : subDays(d, 1)));
  };

  const goToday = () => setCurrentDate(new Date());

  const toggleCalendar = (id: string) => {
    setVisibleCalendarIds((prev) => {
      const next = new Set(prev);
      if (next.has(id)) next.delete(id);
      else next.add(id);
      return next;
    });
  };

  const handleDateClick = (date: Date) => {
    if (viewMode === "month") {
      setCurrentDate(date);
      setViewMode("day");
    } else {
      setDefaultEventDate(date);
      setSelectedEvent(null);
      setEventModalOpen(true);
    }
  };

  const handleTimeClick = (date: Date) => {
    setDefaultEventDate(date);
    setSelectedEvent(null);
    setEventModalOpen(true);
  };

  const handleEventClick = (event: CalendarEvent) => {
    setSelectedEvent(event);
    setEventModalOpen(true);
  };

  const handleEventSaved = () => {
    loadEvents();
  };

  const handleCalendarSaved = () => {
    loadCalendars().then(loadEvents);
  };

  const dateLabel =
    viewMode === "month"
      ? format(currentDate, "MMMM yyyy")
      : viewMode === "week"
        ? `${format(startOfWeek(currentDate), "MMM d")} - ${format(endOfWeek(currentDate), "MMM d, yyyy")}`
        : format(currentDate, "EEEE, MMMM d, yyyy");

  return (
    <div className="h-full flex flex-col bg-white dark:bg-gray-900 transition-colors">
      {/* Top Header */}
      <header className="flex items-center justify-between px-4 py-2.5 border-b border-gray-200 dark:border-gray-700 flex-shrink-0 bg-white dark:bg-gray-900">
        <div className="flex items-center gap-3">
          {/* Hamburger */}
          <button
            onClick={() => setSidebarOpen((s) => !s)}
            className="p-2 rounded-xl hover:bg-gray-100 dark:hover:bg-gray-800 text-gray-600 dark:text-gray-400 transition-colors lg:hidden"
          >
            <svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 6h16M4 12h16M4 18h16" />
            </svg>
          </button>
          <button
            onClick={() => setSidebarOpen((s) => !s)}
            className="p-2 rounded-xl hover:bg-gray-100 dark:hover:bg-gray-800 text-gray-600 dark:text-gray-400 transition-colors hidden lg:block"
          >
            <svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 6h16M4 12h16M4 18h16" />
            </svg>
          </button>

          {/* Logo */}
          <div className="flex items-center gap-2">
            <div className="w-8 h-8 bg-blue-600 rounded-lg flex items-center justify-center">
              <svg className="w-5 h-5 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" />
              </svg>
            </div>
            <span className="text-lg font-bold text-gray-900 dark:text-white hidden sm:block">
              Calendar
            </span>
          </div>
        </div>

        {/* Center: Navigation */}
        <div className="flex items-center gap-2">
          <button
            onClick={goToday}
            className="px-3 py-1.5 text-sm font-medium border border-gray-300 dark:border-gray-600 rounded-lg text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors"
          >
            Today
          </button>
          <div className="flex items-center">
            <button
              onClick={() => navigate(-1)}
              className="p-1.5 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800 text-gray-600 dark:text-gray-400 transition-colors"
            >
              <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" />
              </svg>
            </button>
            <button
              onClick={() => navigate(1)}
              className="p-1.5 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800 text-gray-600 dark:text-gray-400 transition-colors"
            >
              <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
              </svg>
            </button>
          </div>
          <h2 className="text-base font-semibold text-gray-900 dark:text-white min-w-[180px] text-center hidden sm:block">
            {dateLabel}
          </h2>
        </div>

        {/* Right: View mode + theme + user */}
        <div className="flex items-center gap-2">
          <div className="hidden sm:flex items-center bg-gray-100 dark:bg-gray-800 rounded-lg p-0.5">
            {(["month", "week", "day"] as ViewMode[]).map((v) => (
              <button
                key={v}
                onClick={() => setViewMode(v)}
                className={`px-3 py-1 text-xs font-medium rounded-md transition-colors capitalize ${
                  viewMode === v
                    ? "bg-white dark:bg-gray-700 text-gray-900 dark:text-white shadow-sm"
                    : "text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white"
                }`}
              >
                {v}
              </button>
            ))}
          </div>

          <button
            onClick={toggle}
            className="p-2 rounded-xl hover:bg-gray-100 dark:hover:bg-gray-800 text-gray-600 dark:text-gray-400 transition-colors"
          >
            {theme === "dark" ? (
              <svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z" />
              </svg>
            ) : (
              <svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z" />
              </svg>
            )}
          </button>

          {/* User menu */}
          <div className="relative">
            <button
              onClick={() => setUserMenuOpen((u) => !u)}
              className="w-8 h-8 rounded-full bg-gradient-to-br from-blue-500 to-purple-600 flex items-center justify-center text-white text-sm font-semibold"
            >
              {user?.email?.[0]?.toUpperCase() || "U"}
            </button>
            {userMenuOpen && (
              <>
                <div
                  className="fixed inset-0 z-40"
                  onClick={() => setUserMenuOpen(false)}
                />
                <div className="absolute right-0 mt-2 w-56 bg-white dark:bg-gray-800 rounded-xl shadow-lg border border-gray-200 dark:border-gray-700 py-1 z-50 animate-scale-in">
                  <div className="px-4 py-2.5 border-b border-gray-100 dark:border-gray-700">
                    <p className="text-sm font-medium text-gray-900 dark:text-white truncate">
                      {user?.email}
                    </p>
                    <p className="text-xs text-gray-500 dark:text-gray-400">
                      {user?.timezone}
                    </p>
                  </div>
                  <button
                    onClick={() => {
                      setUserMenuOpen(false);
                      logout();
                    }}
                    className="w-full text-left px-4 py-2 text-sm text-red-600 dark:text-red-400 hover:bg-gray-50 dark:hover:bg-gray-700/50 transition-colors"
                  >
                    Sign out
                  </button>
                </div>
              </>
            )}
          </div>
        </div>
      </header>

      {/* Mobile date label */}
      <div className="sm:hidden text-center py-2 border-b border-gray-100 dark:border-gray-800 flex-shrink-0">
        <span className="text-sm font-semibold text-gray-900 dark:text-white">{dateLabel}</span>
        <div className="flex items-center justify-center gap-1 mt-1">
          {(["month", "week", "day"] as ViewMode[]).map((v) => (
            <button
              key={v}
              onClick={() => setViewMode(v)}
              className={`px-2.5 py-0.5 text-xs font-medium rounded-md transition-colors capitalize ${
                viewMode === v
                  ? "bg-blue-100 dark:bg-blue-900/30 text-blue-700 dark:text-blue-400"
                  : "text-gray-500 dark:text-gray-400"
              }`}
            >
              {v}
            </button>
          ))}
        </div>
      </div>

      {/* Body */}
      <div className="flex flex-1 overflow-hidden">
        {/* Sidebar */}
        {sidebarOpen && (
          <aside className="w-64 border-r border-gray-200 dark:border-gray-700 flex-shrink-0 overflow-y-auto bg-white dark:bg-gray-900 flex flex-col">
            {/* New Event button */}
            <div className="p-4">
              <button
                onClick={() => {
                  setSelectedEvent(null);
                  setDefaultEventDate(new Date());
                  setEventModalOpen(true);
                }}
                className="w-full flex items-center justify-center gap-2 px-4 py-2.5 bg-blue-600 hover:bg-blue-700 text-white rounded-xl font-medium text-sm shadow-lg shadow-blue-600/20 transition-all hover:shadow-blue-600/30"
              >
                <svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 4v16m8-8H4" />
                </svg>
                New Event
              </button>
            </div>

            {/* Mini Calendar */}
            <div className="px-4 pb-4">
              <MiniCalendar
                selectedDate={currentDate}
                onDateSelect={(d) => setCurrentDate(d)}
              />
            </div>

            {/* Calendar list */}
            <div className="px-4 pb-4 flex-1">
              <div className="flex items-center justify-between mb-2">
                <h3 className="text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wider">
                  My Calendars
                </h3>
                <div className="flex gap-0.5">
                  <button
                    onClick={() => setAddUrlModalOpen(true)}
                    className="p-1 rounded-md hover:bg-gray-100 dark:hover:bg-gray-700 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 transition-colors"
                    title="Add from URL"
                  >
                    <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
                    </svg>
                  </button>
                  <button
                    onClick={() => {
                      setEditingCalendar(null);
                      setCalendarModalOpen(true);
                    }}
                    className="p-1 rounded-md hover:bg-gray-100 dark:hover:bg-gray-700 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 transition-colors"
                    title="New calendar"
                  >
                    <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 4v16m8-8H4" />
                    </svg>
                  </button>
                </div>
              </div>
              <div className="space-y-0.5">
                {calendars.map((cal) => (
                  <div
                    key={cal.id}
                    className="flex items-center gap-2 py-1.5 px-1 rounded-lg group hover:bg-gray-50 dark:hover:bg-gray-800/50"
                  >
                    <button
                      onClick={() => toggleCalendar(cal.id)}
                      className="flex-shrink-0"
                    >
                      <div
                        className={`w-4 h-4 rounded border-2 transition-colors flex items-center justify-center`}
                        style={{
                          borderColor: cal.color,
                          backgroundColor: visibleCalendarIds.has(cal.id)
                            ? cal.color
                            : "transparent",
                        }}
                      >
                        {visibleCalendarIds.has(cal.id) && (
                          <svg
                            className="w-3 h-3 text-white"
                            fill="none"
                            viewBox="0 0 24 24"
                            stroke="currentColor"
                          >
                            <path
                              strokeLinecap="round"
                              strokeLinejoin="round"
                              strokeWidth={3}
                              d="M5 13l4 4L19 7"
                            />
                          </svg>
                        )}
                      </div>
                    </button>
                    <span className="text-sm text-gray-700 dark:text-gray-300 flex-1 truncate">
                      {cal.name}
                    </span>
                    {cal.role === "owner" && (
                      <button
                        onClick={() => {
                          setEditingCalendar(cal);
                          setCalendarModalOpen(true);
                        }}
                        className="p-0.5 rounded opacity-0 group-hover:opacity-100 hover:bg-gray-200 dark:hover:bg-gray-700 text-gray-400 transition-all"
                      >
                        <svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                          <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 5v.01M12 12v.01M12 19v.01M12 6a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2z" />
                        </svg>
                      </button>
                    )}
                  </div>
                ))}
              </div>
            </div>
          </aside>
        )}

        {/* Main Content */}
        <main className="flex-1 overflow-hidden">
          {loading ? (
            <div className="flex items-center justify-center h-full">
              <div className="w-8 h-8 border-2 border-blue-600 border-t-transparent rounded-full animate-spin" />
            </div>
          ) : viewMode === "month" ? (
            <MonthView
              currentDate={currentDate}
              events={events}
              calendars={calendars}
              visibleCalendarIds={visibleCalendarIds}
              onDateClick={handleDateClick}
              onEventClick={handleEventClick}
            />
          ) : viewMode === "week" ? (
            <WeekView
              currentDate={currentDate}
              events={events}
              calendars={calendars}
              visibleCalendarIds={visibleCalendarIds}
              onTimeClick={handleTimeClick}
              onEventClick={handleEventClick}
            />
          ) : (
            <DayView
              currentDate={currentDate}
              events={events}
              calendars={calendars}
              visibleCalendarIds={visibleCalendarIds}
              onTimeClick={handleTimeClick}
              onEventClick={handleEventClick}
            />
          )}
        </main>
      </div>

      {/* Modals */}
      <EventModal
        open={eventModalOpen}
        onClose={() => setEventModalOpen(false)}
        onSaved={handleEventSaved}
        event={selectedEvent}
        calendars={calendars}
        defaultDate={defaultEventDate}
        defaultCalendarId={
          calendars.find((c) => c.role === "owner")?.id
        }
      />
      <CalendarModal
        open={calendarModalOpen}
        onClose={() => setCalendarModalOpen(false)}
        onSaved={handleCalendarSaved}
        calendar={editingCalendar}
      />
      <AddCalendarUrlModal
        open={addUrlModalOpen}
        onClose={() => setAddUrlModalOpen(false)}
        onSaved={handleCalendarSaved}
        targetCalendarId={null}
        calendars={calendars}
      />
    </div>
  );
}
