import { useState, useEffect, useCallback } from 'react';
import {
  Typography,
  Button,
  Grid,
  Skeleton,
  Empty,
  List,
  Tag,
  Space,
  message,
  theme,
  Modal,
  Segmented,
  Drawer,
  Divider,
} from 'antd';
import {
  CalendarOutlined,
  PlusOutlined,
  ClockCircleOutlined,
  EnvironmentOutlined,
  DeleteOutlined,
  EditOutlined,
  SettingOutlined,
  LeftOutlined,
  RightOutlined,
} from '@ant-design/icons';
import dayjs, { Dayjs } from 'dayjs';
import { useNavigate } from 'react-router-dom';
import { api } from '@/lib/api';
import FeatureGate from '@/components/FeatureGate';
import CalendarLayerPanel from '@/components/calendar/CalendarLayerPanel';
import PersonalCalendarView from '@/components/calendar/PersonalCalendarView';
import CalendarTimeGrid from '@/components/calendar/CalendarTimeGrid';
import CalendarItemModal, { type CalendarItemFormData } from '@/components/calendar/CalendarItemModal';
import CalendarItemDetail from '@/components/calendar/CalendarItemDetail';
import CalendarFeedsPanel from '@/components/calendar/CalendarFeedsPanel';
import CalendarExportPanel from '@/components/calendar/CalendarExportPanel';
import { getDateRangeForView, type CalendarViewMode } from '@/components/calendar/calendarUtils';
import type {
  CalendarLayer,
  PersonalCalendarItem,
  PersonalCalendarResponse,
  SeriesEditScope,
} from '@/types/api';

const { Text } = Typography;

export default function MyCalendarPage() {
  const navigate = useNavigate();
  const screens = Grid.useBreakpoint();
  const isMobile = !screens.md;
  const { token } = theme.useToken();

  // Data state
  const [layers, setLayers] = useState<CalendarLayer[]>([]);
  const [items, setItems] = useState<PersonalCalendarItem[]>([]);
  const [loading, setLoading] = useState(true);

  // View state
  const [viewMode, setViewMode] = useState<CalendarViewMode>(isMobile ? 'day' : 'month');
  const [currentDate, setCurrentDate] = useState<Dayjs>(dayjs());
  const [selectedDate, setSelectedDate] = useState<string | null>(null);

  // Modal / detail state
  const [itemModalOpen, setItemModalOpen] = useState(false);
  const [editingItem, setEditingItem] = useState<PersonalCalendarItem | null>(null);
  const [selectedItem, setSelectedItem] = useState<PersonalCalendarItem | null>(null);
  const [settingsOpen, setSettingsOpen] = useState(false);

  // Derived: enabled layer IDs for filtering
  const enabledLayerIds = new Set(layers.filter((l) => l.isEnabled).map((l) => l.id));

  // Filtered items based on enabled layers
  const filteredItems = items.filter((item) => enabledLayerIds.has(item.layerId));

  // Items for the selected date (used in month view detail panel)
  const selectedDateItems = selectedDate
    ? filteredItems.filter((item) => item.date === selectedDate)
    : [];

  // Fetch layers
  const fetchLayers = useCallback(async () => {
    try {
      const { data } = await api.get<{ layers: CalendarLayer[] }>('/calendar/layers');
      setLayers(data.layers);
    } catch {
      // Layers may not exist yet
    }
  }, []);

  // Fetch items for the current visible range
  const fetchItems = useCallback(async () => {
    const { startDate, endDate } = getDateRangeForView(viewMode, currentDate);
    try {
      const { data } = await api.get<PersonalCalendarResponse>('/calendar/my', {
        params: { startDate, endDate },
      });
      const allItems: PersonalCalendarItem[] = [];
      for (const dateGroup of Object.values(data.dates)) {
        allItems.push(...dateGroup.items);
      }
      setItems(allItems);
    } catch {
      // Empty calendar
    }
  }, [viewMode, currentDate]);

  // Initial load
  useEffect(() => {
    const load = async () => {
      setLoading(true);
      await Promise.all([fetchLayers(), fetchItems()]);
      setLoading(false);
    };
    load();
  }, [fetchLayers, fetchItems]);

  // Layer CRUD
  const handleCreateLayer = async (name: string, color: string) => {
    try {
      await api.post('/calendar/layers', { name, color });
      await fetchLayers();
      message.success('Layer created');
    } catch {
      message.error('Failed to create layer');
    }
  };

  const handleUpdateLayer = async (id: string, updates: Partial<CalendarLayer>) => {
    try {
      await api.patch(`/calendar/layers/${id}`, updates);
      setLayers((prev) =>
        prev.map((l) => (l.id === id ? { ...l, ...updates } : l)),
      );
    } catch {
      message.error('Failed to update layer');
      await fetchLayers();
    }
  };

  const handleDeleteLayer = async (id: string) => {
    try {
      await api.delete(`/calendar/layers/${id}`);
      setLayers((prev) => prev.filter((l) => l.id !== id));
      message.success('Layer deleted');
    } catch {
      message.error('Failed to delete layer');
    }
  };

  // Item CRUD
  const handleSaveItem = async (values: CalendarItemFormData, scope?: SeriesEditScope) => {
    try {
      if (editingItem?.calendarItemId) {
        await api.patch(
          `/calendar/items/${editingItem.calendarItemId}`,
          values,
          { params: scope ? { scope } : undefined },
        );
        message.success('Event updated');
      } else {
        await api.post('/calendar/items', values);
        message.success('Event created');
      }
      setItemModalOpen(false);
      setEditingItem(null);
      await fetchItems();
    } catch {
      message.error('Failed to save event');
    }
  };

  const handleDeleteItem = async (item: PersonalCalendarItem, scope?: SeriesEditScope) => {
    if (!item.calendarItemId) return;
    try {
      await api.delete(`/calendar/items/${item.calendarItemId}`, {
        params: scope ? { scope } : undefined,
      });
      message.success('Event deleted');
      await fetchItems();
    } catch {
      message.error('Failed to delete event');
    }
  };

  const confirmDeleteItem = (item: PersonalCalendarItem) => {
    if (item.isRecurring && item.seriesId) {
      Modal.confirm({
        title: 'Delete recurring event',
        content: 'How would you like to delete this recurring event?',
        okText: 'This event only',
        cancelText: 'Cancel',
        onOk: () => handleDeleteItem(item, 'THIS_ONLY'),
        footer: (_, { OkBtn, CancelBtn }) => (
          <Space>
            <CancelBtn />
            <OkBtn />
            <Button danger onClick={() => { handleDeleteItem(item, 'ALL'); Modal.destroyAll(); }}>
              All in series
            </Button>
          </Space>
        ),
      });
    } else {
      Modal.confirm({
        title: 'Delete event?',
        content: `Are you sure you want to delete "${item.title}"?`,
        okText: 'Delete',
        okType: 'danger',
        onOk: () => handleDeleteItem(item),
      });
    }
  };

  // Open modal for new item on a date
  const handleAddItem = (date?: string) => {
    setEditingItem(null);
    if (date) {
      setSelectedDate(date);
    }
    setItemModalOpen(true);
  };

  // Show item detail (click on any item)
  const handleItemClick = (item: PersonalCalendarItem) => {
    setSelectedItem(item);
  };

  // Open edit modal for a personal item (from detail drawer)
  const handleEditItem = (item: PersonalCalendarItem) => {
    if (item.type !== 'personal') return;
    setEditingItem(item);
    setItemModalOpen(true);
  };

  // Date click handler
  const handleDateSelect = (date: string) => {
    setSelectedDate(date);
    // In month view, clicking a date also shows the detail panel
    // In grid views, clicking a date opens the add-item modal
    if (viewMode !== 'month') {
      handleAddItem(date);
    }
  };

  // Navigation
  const handleNavigate = (direction: 'prev' | 'next') => {
    const delta = direction === 'next' ? 1 : -1;
    switch (viewMode) {
      case 'day':
        setCurrentDate((d) => d.add(delta, 'day'));
        break;
      case '3day':
        setCurrentDate((d) => d.add(delta * 3, 'day'));
        break;
      case 'week':
        setCurrentDate((d) => d.add(delta * 7, 'day'));
        break;
      case 'month':
        setCurrentDate((d) => d.add(delta, 'month'));
        break;
    }
  };

  const handleToday = () => {
    setCurrentDate(dayjs());
    setSelectedDate(dayjs().format('YYYY-MM-DD'));
  };

  // Navigation label
  const getNavLabel = (): string => {
    switch (viewMode) {
      case 'day':
        return currentDate.format('ddd, MMM D');
      case '3day':
        return `${currentDate.format('MMM D')} - ${currentDate.add(2, 'day').format('MMM D')}`;
      case 'week': {
        const start = currentDate.startOf('week');
        const end = currentDate.endOf('week');
        return start.month() === end.month()
          ? `${start.format('MMM D')} - ${end.format('D')}`
          : `${start.format('MMM D')} - ${end.format('MMM D')}`;
      }
      case 'month':
        return currentDate.format('MMMM YYYY');
    }
  };

  if (loading) {
    return (
      <div style={{ padding: '12px 0' }}>
        <Skeleton active paragraph={{ rows: 10 }} />
      </div>
    );
  }

  // Date detail panel (right side on desktop, used only in month view)
  const dateDetailPanel = viewMode === 'month' && selectedDate && (
    <div
      style={{
        width: isMobile ? '100%' : 280,
        flexShrink: 0,
        padding: isMobile ? '12px 0' : '0 0 0 16px',
        borderLeft: isMobile ? undefined : `1px solid ${token.colorBorderSecondary}`,
      }}
    >
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 12 }}>
        <Text strong style={{ fontSize: 15 }}>
          {dayjs(selectedDate).format('ddd, MMM D')}
        </Text>
        <Button
          type="primary"
          size="small"
          icon={<PlusOutlined />}
          onClick={() => handleAddItem(selectedDate)}
        >
          Add
        </Button>
      </div>

      {selectedDateItems.length === 0 ? (
        <Empty description="No events" image={Empty.PRESENTED_IMAGE_SIMPLE} />
      ) : (
        <List
          size="small"
          dataSource={selectedDateItems}
          renderItem={(item) => (
            <List.Item
              style={{ padding: '8px 0', cursor: 'pointer' }}
              onClick={() => handleItemClick(item)}
              actions={
                item.type === 'personal'
                  ? [
                      <Button
                        key="edit"
                        type="text"
                        size="small"
                        icon={<EditOutlined />}
                        onClick={(e) => {
                          e.stopPropagation();
                          handleEditItem(item);
                        }}
                      />,
                      <Button
                        key="delete"
                        type="text"
                        size="small"
                        danger
                        icon={<DeleteOutlined />}
                        onClick={(e) => {
                          e.stopPropagation();
                          confirmDeleteItem(item);
                        }}
                      />,
                    ]
                  : undefined
              }
            >
              <List.Item.Meta
                avatar={
                  <div
                    style={{
                      width: 4,
                      height: 32,
                      borderRadius: 2,
                      background: item.color,
                      flexShrink: 0,
                    }}
                  />
                }
                title={
                  <Text style={{ fontSize: 13 }} ellipsis>
                    {item.title}
                  </Text>
                }
                description={
                  <Space size={4} wrap style={{ fontSize: 11 }}>
                    {!item.isAllDay && (
                      <Tag
                        icon={<ClockCircleOutlined />}
                        style={{ fontSize: 11, margin: 0 }}
                      >
                        {item.startTime?.slice(0, 5)} - {item.endTime?.slice(0, 5)}
                      </Tag>
                    )}
                    {item.isAllDay && <Tag style={{ fontSize: 11, margin: 0 }}>All day</Tag>}
                    {item.location && (
                      <Tag
                        icon={<EnvironmentOutlined />}
                        style={{ fontSize: 11, margin: 0 }}
                      >
                        {item.location}
                      </Tag>
                    )}
                    {item.type !== 'personal' && (
                      <Tag color="blue" style={{ fontSize: 10, margin: 0 }}>
                        {item.type}
                      </Tag>
                    )}
                  </Space>
                }
              />
            </List.Item>
          )}
        />
      )}
    </div>
  );

  return (
    <FeatureGate feature="enableSocialCalendar">
      <div style={{ padding: '12px 0' }}>
        {/* Header row 1: Tab selector + settings/add */}
        <div
          style={{
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'space-between',
            marginBottom: 8,
          }}
        >
          <Space>
            <CalendarOutlined style={{ fontSize: 20 }} />
            <Segmented
              options={['My Calendar', 'Shared']}
              value="My Calendar"
              onChange={(val) => {
                if (val === 'Shared') navigate('/volunteer/calendar/shared');
              }}
            />
          </Space>
          <Space>
            <Button
              icon={<SettingOutlined />}
              onClick={() => setSettingsOpen(true)}
            />
            <Button
              type="primary"
              icon={<PlusOutlined />}
              onClick={() => handleAddItem(selectedDate ?? dayjs().format('YYYY-MM-DD'))}
            >
              {!isMobile && 'Add Event'}
            </Button>
          </Space>
        </div>

        {/* Header row 2: Navigation + view mode */}
        <div
          style={{
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'space-between',
            marginBottom: 12,
            flexWrap: 'wrap',
            gap: 8,
          }}
        >
          <Space>
            <Button
              icon={<LeftOutlined />}
              size="small"
              onClick={() => handleNavigate('prev')}
            />
            <Button size="small" onClick={handleToday}>
              Today
            </Button>
            <Button
              icon={<RightOutlined />}
              size="small"
              onClick={() => handleNavigate('next')}
            />
            <Text strong style={{ fontSize: 15, marginLeft: 4 }}>
              {getNavLabel()}
            </Text>
          </Space>
          <Segmented
            size="small"
            options={[
              { label: 'Day', value: 'day' },
              { label: isMobile ? '3D' : '3 Day', value: '3day' },
              { label: 'Week', value: 'week' },
              { label: 'Month', value: 'month' },
            ]}
            value={viewMode}
            onChange={(val) => setViewMode(val as CalendarViewMode)}
          />
        </div>

        {viewMode === 'month' ? (
          /* Month view: layer panel + calendar + date detail */
          isMobile ? (
            <div>
              <CalendarLayerPanel
                layers={layers}
                compact
                onToggle={(id, enabled) => handleUpdateLayer(id, { isEnabled: enabled })}
                onCreate={handleCreateLayer}
                onUpdate={handleUpdateLayer}
                onDelete={handleDeleteLayer}
              />
              <PersonalCalendarView
                items={filteredItems}
                currentMonth={currentDate}
                selectedDate={selectedDate}
                onDateSelect={(date) => setSelectedDate(date)}
                onItemClick={handleItemClick}
                onMonthChange={setCurrentDate}
              />
              {dateDetailPanel}
            </div>
          ) : (
            <div style={{ display: 'flex', gap: 0 }}>
              <div style={{ width: 240, flexShrink: 0, paddingRight: 16 }}>
                <CalendarLayerPanel
                  layers={layers}
                  onToggle={(id, enabled) => handleUpdateLayer(id, { isEnabled: enabled })}
                  onCreate={handleCreateLayer}
                  onUpdate={handleUpdateLayer}
                  onDelete={handleDeleteLayer}
                />
              </div>
              <div style={{ flex: 1, minWidth: 0 }}>
                <PersonalCalendarView
                  items={filteredItems}
                  currentMonth={currentDate}
                  selectedDate={selectedDate}
                  onDateSelect={(date) => setSelectedDate(date)}
                  onItemClick={handleItemClick}
                  onMonthChange={setCurrentDate}
                />
              </div>
              {dateDetailPanel}
            </div>
          )
        ) : (
          /* Day / 3-Day / Week views: layer panel + time grid */
          isMobile ? (
            <div>
              <CalendarLayerPanel
                layers={layers}
                compact
                onToggle={(id, enabled) => handleUpdateLayer(id, { isEnabled: enabled })}
                onCreate={handleCreateLayer}
                onUpdate={handleUpdateLayer}
                onDelete={handleDeleteLayer}
              />
              <CalendarTimeGrid
                items={filteredItems}
                viewMode={viewMode}
                currentDate={currentDate}
                onDateSelect={handleDateSelect}
                onItemClick={handleItemClick}
                onNavigate={handleNavigate}
              />
            </div>
          ) : (
            <div style={{ display: 'flex', gap: 0 }}>
              <div style={{ width: 240, flexShrink: 0, paddingRight: 16 }}>
                <CalendarLayerPanel
                  layers={layers}
                  onToggle={(id, enabled) => handleUpdateLayer(id, { isEnabled: enabled })}
                  onCreate={handleCreateLayer}
                  onUpdate={handleUpdateLayer}
                  onDelete={handleDeleteLayer}
                />
              </div>
              <div style={{ flex: 1, minWidth: 0 }}>
                <CalendarTimeGrid
                  items={filteredItems}
                  viewMode={viewMode}
                  currentDate={currentDate}
                  onDateSelect={handleDateSelect}
                  onItemClick={handleItemClick}
                  onNavigate={handleNavigate}
                />
              </div>
            </div>
          )
        )}

        {/* Item detail drawer */}
        <CalendarItemDetail
          item={selectedItem}
          open={!!selectedItem}
          onClose={() => setSelectedItem(null)}
          onEdit={(item) => {
            setSelectedItem(null);
            handleEditItem(item);
          }}
          onDelete={(item) => {
            setSelectedItem(null);
            confirmDeleteItem(item);
          }}
        />

        {/* Settings drawer */}
        <Drawer
          title="Calendar Settings"
          open={settingsOpen}
          onClose={() => {
            setSettingsOpen(false);
            fetchItems();
          }}
          width={400}
        >
          <CalendarFeedsPanel />
          <Divider />
          <CalendarExportPanel layers={layers} />
        </Drawer>

        {/* Item create/edit modal */}
        <CalendarItemModal
          open={itemModalOpen}
          item={editingItem}
          layers={layers.filter((l) => l.layerType === 'USER')}
          defaultDate={selectedDate ?? dayjs().format('YYYY-MM-DD')}
          onSave={handleSaveItem}
          onDelete={editingItem ? () => confirmDeleteItem(editingItem) : undefined}
          onCancel={() => {
            setItemModalOpen(false);
            setEditingItem(null);
          }}
        />
      </div>
    </FeatureGate>
  );
}
