import { useState, useEffect, useCallback, useRef, useMemo } from 'react';
import {
  Table,
  Button,
  Dropdown,
  Input,
  Select,
  Tag,
  Space,
  Form,
  Switch,
  Popconfirm,
  message,
  Typography,
  Row,
  Col,
  Progress,
  DatePicker,
  TimePicker,
  InputNumber,
  Drawer,
  Card,
  Statistic,
  Tabs,
  Segmented,
  Checkbox,
  Alert,
  Tooltip,
  Grid,
} from 'antd';
import {
  PlusOutlined,
  EditOutlined,
  DeleteOutlined,
  SearchOutlined,
  ScheduleOutlined,
  MailOutlined,
  CheckCircleOutlined,
  ClockCircleOutlined,
  StopOutlined,
  TeamOutlined,
  VideoCameraOutlined,
  LinkOutlined,
  EnvironmentOutlined,
  ReadOutlined,
  CustomerServiceOutlined,
  PhoneOutlined,
  AppstoreOutlined,
} from '@ant-design/icons';
import type { MenuProps } from 'antd';
import type { ColumnsType, TablePaginationConfig } from 'antd/es/table';
import dayjs from 'dayjs';
import { useOutletContext, useNavigate } from 'react-router-dom';
import { api } from '@/lib/api';
import { useSettingsStore } from '@/stores/settings.store';
import type { AppOutletContext } from '@/components/AppLayout';
import type {
  Shift,
  ShiftSignup,
  ShiftsListResponse,
  ShiftsListParams,
  ShiftStats,
  ShiftStatus,
  ShiftKind,
  Cut,
  CreateShiftSeriesInput,
  CalendarData,
  EditMode,
  RecurrenceFrequency,
} from '@/types/api';
import {
  SHIFT_STATUS_COLORS,
  SHIFT_STATUS_LABELS,
  SIGNUP_SOURCE_COLORS,
  SHIFT_KIND_LABELS,
  SHIFT_KIND_COLORS,
} from '@/types/api';
import EditModeModal from '@/components/shifts/EditModeModal';
import { getErrorMessage } from '@/utils/getErrorMessage';
import ShiftsCalendar from '@/components/shifts/ShiftsCalendar';

const { Text } = Typography;

const statusOptions = Object.entries(SHIFT_STATUS_LABELS).map(([value, label]) => ({
  value,
  label,
}));

const kindOptions = (Object.entries(SHIFT_KIND_LABELS) as [ShiftKind, string][]).map(
  ([value, label]) => ({ value, label })
);

const KIND_ICONS: Record<ShiftKind, React.ReactNode> = {
  CANVASS: <EnvironmentOutlined />,
  TRAINING: <ReadOutlined />,
  EVENT_STAFFING: <CustomerServiceOutlined />,
  PHONE_BANK: <PhoneOutlined />,
  OTHER: <AppstoreOutlined />,
};

const DAYS_OF_WEEK = [
  { label: 'Sun', value: 0 },
  { label: 'Mon', value: 1 },
  { label: 'Tue', value: 2 },
  { label: 'Wed', value: 3 },
  { label: 'Thu', value: 4 },
  { label: 'Fri', value: 5 },
  { label: 'Sat', value: 6 },
];

export default function ShiftsPage() {
  const { settings: siteSettings } = useSettingsStore();
  const showMeet = siteSettings?.enableMeet !== false;
  const [shifts, setShifts] = useState<Shift[]>([]);
  const [pagination, setPagination] = useState({ page: 1, limit: 20, total: 0, totalPages: 0 });
  const [loading, setLoading] = useState(false);
  const [search, setSearch] = useState('');
  const [debouncedSearch, setDebouncedSearch] = useState('');
  const searchTimerRef = useRef<ReturnType<typeof setTimeout>>(undefined);
  const [statusFilter, setStatusFilter] = useState<ShiftStatus | undefined>();
  const [kindFilter, setKindFilter] = useState<ShiftKind | undefined>();
  const [stats, setStats] = useState<ShiftStats | null>(null);

  // Create drawer
  const [createDrawerOpen, setCreateDrawerOpen] = useState(false);
  const [createLoading, setCreateLoading] = useState(false);
  const [createMode, setCreateMode] = useState<'single' | 'series'>('single');
  const [frequency, setFrequency] = useState<RecurrenceFrequency>('WEEKLY');
  const [estimatedCount, setEstimatedCount] = useState<number>(0);
  const [createForm] = Form.useForm();

  // Edit drawer
  const [editDrawerOpen, setEditDrawerOpen] = useState(false);
  const [editingShift, setEditingShift] = useState<Shift | null>(null);
  const [editForm] = Form.useForm();

  // Signups drawer
  const [signupsDrawerOpen, setSignupsDrawerOpen] = useState(false);
  const [signupsShift, setSignupsShift] = useState<Shift | null>(null);
  const [signups, setSignups] = useState<ShiftSignup[]>([]);
  const [signupsLoading, setSignupsLoading] = useState(false);
  const [addEmail, setAddEmail] = useState('');
  const [addName, setAddName] = useState('');

  // Cuts for area dropdown
  const [cuts, setCuts] = useState<Cut[]>([]);
  const [ticketedEvents, setTicketedEvents] = useState<Array<{
    id: string;
    slug: string;
    title: string;
    date: string;
    startTime: string;
    endTime: string;
    venueName: string | null;
    venueAddress: string | null;
  }>>([]);

  // Calendar view state
  const [activeTab, setActiveTab] = useState<'table' | 'calendar'>('table');
  const [editModeModalOpen, setEditModeModalOpen] = useState(false);
  const [editingSeriesShift, setEditingSeriesShift] = useState<Shift | null>(null);
  const [seriesShiftCount, setSeriesShiftCount] = useState(0);
  const [calendarData, setCalendarData] = useState<CalendarData['dates']>({});
  const [calendarLoading, setCalendarLoading] = useState(false);
  const [currentMonth] = useState(dayjs());
  const screens = Grid.useBreakpoint();
  const isMobile = !screens.md;

  const handleSearchChange = (value: string) => {
    setSearch(value);
    clearTimeout(searchTimerRef.current);
    searchTimerRef.current = setTimeout(() => setDebouncedSearch(value), 300);
  };

  useEffect(() => {
    return () => clearTimeout(searchTimerRef.current);
  }, []);

  // Estimate occurrence count for series mode
  useEffect(() => {
    if (createMode !== 'series') return;

    const values = createForm.getFieldsValue();
    if (!values.startDate || !frequency) return;

    const startDate = dayjs(values.startDate);
    const endDate = values.endDate ? dayjs(values.endDate) : startDate.add(12, 'weeks');
    const days = endDate.diff(startDate, 'days') + 1;

    let count = 0;
    if (frequency === 'DAILY') {
      count = days;
    } else if (frequency === 'WEEKLY') {
      const daysOfWeek = values.daysOfWeek?.length || 0;
      count = Math.floor(days / 7) * daysOfWeek;
    } else if (frequency === 'MONTHLY') {
      count = Math.floor(days / 30);
    }

    setEstimatedCount(Math.min(count, 100)); // Cap at 100
  }, [createForm, frequency, createMode]);

  const fetchStats = useCallback(async () => {
    try {
      const { data } = await api.get<ShiftStats>('/map/shifts/stats');
      setStats(data);
    } catch {
      // Non-critical
    }
  }, []);

  const fetchCuts = useCallback(async () => {
    try {
      const { data } = await api.get('/map/cuts', { params: { limit: 100 } });
      setCuts(data.cuts ?? data);
    } catch {
      // Non-critical
    }
  }, []);

  const fetchTicketedEvents = useCallback(async () => {
    try {
      const { data } = await api.get('/ticketed-events/admin', { params: { limit: 100 } });
      setTicketedEvents(data.events ?? data.items ?? data ?? []);
    } catch {
      // Non-critical — picker stays empty
    }
  }, []);

  const fetchCalendarData = useCallback(async (month: dayjs.Dayjs) => {
    setCalendarLoading(true);
    try {
      const startDate = month.startOf('month').format('YYYY-MM-DD');
      const endDate = month.endOf('month').format('YYYY-MM-DD');

      const { data } = await api.get<CalendarData>('/map/shifts/calendar', {
        params: { startDate, endDate },
      });

      setCalendarData(data.dates);
    } catch {
      message.error('Failed to load calendar data');
    } finally {
      setCalendarLoading(false);
    }
  }, []);

  const fetchShifts = useCallback(async (params?: ShiftsListParams) => {
    setLoading(true);
    try {
      const { data } = await api.get<ShiftsListResponse>('/map/shifts', {
        params: {
          page: params?.page ?? pagination.page,
          limit: params?.limit ?? pagination.limit,
          search: params?.search ?? (debouncedSearch || undefined),
          status: params?.status ?? statusFilter,
          kind: params?.kind ?? kindFilter,
        },
      });
      setShifts(data.shifts);
      setPagination(data.pagination);
    } catch {
      message.error('Failed to load shifts');
    } finally {
      setLoading(false);
    }
  }, [pagination.page, pagination.limit, debouncedSearch, statusFilter, kindFilter]);

  useEffect(() => {
    fetchShifts({ page: 1 });
    fetchStats();
    fetchCuts();
    fetchTicketedEvents();
  }, [debouncedSearch, statusFilter, kindFilter]); // eslint-disable-line react-hooks/exhaustive-deps

  useEffect(() => {
    if (activeTab === 'calendar') {
      fetchCalendarData(currentMonth);
    }
  }, [activeTab, currentMonth, fetchCalendarData]);

  const handleTableChange = (pag: TablePaginationConfig) => {
    fetchShifts({ page: pag.current ?? 1, limit: pag.pageSize ?? 20 });
  };

  const handleCreate = async (values: Record<string, unknown>) => {
    setCreateLoading(true);
    try {
      if (createMode === 'single') {
        // Single shift creation
        const payload = {
          title: values.title,
          description: values.description || undefined,
          date: dayjs(values.date as string).format('YYYY-MM-DD'),
          startTime: dayjs(values.startTime as string).format('HH:mm'),
          endTime: dayjs(values.endTime as string).format('HH:mm'),
          location: values.location || undefined,
          maxVolunteers: values.maxVolunteers,
          isPublic: values.isPublic || false,
          cutId: values.cutId || undefined,
          kind: (values.kind as ShiftKind) || 'CANVASS',
          ticketedEventId:
            values.kind === 'EVENT_STAFFING'
              ? ((values.ticketedEventId as string) || undefined)
              : undefined,
        };
        await api.post('/map/shifts', payload);
        message.success(`${SHIFT_KIND_LABELS[payload.kind]} shift created`);
      } else {
        // Series creation
        const seriesPayload: CreateShiftSeriesInput = {
          title: values.title as string,
          description: values.description as string | undefined,
          startTime: dayjs(values.startTime as string).format('HH:mm'),
          endTime: dayjs(values.endTime as string).format('HH:mm'),
          location: values.location as string | undefined,
          maxVolunteers: values.maxVolunteers as number,
          isPublic: (values.isPublic as boolean) ?? false,
          cutId: values.cutId as string | undefined,
          kind: (values.kind as ShiftKind) || 'CANVASS',
          frequency: values.frequency as 'DAILY' | 'WEEKLY' | 'MONTHLY',
          daysOfWeek: values.frequency === 'WEEKLY' ? (values.daysOfWeek as number[]) : undefined,
          startDate: dayjs(values.startDate as string).format('YYYY-MM-DD'),
          endDate: values.endDate ? dayjs(values.endDate as string).format('YYYY-MM-DD') : undefined,
        };
        await api.post('/map/shifts/series', seriesPayload);
        message.success(`${SHIFT_KIND_LABELS[seriesPayload.kind!]} series created`);
      }

      setCreateDrawerOpen(false);
      createForm.resetFields();
      setCreateMode('single'); // Reset to single mode
      fetchShifts({ page: 1 });
      fetchStats();
      if (activeTab === 'calendar') {
        fetchCalendarData(currentMonth);
      }
    } catch (err: unknown) {
      const msg =
        (err as { response?: { data?: { error?: { message?: string } } } })
          ?.response?.data?.error?.message || `Failed to create ${createMode === 'single' ? 'shift' : 'shift series'}`;
      message.error(msg);
    } finally {
      setCreateLoading(false);
    }
  };

  const handleEdit = async (values: Record<string, unknown>) => {
    if (!editingShift) return;
    try {
      const payload: Record<string, unknown> = {};
      if (values.title !== undefined) payload.title = values.title;
      if (values.description !== undefined) payload.description = values.description || null;
      if (values.date !== undefined) payload.date = dayjs(values.date as string).format('YYYY-MM-DD');
      if (values.startTime !== undefined) payload.startTime = dayjs(values.startTime as string).format('HH:mm');
      if (values.endTime !== undefined) payload.endTime = dayjs(values.endTime as string).format('HH:mm');
      if (values.location !== undefined) payload.location = values.location || null;
      if (values.maxVolunteers !== undefined) payload.maxVolunteers = values.maxVolunteers;
      if (values.isPublic !== undefined) payload.isPublic = values.isPublic;
      if (values.status !== undefined) payload.status = values.status;
      if (values.cutId !== undefined) payload.cutId = values.cutId || null;
      if (values.kind !== undefined) payload.kind = values.kind;
      if (values.kind === 'EVENT_STAFFING') {
        payload.ticketedEventId = (values.ticketedEventId as string) || null;
      } else if (values.kind !== undefined) {
        // Changing away from EVENT_STAFFING clears the link
        payload.ticketedEventId = null;
      }

      await api.put(`/map/shifts/${editingShift.id}`, payload);
      message.success('Shift updated');
      setEditDrawerOpen(false);
      setEditingShift(null);
      editForm.resetFields();
      fetchShifts();
      fetchStats();
    } catch (err: unknown) {
      const msg =
        (err as { response?: { data?: { error?: { message?: string } } } })
          ?.response?.data?.error?.message || 'Failed to update shift';
      message.error(msg);
    }
  };

  const handleDelete = async (id: string) => {
    try {
      await api.delete(`/map/shifts/${id}`);
      message.success('Shift deleted');
      fetchShifts();
      fetchStats();
    } catch {
      message.error('Failed to delete shift');
    }
  };


  const handleEditMode = (editMode: EditMode) => {
    if (!editingSeriesShift) return;

    setEditModeModalOpen(false);

    // If mode is THIS, set isException and break from series
    if (editMode.mode === 'THIS') {
      // Open edit drawer with pre-filled values
      setEditingShift(editingSeriesShift);
      setEditDrawerOpen(true);
    } else {
      // For FUTURE and ALL, show edit drawer with special handling
      setEditingShift(editingSeriesShift);
      setEditDrawerOpen(true);
    }

    setEditingSeriesShift(null);
  };

  const handleEditShift = (shift: Shift) => {
    if (shift.seriesId && !shift.isException) {
      // Part of a series - show edit mode modal
      setEditingSeriesShift(shift);
      setEditModeModalOpen(true);
      // Fetch series shift count
      if (shift.seriesId) {
        api.get(`/api/map/shifts/series/${shift.seriesId}/count`)
          .then((res) => setSeriesShiftCount(res.data.count ?? 0))
          .catch(() => setSeriesShiftCount(0));
      }
    } else {
      // Regular shift or exception - edit normally
      openEdit(shift);
    }
  };

  const openEdit = (shift: Shift) => {
    setEditingShift(shift);
    editForm.setFieldsValue({
      title: shift.title,
      description: shift.description,
      date: dayjs(shift.date),
      startTime: dayjs(shift.startTime, 'HH:mm'),
      endTime: dayjs(shift.endTime, 'HH:mm'),
      location: shift.location,
      maxVolunteers: shift.maxVolunteers,
      isPublic: shift.isPublic,
      status: shift.status,
      cutId: shift.cutId,
      kind: shift.kind || 'CANVASS',
      ticketedEventId: shift.ticketedEventId || undefined,
    });
    setEditDrawerOpen(true);
  };

  const openSignups = async (shift: Shift) => {
    setSignupsShift(shift);
    setSignupsDrawerOpen(true);
    await fetchSignups(shift.id);
  };

  const fetchSignups = async (shiftId: string) => {
    setSignupsLoading(true);
    try {
      const { data } = await api.get<Shift>(`/map/shifts/${shiftId}`);
      setSignups(data.signups || []);
      setSignupsShift(data);
    } catch {
      message.error('Failed to load signups');
    } finally {
      setSignupsLoading(false);
    }
  };

  const handleAddSignup = async () => {
    if (!signupsShift || !addEmail.trim()) return;
    try {
      await api.post(`/map/shifts/${signupsShift.id}/signups`, {
        userEmail: addEmail.trim(),
        userName: addName.trim() || undefined,
      });
      message.success('Volunteer added');
      setAddEmail('');
      setAddName('');
      fetchSignups(signupsShift.id);
      fetchShifts();
      fetchStats();
    } catch (err: unknown) {
      const msg =
        (err as { response?: { data?: { error?: { message?: string } } } })
          ?.response?.data?.error?.message || 'Failed to add volunteer';
      message.error(msg);
    }
  };

  const handleRemoveSignup = async (signupId: string) => {
    if (!signupsShift) return;
    try {
      await api.delete(`/map/shifts/${signupsShift.id}/signups/${signupId}`);
      message.success('Volunteer removed');
      fetchSignups(signupsShift.id);
      fetchShifts();
      fetchStats();
    } catch {
      message.error('Failed to remove volunteer');
    }
  };

  const handleEmailAll = async () => {
    if (!signupsShift) return;
    try {
      const { data } = await api.post<{ sent: number; failed: number }>(
        `/map/shifts/${signupsShift.id}/email-details`
      );
      message.success(`Emailed ${data.sent} volunteer(s)${data.failed ? `, ${data.failed} failed` : ''}`);
    } catch {
      message.error('Failed to email volunteers');
    }
  };

  const columns: ColumnsType<Shift> = [
    {
      title: 'Title',
      dataIndex: 'title',
      key: 'title',
      render: (title: string) => <span style={{ fontWeight: 500 }}>{title}</span>,
    },
    {
      title: 'Date',
      dataIndex: 'date',
      key: 'date',
      render: (date: string) => dayjs(date).format('YYYY-MM-DD'),
    },
    {
      title: 'Time',
      key: 'time',
      render: (_: unknown, record: Shift) => `${record.startTime} — ${record.endTime}`,
      responsive: ['md'],
    },
    {
      title: 'Location',
      dataIndex: 'location',
      key: 'location',
      render: (loc: string | null) => loc || '--',
      responsive: ['lg'],
    },
    {
      title: 'Area',
      key: 'cut',
      render: (_: unknown, record: Shift) => record.cut?.name || '--',
      responsive: ['md'],
    },
    {
      title: 'Volunteers',
      key: 'volunteers',
      width: 140,
      render: (_: unknown, record: Shift) => {
        const confirmed = record._count?.signups ?? record.currentVolunteers;
        const pct = record.maxVolunteers > 0 ? Math.round((confirmed / record.maxVolunteers) * 100) : 0;
        return (
          <div>
            <Progress
              percent={pct}
              size="small"
              status={pct >= 100 ? 'exception' : 'active'}
              format={() => `${confirmed}/${record.maxVolunteers}`}
            />
          </div>
        );
      },
    },
    {
      title: 'Kind',
      dataIndex: 'kind',
      key: 'kind',
      width: 150,
      render: (kind: ShiftKind, record: Shift) => {
        const k = kind || 'CANVASS';
        const tag = (
          <Tag color={SHIFT_KIND_COLORS[k]} icon={KIND_ICONS[k]}>
            {SHIFT_KIND_LABELS[k]}
          </Tag>
        );
        if (record.ticketedEvent) {
          return (
            <Tooltip title={`Event: ${record.ticketedEvent.title}`}>
              <span>{tag}</span>
            </Tooltip>
          );
        }
        return tag;
      },
      responsive: ['md'],
    },
    {
      title: 'Status',
      dataIndex: 'status',
      key: 'status',
      width: 100,
      render: (status: ShiftStatus) => (
        <Tag color={SHIFT_STATUS_COLORS[status]}>{SHIFT_STATUS_LABELS[status]}</Tag>
      ),
    },
    {
      title: 'Public',
      dataIndex: 'isPublic',
      key: 'isPublic',
      width: 70,
      render: (isPublic: boolean) =>
        isPublic ? <CheckCircleOutlined style={{ color: '#52c41a' }} /> : null,
    },
    ...(showMeet ? [{
      title: '',
      key: 'meeting',
      width: 36,
      render: (_: unknown, record: Shift) =>
        record.meeting?.isActive ? (
          <Tooltip title="Video briefing linked">
            <VideoCameraOutlined style={{ color: '#1890ff' }} />
          </Tooltip>
        ) : null,
    }] : []),
    {
      title: 'Actions',
      key: 'actions',
      width: 120,
      render: (_: unknown, record: Shift) => (
        <Space>
          <Tooltip title="Edit">
            <Button
              type="link"
              size="small"
              icon={<EditOutlined />}
              onClick={(e) => { e.stopPropagation(); handleEditShift(record); }}
            />
          </Tooltip>
          <Popconfirm
            title="Delete this shift?"
            onConfirm={(e) => { e?.stopPropagation(); handleDelete(record.id); }}
            onCancel={(e) => e?.stopPropagation()}
          >
            <Tooltip title="Delete">
              <Button
                type="link"
                size="small"
                danger
                icon={<DeleteOutlined />}
                onClick={(e) => e.stopPropagation()}
              />
            </Tooltip>
          </Popconfirm>
        </Space>
      ),
    },
  ];

  const signupColumns: ColumnsType<ShiftSignup> = [
    {
      title: 'Email',
      dataIndex: 'userEmail',
      key: 'userEmail',
    },
    {
      title: 'Name',
      dataIndex: 'userName',
      key: 'userName',
      render: (name: string | null) => name || '--',
    },
    {
      title: 'Phone',
      key: 'phone',
      render: (_: unknown, record: ShiftSignup) =>
        record.userPhone || record.user?.phone || '--',
      responsive: ['md'],
    },
    {
      title: 'Source',
      dataIndex: 'signupSource',
      key: 'signupSource',
      width: 100,
      render: (source: string) => (
        <Tag color={SIGNUP_SOURCE_COLORS[source as keyof typeof SIGNUP_SOURCE_COLORS]}>
          {source}
        </Tag>
      ),
    },
    {
      title: 'Date',
      dataIndex: 'signupDate',
      key: 'signupDate',
      render: (date: string) => dayjs(date).format('YYYY-MM-DD'),
      responsive: ['lg'],
    },
    {
      title: '',
      key: 'remove',
      width: 60,
      render: (_: unknown, record: ShiftSignup) =>
        record.status === 'CONFIRMED' ? (
          <Popconfirm title="Remove this volunteer?" onConfirm={() => handleRemoveSignup(record.id)}>
            <Tooltip title="Remove">
              <Button type="link" size="small" danger icon={<DeleteOutlined />} />
            </Tooltip>
          </Popconfirm>
        ) : (
          <Tag color="red">Cancelled</Tag>
        ),
    },
  ];

  const cutOptions = cuts.map((c) => ({ value: c.id, label: c.name }));

  const openCreateDrawer = useCallback((kind: ShiftKind = 'CANVASS') => {
    createForm.resetFields();
    createForm.setFieldValue('kind', kind);
    setCreateDrawerOpen(true);
  }, [createForm]);

  const createMenuItems: MenuProps['items'] = kindOptions.map((opt) => ({
    key: opt.value,
    label: opt.label,
    icon: KIND_ICONS[opt.value],
    onClick: () => openCreateDrawer(opt.value),
  }));

  const shiftFormFields = (isEdit = false) => (
    <>
      {/* Mode Selector (only for create, not edit) */}
      {!isEdit && (
        <Form.Item label="Type">
          <Segmented
            value={createMode}
            onChange={(value) => setCreateMode(value as 'single' | 'series')}
            options={[
              { label: 'Single Shift', value: 'single' },
              { label: 'Shift Series', value: 'series' },
            ]}
            block
          />
        </Form.Item>
      )}

      <Form.Item
        name="kind"
        label="Kind"
        initialValue="CANVASS"
        rules={[{ required: true, message: 'Kind is required' }]}
      >
        <Select
          options={kindOptions.map((opt) => ({
            value: opt.value,
            label: (
              <Space>
                {KIND_ICONS[opt.value]}
                {opt.label}
              </Space>
            ),
          }))}
          onChange={(value) => {
            // Clear event link when leaving EVENT_STAFFING
            if (value !== 'EVENT_STAFFING') {
              (isEdit ? editForm : createForm).setFieldValue('ticketedEventId', undefined);
            }
          }}
        />
      </Form.Item>
      <Form.Item noStyle shouldUpdate={(prev, curr) => prev.kind !== curr.kind}>
        {({ getFieldValue }) =>
          getFieldValue('kind') === 'EVENT_STAFFING' ? (
            <Form.Item
              name="ticketedEventId"
              label="Event"
              tooltip="Pick the event this shift supports — selecting one will pre-fill the date, time, and location."
            >
              <Select
                placeholder="Select an event"
                showSearch
                allowClear
                optionFilterProp="label"
                options={ticketedEvents.map((ev) => ({
                  value: ev.id,
                  label: `${ev.title} — ${dayjs(ev.date).format('MMM D, YYYY')}`,
                }))}
                onChange={(eventId) => {
                  if (!eventId) return;
                  const ev = ticketedEvents.find((e) => e.id === eventId);
                  if (!ev) return;
                  const form = isEdit ? editForm : createForm;
                  const updates: Record<string, unknown> = {
                    date: dayjs(ev.date),
                    startTime: dayjs(ev.startTime, 'HH:mm'),
                    endTime: dayjs(ev.endTime, 'HH:mm'),
                  };
                  const venue = [ev.venueName, ev.venueAddress].filter(Boolean).join(', ');
                  if (venue) updates.location = venue;
                  // Only seed title if it's empty (don't stomp existing input)
                  if (!form.getFieldValue('title')) {
                    updates.title = `Staff: ${ev.title}`;
                  }
                  form.setFieldsValue(updates);
                }}
              />
            </Form.Item>
          ) : null
        }
      </Form.Item>
      <Form.Item
        name="title"
        label="Title"
        rules={[{ required: true, message: 'Title is required' }]}
      >
        <Input placeholder="e.g. Door Knocking, Phone Banking" />
      </Form.Item>
      <Form.Item name="description" label="Description">
        <Input.TextArea rows={3} placeholder="Shift details and instructions" />
      </Form.Item>

      {/* Date field(s) - conditional based on mode */}
      {createMode === 'single' || isEdit ? (
        <Row gutter={12}>
          <Col xs={24} sm={8}>
            <Form.Item
              name="date"
              label="Date"
              rules={[{ required: true, message: 'Date is required' }]}
            >
              <DatePicker style={{ width: '100%' }} />
            </Form.Item>
          </Col>
          <Col xs={12} sm={8}>
            <Form.Item
              name="startTime"
              label="Start Time"
              rules={[{ required: true, message: 'Required' }]}
            >
              <TimePicker format="HH:mm" style={{ width: '100%' }} minuteStep={5} />
            </Form.Item>
          </Col>
          <Col xs={12} sm={8}>
            <Form.Item
              name="endTime"
              label="End Time"
              rules={[{ required: true, message: 'Required' }]}
            >
              <TimePicker format="HH:mm" style={{ width: '100%' }} minuteStep={5} />
            </Form.Item>
          </Col>
        </Row>
      ) : (
        <>
          <Row gutter={12}>
            <Col xs={12} sm={8}>
              <Form.Item
                name="startTime"
                label="Start Time"
                rules={[{ required: true, message: 'Required' }]}
              >
                <TimePicker format="HH:mm" style={{ width: '100%' }} minuteStep={5} />
              </Form.Item>
            </Col>
            <Col xs={12} sm={8}>
              <Form.Item
                name="endTime"
                label="End Time"
                rules={[{ required: true, message: 'Required' }]}
              >
                <TimePicker format="HH:mm" style={{ width: '100%' }} minuteStep={5} />
              </Form.Item>
            </Col>
          </Row>

          {/* Recurrence Section for Series Mode */}
          <div style={{ marginTop: 16, marginBottom: 16, padding: 16, background: 'rgba(255, 255, 255, 0.05)', borderRadius: 8, border: '1px solid rgba(255, 255, 255, 0.1)' }}>
            <Typography.Title level={5}>Recurrence</Typography.Title>

            <Form.Item
              name="frequency"
              label="Repeat"
              initialValue="WEEKLY"
              rules={[{ required: true }]}
            >
              <Select onChange={(value) => setFrequency(value as RecurrenceFrequency)}>
                <Select.Option value="DAILY">Daily</Select.Option>
                <Select.Option value="WEEKLY">Weekly</Select.Option>
                <Select.Option value="MONTHLY">Monthly</Select.Option>
              </Select>
            </Form.Item>

            {frequency === 'WEEKLY' && (
              <Form.Item
                name="daysOfWeek"
                label="Days of Week"
                rules={[{ required: true, message: 'Select at least one day' }]}
              >
                <Checkbox.Group options={DAYS_OF_WEEK} />
              </Form.Item>
            )}

            <Row gutter={12}>
              <Col xs={12}>
                <Form.Item
                  name="startDate"
                  label="Start Date"
                  rules={[{ required: true, message: 'Required' }]}
                >
                  <DatePicker style={{ width: '100%' }} />
                </Form.Item>
              </Col>
              <Col xs={12}>
                <Form.Item name="endDate" label="End Date (Optional)">
                  <DatePicker style={{ width: '100%' }} />
                </Form.Item>
              </Col>
            </Row>

            {estimatedCount > 0 && (
              <Alert
                message={`This will create approximately ${estimatedCount} shift${estimatedCount > 1 ? 's' : ''}`}
                type="info"
                showIcon
              />
            )}
          </div>
        </>
      )}
      <Form.Item name="location" label="Location">
        <Input placeholder="e.g. Campaign HQ, 123 Main St" />
      </Form.Item>
      <Form.Item name="cutId" label="Area (Cut)">
        <Select
          options={cutOptions}
          placeholder="Assign a canvass area..."
          allowClear
          showSearch
          optionFilterProp="label"
        />
      </Form.Item>
      <Row gutter={12}>
        <Col xs={12} sm={8}>
          <Form.Item
            name="maxVolunteers"
            label="Max Volunteers"
            rules={[{ required: true, message: 'Required' }]}
          >
            <InputNumber min={1} style={{ width: '100%' }} />
          </Form.Item>
        </Col>
        <Col xs={12} sm={8}>
          <Form.Item name="isPublic" label="Public" valuePropName="checked">
            <Switch />
          </Form.Item>
        </Col>
        {isEdit && (
          <Col xs={12} sm={8}>
            <Form.Item name="status" label="Status">
              <Select options={statusOptions} />
            </Form.Item>
          </Col>
        )}
      </Row>
    </>
  );

  const { setPageHeader } = useOutletContext<AppOutletContext>();
  const navigate = useNavigate();

  const headerActions = useMemo(() => (
    <Button
      icon={<TeamOutlined />}
      onClick={() => navigate('/app/map/canvass')}
    >
      Canvass Dashboard
    </Button>
  ), [navigate]);

  useEffect(() => {
    setPageHeader({ title: 'Shifts', actions: headerActions });
    return () => setPageHeader(null);
  }, [setPageHeader, headerActions]);

  // Calculate the active drawer width for content adjustment
  const getActiveDrawerWidth = () => {
    if (createDrawerOpen) return createMode === 'series' ? 700 : 600;
    if (editDrawerOpen) return 520;
    if (signupsDrawerOpen) return 640;
    return 0;
  };

  const activeDrawerWidth = getActiveDrawerWidth();

  return (
    <>
      {/* Main Content Container - shifts when drawer opens */}
      <div
        style={{
          marginRight: isMobile ? 0 : activeDrawerWidth,
          transition: 'margin-right 0.15s cubic-bezier(0.2, 0, 0, 1)',
        }}
      >
        {/* Stats Row */}
        {stats && (
        <Row gutter={[12, 12]} style={{ marginBottom: 16 }}>
          <Col xs={12} sm={4}>
            <Card size="small">
              <Statistic title="Total" value={stats.total} prefix={<ScheduleOutlined />} />
            </Card>
          </Col>
          <Col xs={12} sm={4}>
            <Card size="small">
              <Statistic title="Open" value={stats.open} valueStyle={{ color: '#52c41a' }} prefix={<CheckCircleOutlined />} />
            </Card>
          </Col>
          <Col xs={12} sm={4}>
            <Card size="small">
              <Statistic title="Full" value={stats.full} valueStyle={{ color: '#faad14' }} prefix={<StopOutlined />} />
            </Card>
          </Col>
          <Col xs={12} sm={4}>
            <Card size="small">
              <Statistic title="Cancelled" value={stats.cancelled} valueStyle={{ color: '#ff4d4f' }} prefix={<StopOutlined />} />
            </Card>
          </Col>
          <Col xs={12} sm={4}>
            <Card size="small">
              <Statistic title="Upcoming" value={stats.upcoming} prefix={<ClockCircleOutlined />} />
            </Card>
          </Col>
          <Col xs={12} sm={4}>
            <Card size="small">
              <Statistic title="Signups" value={stats.totalSignups} prefix={<TeamOutlined />} />
            </Card>
          </Col>
        </Row>
      )}

      {/* Tabs: Table and Calendar Views */}
      <Tabs
        activeKey={activeTab}
        onChange={(key) => setActiveTab(key as 'table' | 'calendar')}
        items={[
          {
            key: 'table',
            label: 'Table View',
            children: (
              <>
                {/* Filters */}
                <Row gutter={[12, 12]} style={{ marginBottom: 16 }}>
                  <Col xs={24} sm={12} md={8}>
                    <Input
                      placeholder="Search title or location"
                      prefix={<SearchOutlined />}
                      value={search}
                      onChange={(e) => handleSearchChange(e.target.value)}
                      allowClear
                    />
                  </Col>
                  <Col xs={12} sm={6} md={4}>
                    <Select
                      placeholder="Status"
                      options={statusOptions}
                      value={statusFilter}
                      onChange={setStatusFilter}
                      allowClear
                      style={{ width: '100%' }}
                    />
                  </Col>
                  <Col xs={12} sm={6} md={4}>
                    <Select
                      placeholder="Kind"
                      options={kindOptions.map((opt) => ({
                        value: opt.value,
                        label: (
                          <Space>
                            {KIND_ICONS[opt.value]}
                            {opt.label}
                          </Space>
                        ),
                      }))}
                      value={kindFilter}
                      onChange={setKindFilter}
                      allowClear
                      style={{ width: '100%' }}
                    />
                  </Col>
                </Row>

                {/* Table */}
                <Table<Shift>
                  columns={columns}
                  dataSource={shifts}
                  rowKey="id"
                  loading={loading}
                  pagination={{
                    current: pagination.page,
                    pageSize: pagination.limit,
                    total: pagination.total,
                    showSizeChanger: true,
                    showTotal: (total) => `${total} shifts`,
                  }}
                  onChange={handleTableChange}
                  onRow={(record) => ({
                    onClick: () => openSignups(record),
                    style: { cursor: 'pointer' },
                  })}
                  scroll={{ x: 'max-content' }}
                  locale={{ emptyText: (debouncedSearch || statusFilter || kindFilter)
                    ? 'No shifts match your filters.'
                    : <div style={{ padding: 16 }}>
                        <div style={{ marginBottom: 8, color: 'rgba(255,255,255,0.45)' }}>No shifts yet.</div>
                        <Dropdown.Button
                          type="primary"
                          icon={<PlusOutlined />}
                          menu={{ items: createMenuItems }}
                          onClick={() => openCreateDrawer('CANVASS')}
                        >
                          Create Shift
                        </Dropdown.Button>
                      </div>
                  }}
                />
              </>
            ),
          },
          {
            key: 'calendar',
            label: 'Calendar View',
            children: (
              <div style={{ marginTop: 16 }}>
                <ShiftsCalendar
                  loading={calendarLoading}
                  calendarData={calendarData}
                  onSelectDate={(date) => {
                    // Open create drawer with pre-filled date
                    createForm.setFieldsValue({
                      date: date,
                      startTime: dayjs('09:00', 'HH:mm'),
                      endTime: dayjs('12:00', 'HH:mm'),
                      maxVolunteers: 10,
                      isPublic: false,
                    });
                    setCreateDrawerOpen(true);
                  }}
                  onSelectShift={handleEditShift}
                />
              </div>
            ),
          },
        ]}
        tabBarExtraContent={
          <Dropdown.Button
            type="primary"
            icon={<PlusOutlined />}
            menu={{ items: createMenuItems }}
            onClick={() => openCreateDrawer('CANVASS')}
          >
            Create Shift
          </Dropdown.Button>
        }
      />
      </div>

      {/* Create Drawer */}
      <Drawer
        mask={false}
        title={createMode === 'single' ? 'Create Shift' : 'Create Shift Series'}
        open={createDrawerOpen}
        placement="right"
        width={isMobile ? '100%' : (createMode === 'series' ? 700 : 600)}
        destroyOnHidden
        rootStyle={{ position: 'absolute', top: 64, height: 'calc(100vh - 64px)' }}
        onClose={() => {
          setCreateDrawerOpen(false);
          createForm.resetFields();
          setCreateMode('single'); // Reset to single mode
        }}
        extra={
          <Space>
            <Button onClick={() => {
              setCreateDrawerOpen(false);
              createForm.resetFields();
              setCreateMode('single');
            }} disabled={createLoading}>
              Cancel
            </Button>
            <Button
              type="primary"
              loading={createLoading}
              onClick={() => createForm.submit()}
            >
              {createMode === 'single' ? 'Create Shift' : 'Create Series'}
            </Button>
          </Space>
        }
      >
        <Form form={createForm} onFinish={handleCreate} layout="vertical">
          {shiftFormFields(false)}
        </Form>
      </Drawer>

      {/* Edit Drawer */}
      <Drawer
        title="Edit Shift"
        open={editDrawerOpen}
        width={isMobile ? '100%' : 520}
        mask={false}
        destroyOnHidden
        rootStyle={{ position: 'absolute', top: 64, height: 'calc(100vh - 64px)' }}
        onClose={() => {
          setEditDrawerOpen(false);
          setEditingShift(null);
          editForm.resetFields();
        }}
        extra={
          <Space>
            <Button onClick={() => {
              setEditDrawerOpen(false);
              setEditingShift(null);
              editForm.resetFields();
            }}>
              Cancel
            </Button>
            <Button type="primary" onClick={() => editForm.submit()}>
              Save
            </Button>
          </Space>
        }
      >
        <Form form={editForm} onFinish={handleEdit} layout="vertical">
          {shiftFormFields(true)}
        </Form>

        {/* Video Briefing Section */}
        {showMeet && editingShift && (
          <div style={{
            marginTop: 16,
            padding: 16,
            background: 'rgba(255,255,255,0.04)',
            borderRadius: 8,
            border: '1px solid rgba(255,255,255,0.08)',
          }}>
            <Text strong style={{ fontSize: 13, display: 'block', marginBottom: 8 }}>
              <VideoCameraOutlined style={{ marginRight: 6 }} />
              Video Briefing
            </Text>
            {editingShift.meeting ? (
              <div>
                <div style={{ marginBottom: 8 }}>
                  <Text type="secondary" style={{ fontSize: 12 }}>Meeting: </Text>
                  <Text style={{ fontSize: 13 }}>{editingShift.meeting.title}</Text>
                  <Tag
                    color={editingShift.meeting.isActive ? 'green' : 'default'}
                    style={{ marginLeft: 8, fontSize: 11 }}
                  >
                    {editingShift.meeting.isActive ? 'Active' : 'Ended'}
                  </Tag>
                </div>
                <Space>
                  <Button
                    size="small"
                    icon={<LinkOutlined />}
                    onClick={() => {
                      const link = `${window.location.origin}/meet/${editingShift.meeting!.slug}`;
                      navigator.clipboard.writeText(link);
                      message.success('Guest link copied');
                    }}
                  >
                    Copy Link
                  </Button>
                  <Popconfirm
                    title="Remove video briefing?"
                    description="The meeting will be deleted."
                    onConfirm={async () => {
                      try {
                        await api.delete(`/map/shifts/${editingShift.id}/meeting`);
                        message.success('Video briefing removed');
                        fetchShifts();
                        setEditingShift({ ...editingShift, meeting: null, meetingId: null });
                      } catch {
                        message.error('Failed to remove video briefing');
                      }
                    }}
                  >
                    <Button size="small" danger>Remove</Button>
                  </Popconfirm>
                </Space>
              </div>
            ) : (
              <Button
                size="small"
                icon={<VideoCameraOutlined />}
                onClick={async () => {
                  try {
                    const { data } = await api.post(`/map/shifts/${editingShift.id}/meeting`);
                    message.success('Video briefing created');
                    fetchShifts();
                    setEditingShift({ ...editingShift, meeting: data, meetingId: data.id });
                  } catch (err: unknown) {
                    message.error(getErrorMessage(err, 'Failed to create video briefing'));
                  }
                }}
              >
                Add Video Briefing
              </Button>
            )}
          </div>
        )}
      </Drawer>

      {/* Signups Drawer */}
      <Drawer
        title={
          <Space>
            <TeamOutlined />
            <span>Signups — {signupsShift?.title}</span>
          </Space>
        }
        open={signupsDrawerOpen}
        width={isMobile ? '100%' : 640}
        mask={false}
        destroyOnHidden
        rootStyle={{ position: 'absolute', top: 64, height: 'calc(100vh - 64px)' }}
        onClose={() => {
          setSignupsDrawerOpen(false);
          setSignupsShift(null);
          setSignups([]);
          setAddEmail('');
          setAddName('');
        }}
        extra={
          <Popconfirm
            title={`Email all ${signups.filter((s) => s.status === 'CONFIRMED').length} volunteer(s)?`}
            onConfirm={handleEmailAll}
            disabled={signups.filter((s) => s.status === 'CONFIRMED').length === 0}
          >
            <Button
              icon={<MailOutlined />}
              disabled={signups.filter((s) => s.status === 'CONFIRMED').length === 0}
            >
              Email All
            </Button>
          </Popconfirm>
        }
      >
        {signupsShift && (
          <Card size="small" style={{ marginBottom: 16 }}>
            <Row gutter={12}>
              <Col span={8}>
                <Text type="secondary">Date</Text>
                <br />
                <Text strong>{dayjs(signupsShift.date).format('YYYY-MM-DD')}</Text>
              </Col>
              <Col span={8}>
                <Text type="secondary">Time</Text>
                <br />
                <Text strong>{signupsShift.startTime} — {signupsShift.endTime}</Text>
              </Col>
              <Col span={8}>
                <Text type="secondary">Volunteers</Text>
                <br />
                <Text strong>
                  {signupsShift._count?.signups ?? signupsShift.currentVolunteers} / {signupsShift.maxVolunteers}
                </Text>
              </Col>
            </Row>
          </Card>
        )}

        <Table<ShiftSignup>
          columns={signupColumns}
          dataSource={signups.filter((s) => s.status === 'CONFIRMED')}
          rowKey="id"
          loading={signupsLoading}
          pagination={false}
          size="small"
          locale={{ emptyText: 'No volunteers signed up yet.' }}
        />

        <div style={{ marginTop: 16, display: 'flex', gap: 8 }}>
          <Input
            placeholder="Email"
            value={addEmail}
            onChange={(e) => setAddEmail(e.target.value)}
            style={{ flex: 2 }}
          />
          <Input
            placeholder="Name (optional)"
            value={addName}
            onChange={(e) => setAddName(e.target.value)}
            style={{ flex: 1 }}
          />
          <Button
            type="primary"
            icon={<PlusOutlined />}
            onClick={handleAddSignup}
            disabled={!addEmail.trim()}
          >
            Add
          </Button>
        </div>
      </Drawer>

      {/* Edit Mode Modal */}
      <EditModeModal
        open={editModeModalOpen}
        onCancel={() => {
          setEditModeModalOpen(false);
          setEditingSeriesShift(null);
        }}
        onConfirm={handleEditMode}
        shiftDate={editingSeriesShift?.date || ''}
        shiftsCount={seriesShiftCount}
      />
    </>
  );
}
