import { Drawer, DatePicker, Select, Space, Alert, Switch, Button, message, Grid } from 'antd';
import { ClockCircleOutlined } from '@ant-design/icons';
import { useState, useEffect } from 'react';
import dayjs, { Dayjs } from 'dayjs';
import utc from 'dayjs/plugin/utc';
import timezone from 'dayjs/plugin/timezone';
import { mediaApi } from '@/lib/media-api';
import type { Video } from '@/types/media';
import { getErrorMessage } from '@/utils/getErrorMessage';

dayjs.extend(utc);
dayjs.extend(timezone);

interface SchedulePublishModalProps {
  video: Video | null;
  open: boolean;
  onClose: () => void;
  onSuccess?: () => void;
}

// Common timezones
const TIMEZONES = [
  { value: 'UTC', label: 'UTC (Coordinated Universal Time)' },
  { value: 'America/New_York', label: 'EST (Eastern Standard Time)' },
  { value: 'America/Chicago', label: 'CST (Central Standard Time)' },
  { value: 'America/Denver', label: 'MST (Mountain Standard Time)' },
  { value: 'America/Los_Angeles', label: 'PST (Pacific Standard Time)' },
  { value: 'America/Toronto', label: 'Toronto (Canada)' },
  { value: 'America/Vancouver', label: 'Vancouver (Canada)' },
  { value: 'Europe/London', label: 'GMT (London)' },
  { value: 'Europe/Paris', label: 'CET (Paris)' },
  { value: 'Asia/Tokyo', label: 'JST (Tokyo)' },
  { value: 'Australia/Sydney', label: 'AEDT (Sydney)' },
];

export default function SchedulePublishModal({
  video,
  open,
  onClose,
  onSuccess,
}: SchedulePublishModalProps) {
  const [publishNow, setPublishNow] = useState(false);
  const screens = Grid.useBreakpoint();
  const isMobile = !screens.md;
  const [publishAt, setPublishAt] = useState<Dayjs | null>(null);
  const [selectedTimezone, setSelectedTimezone] = useState<string>('UTC');
  const [unpublishEnabled, setUnpublishEnabled] = useState(false);
  const [unpublishAt, setUnpublishAt] = useState<Dayjs | null>(null);
  const [loading, setLoading] = useState(false);

  // Reset state when modal opens
  useEffect(() => {
    if (open && video) {
      setPublishNow(!video.scheduledPublishAt);
      setPublishAt(video.scheduledPublishAt ? dayjs(video.scheduledPublishAt) : dayjs().add(1, 'hour'));
      setUnpublishEnabled(!!video.scheduledUnpublishAt);
      setUnpublishAt(video.scheduledUnpublishAt ? dayjs(video.scheduledUnpublishAt) : null);
      setSelectedTimezone(dayjs.tz.guess() || 'UTC'); // Auto-detect user timezone
    }
  }, [open, video]);

  const handleSchedule = async () => {
    if (!video) return;

    try {
      setLoading(true);

      if (publishNow) {
        // Publish immediately by updating video
        await mediaApi.patch(`/videos/${video.id}`, {
          isPublished: true,
        });
        message.success('Video published successfully');
      } else {
        if (!publishAt) {
          message.error('Please select a publish date/time');
          return;
        }

        // Convert to UTC for backend
        const publishDateUTC = publishAt.tz(selectedTimezone).utc().toISOString();

        // Schedule publish
        await mediaApi.post(`/videos/${video.id}/schedule-publish`, {
          publishAt: publishDateUTC,
          timezone: selectedTimezone,
        });

        message.success(`Video scheduled to publish at ${publishAt.tz(selectedTimezone).format('YYYY-MM-DD HH:mm')} ${selectedTimezone}`);
      }

      // Handle unpublish if enabled
      if (unpublishEnabled && unpublishAt) {
        const unpublishDateUTC = unpublishAt.tz(selectedTimezone).utc().toISOString();
        await mediaApi.post(`/videos/${video.id}/schedule-unpublish`, {
          unpublishAt: unpublishDateUTC,
          timezone: selectedTimezone,
        });
        message.success(`Video scheduled to unpublish at ${unpublishAt.tz(selectedTimezone).format('YYYY-MM-DD HH:mm')} ${selectedTimezone}`);
      }

      onSuccess?.();
      onClose();
    } catch (error: unknown) {
      message.error(getErrorMessage(error, 'Failed to schedule video'));
    } finally {
      setLoading(false);
    }
  };

  const handleCancelSchedule = async (action: 'publish' | 'unpublish') => {
    if (!video) return;

    try {
      setLoading(true);
      await mediaApi.delete(`/videos/${video.id}/schedule/${action}`);
      message.success(`${action} schedule cancelled`);
      onSuccess?.();
      onClose();
    } catch (error: unknown) {
      message.error(getErrorMessage(error, `Failed to cancel ${action} schedule`));
    } finally {
      setLoading(false);
    }
  };

  // Disable dates in the past
  const disabledDate = (current: Dayjs) => {
    return current && current < dayjs().startOf('day');
  };

  // Disable times in the past for today
  const disabledDateTime = () => {
    const now = dayjs();
    return {
      disabledHours: () => {
        if (publishAt?.isSame(now, 'day')) {
          return Array.from({ length: now.hour() }, (_, i) => i);
        }
        return [];
      },
      disabledMinutes: (selectedHour: number) => {
        if (publishAt?.isSame(now, 'day') && selectedHour === now.hour()) {
          return Array.from({ length: now.minute() + 1 }, (_, i) => i);
        }
        return [];
      },
    };
  };

  const localTime = publishAt?.tz(selectedTimezone).format('YYYY-MM-DD HH:mm:ss');
  const serverTime = publishAt?.utc().format('YYYY-MM-DD HH:mm:ss UTC');

  return (
    <Drawer
      title={
        <Space>
          <ClockCircleOutlined />
          Schedule Publishing
        </Space>
      }
      open={open}
      onClose={onClose}
      width={isMobile ? '95vw' : 600}
      placement="right"
      mask={false}
      rootStyle={{ position: 'absolute', top: 64, height: 'calc(100vh - 64px)' }}
      extra={
        <Button type="primary" onClick={handleSchedule} loading={loading}>
          {publishNow ? 'Publish Now' : 'Schedule'}
        </Button>
      }
      aria-label="Schedule video publishing"
    >
      {video && (
        <div>
          <div style={{ marginBottom: 16 }}>
            <strong>Video:</strong> {video.title || video.filename}
          </div>

          {/* Publish Now Toggle */}
          <div style={{ marginBottom: 16 }}>
            <Space>
              <Switch
                checked={publishNow}
                onChange={setPublishNow}
                aria-label="Toggle publish now"
              />
              <span>Publish immediately</span>
            </Space>
          </div>

          {!publishNow && (
            <>
              {/* Timezone Selector */}
              <div style={{ marginBottom: 16 }}>
                <label style={{ display: 'block', marginBottom: 8 }}>
                  <strong>Timezone:</strong>
                </label>
                <Select
                  style={{ width: '100%' }}
                  value={selectedTimezone}
                  onChange={setSelectedTimezone}
                  options={TIMEZONES}
                  showSearch
                  filterOption={(input, option) =>
                    (option?.label ?? '').toLowerCase().includes(input.toLowerCase())
                  }
                />
              </div>

              {/* Publish Date/Time */}
              <div style={{ marginBottom: 16 }}>
                <label style={{ display: 'block', marginBottom: 8 }}>
                  <strong>Publish Date & Time:</strong>
                </label>
                <DatePicker
                  showTime
                  format="YYYY-MM-DD HH:mm"
                  value={publishAt}
                  onChange={setPublishAt}
                  disabledDate={disabledDate}
                  disabledTime={disabledDateTime}
                  style={{ width: '100%' }}
                  placeholder="Select publish date and time"
                />
              </div>

              {/* Time Preview */}
              {publishAt && (
                <Alert
                  type="info"
                  message="Time Preview"
                  description={
                    <div>
                      <div><strong>Local Time ({selectedTimezone}):</strong> {localTime}</div>
                      <div><strong>Server Time:</strong> {serverTime}</div>
                    </div>
                  }
                  style={{ marginBottom: 16 }}
                />
              )}

              {/* Auto-unpublish Toggle */}
              <div style={{ marginBottom: 16 }}>
                <Space>
                  <Switch
                    checked={unpublishEnabled}
                    onChange={setUnpublishEnabled}
                    aria-label="Toggle auto-unpublish"
                  />
                  <span>Auto-unpublish after a period</span>
                </Space>
              </div>

              {/* Unpublish Date/Time */}
              {unpublishEnabled && (
                <div style={{ marginBottom: 16 }}>
                  <label style={{ display: 'block', marginBottom: 8 }}>
                    <strong>Unpublish Date & Time:</strong>
                  </label>
                  <DatePicker
                    showTime
                    format="YYYY-MM-DD HH:mm"
                    value={unpublishAt}
                    onChange={setUnpublishAt}
                    disabledDate={(current) => {
                      // Unpublish must be after publish
                      return !!(current && (current < dayjs().startOf('day') || (publishAt && current <= publishAt)));
                    }}
                    style={{ width: '100%' }}
                    placeholder="Select unpublish date and time"
                  />
                </div>
              )}
            </>
          )}

          {/* Cancel existing schedules */}
          {(video.scheduledPublishAt || video.scheduledUnpublishAt) && (
            <div style={{ marginTop: 16 }}>
              <Alert
                type="warning"
                message="Existing Schedules"
                description={
                  <Space direction="vertical" style={{ width: '100%' }}>
                    {video.scheduledPublishAt && (
                      <div>
                        <div>Publish scheduled for: {dayjs(video.scheduledPublishAt).format('YYYY-MM-DD HH:mm UTC')}</div>
                        <a onClick={() => handleCancelSchedule('publish')}>Cancel publish schedule</a>
                      </div>
                    )}
                    {video.scheduledUnpublishAt && (
                      <div>
                        <div>Unpublish scheduled for: {dayjs(video.scheduledUnpublishAt).format('YYYY-MM-DD HH:mm UTC')}</div>
                        <a onClick={() => handleCancelSchedule('unpublish')}>Cancel unpublish schedule</a>
                      </div>
                    )}
                  </Space>
                }
              />
            </div>
          )}
        </div>
      )}
    </Drawer>
  );
}
