import { useState, useEffect, useCallback, forwardRef } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { Plus, Pencil, Trash2, FileText } from 'lucide-react';
import { toast } from 'sonner';
import api, { getErrorMessage } from '@/lib/api';
import type { Calendar, EventTemplate } from '@/types';
import { useCalendars } from '@/hooks/useCalendars';
import { Button } from '@/components/ui/button';
import { Checkbox } from '@/components/ui/checkbox';
import CalendarForm from './CalendarForm';
import TemplateForm from './TemplateForm';
import SharedCalendarSection, { loadVisibility, saveVisibility } from './SharedCalendarSection';

interface CalendarSidebarProps {
  onUseTemplate?: (template: EventTemplate) => void;
  onSharedVisibilityChange?: (visibleIds: Set<number>) => void;
  width: number;
}

const CalendarSidebar = forwardRef<HTMLDivElement, CalendarSidebarProps>(function CalendarSidebar({ onUseTemplate, onSharedVisibilityChange, width }, ref) {
  const queryClient = useQueryClient();
  const { data: calendars = [], sharedData: sharedCalendars = [] } = useCalendars();
  const [showForm, setShowForm] = useState(false);
  const [editingCalendar, setEditingCalendar] = useState<Calendar | null>(null);
  const [showTemplateForm, setShowTemplateForm] = useState(false);
  const [editingTemplate, setEditingTemplate] = useState<EventTemplate | null>(null);

  const [sharedVisibility, setSharedVisibility] = useState<Record<number, boolean>>(() => loadVisibility());

  const visibleSharedIds = new Set(
    sharedCalendars
      .filter((m) => sharedVisibility[m.calendar_id] !== false)
      .map((m) => m.calendar_id)
  );

  useEffect(() => {
    onSharedVisibilityChange?.(visibleSharedIds);
  }, [sharedCalendars, sharedVisibility]);

  const handleSharedVisibilityChange = useCallback((calendarId: number, visible: boolean) => {
    setSharedVisibility((prev) => {
      const next = { ...prev, [calendarId]: visible };
      saveVisibility(next);
      return next;
    });
  }, []);

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

  const toggleMutation = useMutation({
    mutationFn: async ({ id, is_visible }: { id: number; is_visible: boolean }) => {
      await api.put(`/calendars/${id}`, { is_visible });
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['calendars'] });
      queryClient.invalidateQueries({ queryKey: ['calendar-events'] });
    },
    onError: (error) => {
      toast.error(getErrorMessage(error, 'Failed to update calendar'));
    },
  });

  const deleteTemplateMutation = useMutation({
    mutationFn: async (id: number) => {
      await api.delete(`/event-templates/${id}`);
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['event-templates'] });
      toast.success('Template deleted');
    },
    onError: (error) => {
      toast.error(getErrorMessage(error, 'Failed to delete template'));
    },
  });

  const handleToggle = (calendar: Calendar) => {
    toggleMutation.mutate({ id: calendar.id, is_visible: !calendar.is_visible });
  };

  const handleEdit = (calendar: Calendar) => {
    setEditingCalendar(calendar);
    setShowForm(true);
  };

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

  return (
    <div ref={ref} className="shrink-0 border-r bg-card flex flex-col" style={{ width }}>
      <div className="h-16 px-4 border-b flex items-center justify-between shrink-0">
        <span className="text-sm font-semibold font-heading text-foreground">Calendars</span>
        <Button
          variant="ghost"
          size="icon"
          className="h-7 w-7"
          onClick={() => { setEditingCalendar(null); setShowForm(true); }}
        >
          <Plus className="h-4 w-4" />
        </Button>
      </div>
      <div className="flex-1 overflow-y-auto p-3 space-y-4">
        {/* Owned calendars list (non-shared only) */}
        <div className="space-y-0.5">
          {calendars.filter((c) => !c.is_shared).map((cal) => (
            <div
              key={cal.id}
              className="group flex items-center gap-2.5 rounded-md px-2 py-1.5 hover:bg-card-elevated transition-colors duration-150"
            >
              <Checkbox
                checked={cal.is_visible}
                onChange={() => handleToggle(cal)}
                className="shrink-0"
                style={{
                  accentColor: cal.color,
                  borderColor: cal.is_visible ? cal.color : undefined,
                  backgroundColor: cal.is_visible ? cal.color : undefined,
                }}
              />
              <span
                className="h-2.5 w-2.5 rounded-full shrink-0"
                style={{ backgroundColor: cal.color }}
              />
              <span className="text-sm text-foreground truncate flex-1">{cal.name}</span>
              <button
                onClick={() => handleEdit(cal)}
                className="opacity-100 md:opacity-0 md:group-hover:opacity-100 transition-opacity duration-150 text-muted-foreground hover:text-foreground"
              >
                <Pencil className="h-3.5 w-3.5" />
              </button>
            </div>
          ))}
        </div>

        {/* Shared calendars section -- owned + member */}
        {(calendars.some((c) => c.is_shared) || sharedCalendars.length > 0) && (
          <SharedCalendarSection
            ownedSharedCalendars={calendars.filter((c) => c.is_shared)}
            memberships={sharedCalendars}
            visibleSharedIds={visibleSharedIds}
            onVisibilityChange={handleSharedVisibilityChange}
            onEditCalendar={handleEdit}
            onToggleCalendar={handleToggle}
          />
        )}

        {/* Templates section */}
        <div className="space-y-1.5">
          <div className="flex items-center justify-between px-2">
            <span className="text-[11px] font-semibold uppercase tracking-wider text-muted-foreground">
              Templates
            </span>
            <Button
              variant="ghost"
              size="icon"
              className="h-5 w-5"
              onClick={() => { setEditingTemplate(null); setShowTemplateForm(true); }}
            >
              <Plus className="h-3 w-3" />
            </Button>
          </div>
          {templates.length === 0 ? (
            <p className="text-xs text-muted-foreground px-2">No templates yet</p>
          ) : (
            <div className="space-y-0.5">
              {templates.map((tmpl) => (
                <div
                  key={tmpl.id}
                  className="group flex items-center gap-2 rounded-md px-2 py-1.5 hover:bg-card-elevated transition-colors duration-150 cursor-pointer"
                  onClick={() => onUseTemplate?.(tmpl)}
                >
                  <FileText className="h-3.5 w-3.5 text-muted-foreground shrink-0" />
                  <span className="text-sm text-foreground truncate flex-1">{tmpl.name}</span>
                  <button
                    onClick={(e) => {
                      e.stopPropagation();
                      setEditingTemplate(tmpl);
                      setShowTemplateForm(true);
                    }}
                    className="opacity-100 md:opacity-0 md:group-hover:opacity-100 transition-opacity duration-150 text-muted-foreground hover:text-foreground"
                  >
                    <Pencil className="h-3 w-3" />
                  </button>
                  <button
                    onClick={(e) => {
                      e.stopPropagation();
                      if (!window.confirm(`Delete template "${tmpl.name}"?`)) return;
                      deleteTemplateMutation.mutate(tmpl.id);
                    }}
                    className="opacity-100 md:opacity-0 md:group-hover:opacity-100 transition-opacity duration-150 text-muted-foreground hover:text-destructive"
                  >
                    <Trash2 className="h-3 w-3" />
                  </button>
                </div>
              ))}
            </div>
          )}
        </div>
      </div>

      {showForm && (
        <CalendarForm
          calendar={editingCalendar}
          onClose={handleCloseForm}
        />
      )}

      {showTemplateForm && (
        <TemplateForm
          template={editingTemplate}
          onClose={() => { setShowTemplateForm(false); setEditingTemplate(null); }}
        />
      )}
    </div>
  );
});

export default CalendarSidebar;