import { useMemo } from 'react';
import { Select, InputNumber, DatePicker, Space, Typography } from 'antd';
import dayjs from 'dayjs';
import isoWeek from 'dayjs/plugin/isoWeek';
import type { CalendarRecurrenceRule, CalendarRecurrenceFrequency } from '@/types/api';

dayjs.extend(isoWeek);

const { Text } = Typography;

const DAY_LABELS = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
const DAY_VALUES = [1, 2, 3, 4, 5, 6, 7];

interface RecurrenceEditorProps {
  value: CalendarRecurrenceRule | null;
  endDate: string | null;
  onChange: (rule: CalendarRecurrenceRule | null, endDate: string | null) => void;
}

export default function RecurrenceEditor({ value, endDate, onChange }: RecurrenceEditorProps) {
  const frequency = value?.frequency ?? null;
  const interval = value?.interval ?? 1;
  const daysOfWeek = value?.daysOfWeek ?? [];
  const dayOfMonth = value?.dayOfMonth ?? 1;

  const handleFrequencyChange = (freq: CalendarRecurrenceFrequency | 'NONE') => {
    if (freq === 'NONE') {
      onChange(null, null);
      return;
    }
    const rule: CalendarRecurrenceRule = { frequency: freq, interval: 1 };
    if (freq === 'WEEKLY' || freq === 'BIWEEKLY') {
      rule.daysOfWeek = daysOfWeek.length > 0 ? daysOfWeek : [dayjs().isoWeekday()];
    }
    if (freq === 'MONTHLY') {
      rule.dayOfMonth = dayOfMonth || dayjs().date();
    }
    onChange(rule, endDate);
  };

  const handleIntervalChange = (val: number | null) => {
    if (!value) return;
    onChange({ ...value, interval: val ?? 1 }, endDate);
  };

  const handleDaysOfWeekToggle = (day: number) => {
    if (!value) return;
    const current = value.daysOfWeek ?? [];
    const next = current.includes(day)
      ? current.filter(d => d !== day)
      : [...current, day].sort((a, b) => a - b);
    // Must have at least one day selected
    if (next.length === 0) return;
    onChange({ ...value, daysOfWeek: next }, endDate);
  };

  const handleDayOfMonthChange = (val: number | null) => {
    if (!value) return;
    onChange({ ...value, dayOfMonth: val ?? 1 }, endDate);
  };

  const handleEndDateChange = (date: dayjs.Dayjs | null) => {
    onChange(value, date ? date.format('YYYY-MM-DD') : null);
  };

  const previewText = useMemo(() => {
    if (!value) return '';
    const { frequency: freq } = value;
    const intv = value.interval ?? 1;

    if (freq === 'DAILY') {
      return intv === 1 ? 'Every day' : `Every ${intv} days`;
    }

    if (freq === 'WEEKLY' || freq === 'BIWEEKLY') {
      const days = (value.daysOfWeek ?? [])
        .map(d => DAY_LABELS[d - 1])
        .join(', ');
      const base = freq === 'BIWEEKLY'
        ? 'Every 2 weeks'
        : intv === 1
          ? 'Every week'
          : `Every ${intv} weeks`;
      return days ? `${base} on ${days}` : base;
    }

    if (freq === 'MONTHLY') {
      const dom = value.dayOfMonth ?? 1;
      const suffix = dom === 1 ? 'st' : dom === 2 ? 'nd' : dom === 3 ? 'rd' : 'th';
      return intv === 1
        ? `Every month on the ${dom}${suffix}`
        : `Every ${intv} months on the ${dom}${suffix}`;
    }

    return '';
  }, [value]);

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
      <div>
        <Text type="secondary" style={{ fontSize: 12, display: 'block', marginBottom: 4 }}>
          Repeats
        </Text>
        <Select
          value={frequency ?? 'NONE'}
          onChange={handleFrequencyChange}
          style={{ width: '100%' }}
          options={[
            { value: 'NONE', label: 'Does not repeat' },
            { value: 'DAILY', label: 'Daily' },
            { value: 'WEEKLY', label: 'Weekly' },
            { value: 'BIWEEKLY', label: 'Bi-weekly' },
            { value: 'MONTHLY', label: 'Monthly' },
          ]}
        />
      </div>

      {frequency && frequency !== 'BIWEEKLY' && (
        <div>
          <Text type="secondary" style={{ fontSize: 12, display: 'block', marginBottom: 4 }}>
            Every
          </Text>
          <Space>
            <InputNumber
              min={1}
              max={52}
              value={interval}
              onChange={handleIntervalChange}
              style={{ width: 70 }}
            />
            <Text type="secondary">
              {frequency === 'DAILY' ? 'day(s)' : frequency === 'MONTHLY' ? 'month(s)' : 'week(s)'}
            </Text>
          </Space>
        </div>
      )}

      {(frequency === 'WEEKLY' || frequency === 'BIWEEKLY') && (
        <div>
          <Text type="secondary" style={{ fontSize: 12, display: 'block', marginBottom: 4 }}>
            On days
          </Text>
          <div style={{ display: 'flex', gap: 4, flexWrap: 'wrap' }}>
            {DAY_VALUES.map((day, idx) => {
              const selected = daysOfWeek.includes(day);
              return (
                <div
                  key={day}
                  onClick={() => handleDaysOfWeekToggle(day)}
                  style={{
                    width: 38,
                    height: 30,
                    display: 'flex',
                    alignItems: 'center',
                    justifyContent: 'center',
                    borderRadius: 15,
                    fontSize: 12,
                    fontWeight: selected ? 600 : 400,
                    cursor: 'pointer',
                    userSelect: 'none',
                    background: selected ? 'rgba(24, 144, 255, 0.3)' : 'rgba(255,255,255,0.06)',
                    border: selected ? '1px solid rgba(24, 144, 255, 0.6)' : '1px solid rgba(255,255,255,0.12)',
                    color: selected ? '#1890ff' : 'rgba(255,255,255,0.65)',
                    transition: 'all 0.2s',
                  }}
                >
                  {DAY_LABELS[idx]}
                </div>
              );
            })}
          </div>
        </div>
      )}

      {frequency === 'MONTHLY' && (
        <div>
          <Text type="secondary" style={{ fontSize: 12, display: 'block', marginBottom: 4 }}>
            Day of month
          </Text>
          <InputNumber
            min={1}
            max={31}
            value={dayOfMonth}
            onChange={handleDayOfMonthChange}
            style={{ width: 80 }}
          />
        </div>
      )}

      {frequency && (
        <div>
          <Text type="secondary" style={{ fontSize: 12, display: 'block', marginBottom: 4 }}>
            Ends
          </Text>
          <Space>
            <Select
              value={endDate ? 'on_date' : 'never'}
              onChange={(val) => {
                if (val === 'never') {
                  onChange(value, null);
                } else {
                  onChange(value, dayjs().add(3, 'month').format('YYYY-MM-DD'));
                }
              }}
              style={{ width: 120 }}
              options={[
                { value: 'never', label: 'Never' },
                { value: 'on_date', label: 'On date' },
              ]}
            />
            {endDate && (
              <DatePicker
                value={dayjs(endDate)}
                onChange={handleEndDateChange}
                disabledDate={(d) => d.isBefore(dayjs(), 'day')}
              />
            )}
          </Space>
        </div>
      )}

      {frequency && previewText && (
        <Text
          style={{
            fontSize: 12,
            color: 'rgba(255,255,255,0.45)',
            fontStyle: 'italic',
            padding: '4px 0',
          }}
        >
          {previewText}
          {endDate ? `, until ${dayjs(endDate).format('MMM D, YYYY')}` : ''}
        </Text>
      )}
    </div>
  );
}
