import React, { useEffect, useMemo, useRef, useState } from 'react';
import FocusTrap from 'focus-trap-react';
import {
  Box,
  Button,
  color,
  config,
  Dialog,
  Header,
  Icon,
  IconButton,
  Icons,
  Line,
  Overlay,
  OverlayBackdrop,
  OverlayCenter,
  Text,
} from 'folds';
import { stopPropagation } from '../../../utils/keyboard';
import { useReminders } from '../../../hooks/useReminders';
import { useModalStyle } from '../../../hooks/useModalStyle';
import {
  toLocalDate,
  toLocalTime,
  parseLocalDateTime,
  pickerInputStyle,
  formatFriendlyDateTime,
} from '../../../utils/datetimeInput';

type RemindMeDialogProps = {
  roomId: string;
  eventId: string;
  previewText: string;
  onClose: () => void;
};

function getPresets(): Array<{ label: string; ms: number }> {
  const tomorrow = new Date();
  tomorrow.setDate(tomorrow.getDate() + 1);
  tomorrow.setHours(9, 0, 0, 0);
  const timeLabel = tomorrow.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
  return [
    { label: 'In 20 minutes', ms: 20 * 60_000 },
    { label: 'In 1 hour', ms: 60 * 60_000 },
    { label: 'In 3 hours', ms: 3 * 60 * 60_000 },
    { label: `Tomorrow at ${timeLabel}`, ms: tomorrow.getTime() - Date.now() },
  ];
}

// Default custom pick: 1 hour from now, rounded up to the nearest 5 minutes.
function defaultCustomDate(): Date {
  const d = new Date(Date.now() + 60 * 60 * 1000);
  d.setSeconds(0, 0);
  d.setMinutes(Math.ceil(d.getMinutes() / 5) * 5);
  return d;
}

export function RemindMeDialog({ roomId, eventId, previewText, onClose }: RemindMeDialogProps) {
  const modalStyle = useModalStyle(320);
  const { addReminder, removeReminder, reminders } = useReminders();
  const presets = useMemo(() => getPresets(), []);
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [customOpen, setCustomOpen] = useState(false);
  const def = useMemo(() => defaultCustomDate(), []);
  const [dateValue, setDateValue] = useState(() => toLocalDate(def));
  const [timeValue, setTimeValue] = useState(() => toLocalTime(def));
  const dateInputRef = useRef<HTMLInputElement>(null);

  // Reminders already set on this message (soonest first) — so the user can see
  // and cancel them instead of silently stacking duplicates.
  const existing = useMemo(
    () => reminders.filter((r) => r.eventId === eventId).sort((a, b) => a.timestamp - b.timestamp),
    [reminders, eventId],
  );

  // Move focus into the revealed date input for keyboard/SR users.
  useEffect(() => {
    if (customOpen) dateInputRef.current?.focus();
  }, [customOpen]);

  const handleCancelExisting = (timestamp: number) => {
    // Optimistic, matching removeBookmark: the shared account-data store drops
    // the reminder locally at once (no rollback) and re-syncs from the server.
    // We deliberately show no inline error — the store has no rollback path, so a
    // failed write simply reappears on the next sync rather than leaving a stale
    // "couldn't cancel" message beside an already-vanished row.
    removeReminder(eventId, timestamp).catch(() => undefined);
  };

  const commit = async (timestamp: number) => {
    if (busy) return;
    setBusy(true);
    setError(null);
    try {
      await addReminder({
        roomId,
        eventId,
        timestamp,
        message: previewText || 'Reminder',
      });
      onClose();
    } catch {
      setBusy(false);
      setError('Could not set reminder. Try again.');
    }
  };

  const handlePick = (ms: number) => commit(Date.now() + ms);

  const customDate = parseLocalDateTime(dateValue, timeValue);
  const customValid = !!customDate && customDate.getTime() - Date.now() >= 60_000;

  const handleCustom = () => {
    if (!customDate) {
      setError('Please select a valid date and time.');
      return;
    }
    if (customDate.getTime() - Date.now() < 60_000) {
      setError('Reminder time must be at least 1 minute in the future.');
      return;
    }
    commit(customDate.getTime());
  };

  return (
    <Overlay open backdrop={<OverlayBackdrop />}>
      <OverlayCenter>
        <FocusTrap
          focusTrapOptions={{
            initialFocus: false,
            onDeactivate: onClose,
            clickOutsideDeactivates: true,
            escapeDeactivates: stopPropagation,
          }}
        >
          <Dialog
            variant="Surface"
            role="dialog"
            aria-modal="true"
            aria-labelledby="remind-me-title"
            style={modalStyle}
          >
            <Header
              variant="Surface"
              size="500"
              style={{
                padding: `0 ${config.space.S200} 0 ${config.space.S400}`,
                borderBottomWidth: config.borderWidth.B300,
              }}
            >
              <Box grow="Yes" alignItems="Center" gap="200">
                <Icon src={Icons.Clock} size="100" />
                <Text id="remind-me-title" size="H4">
                  Remind Me
                </Text>
              </Box>
              <IconButton size="300" radii="300" onClick={onClose} aria-label="Close">
                <Icon src={Icons.Cross} />
              </IconButton>
            </Header>
            {previewText && (
              <>
                <Box style={{ padding: `${config.space.S200} ${config.space.S400}` }}>
                  <Text size="T200" priority="300" truncate>
                    {previewText}
                  </Text>
                </Box>
                <Line size="300" />
              </>
            )}
            {existing.length > 0 && (
              <>
                <Box
                  direction="Column"
                  gap="100"
                  style={{ padding: `${config.space.S200} ${config.space.S200} 0` }}
                >
                  <Text size="L400" priority="300" style={{ paddingLeft: config.space.S200 }}>
                    {existing.length === 1 ? 'Reminder set' : 'Reminders set'}
                  </Text>
                  {existing.map((r, idx) => (
                    // Composite key: two custom reminders on one message can share
                    // a minute-precision timestamp; index keeps React keys unique.
                    <Box key={`${r.timestamp}-${idx}`} alignItems="Center" gap="200">
                      <Icon src={Icons.Clock} size="100" style={{ flexShrink: 0 }} />
                      <Text size="T200" style={{ flexGrow: 1, minWidth: 0 }} truncate>
                        {formatFriendlyDateTime(r.timestamp)}
                      </Text>
                      <IconButton
                        size="300"
                        radii="300"
                        variant="SurfaceVariant"
                        fill="None"
                        onClick={() => handleCancelExisting(r.timestamp)}
                        aria-label={`Cancel reminder for ${formatFriendlyDateTime(r.timestamp)}`}
                      >
                        <Icon src={Icons.Cross} size="100" />
                      </IconButton>
                    </Box>
                  ))}
                </Box>
                <Line size="300" style={{ marginTop: config.space.S200 }} />
              </>
            )}
            <Box direction="Column" gap="100" style={{ padding: config.space.S200 }}>
              {presets.map((p) => (
                <Button
                  key={p.label}
                  size="300"
                  variant="Secondary"
                  fill="Soft"
                  radii="300"
                  disabled={busy}
                  onClick={() => handlePick(p.ms)}
                >
                  <Text size="B300" truncate>
                    {p.label}
                  </Text>
                </Button>
              ))}

              {customOpen ? (
                <Box direction="Column" gap="200" style={{ paddingTop: config.space.S100 }}>
                  <Box gap="200">
                    <Box direction="Column" gap="100" style={{ flex: 1 }}>
                      <Text as="label" htmlFor="remind-date" size="T200" priority="400">
                        Date
                      </Text>
                      <input
                        ref={dateInputRef}
                        id="remind-date"
                        type="date"
                        value={dateValue}
                        min={toLocalDate(new Date())}
                        disabled={busy}
                        onChange={(e) => {
                          setDateValue(e.target.value);
                          setError(null);
                        }}
                        style={pickerInputStyle(color, config)}
                      />
                    </Box>
                    <Box direction="Column" gap="100" style={{ flex: 1 }}>
                      <Text as="label" htmlFor="remind-time" size="T200" priority="400">
                        Time
                      </Text>
                      <input
                        id="remind-time"
                        type="time"
                        value={timeValue}
                        disabled={busy}
                        onChange={(e) => {
                          setTimeValue(e.target.value);
                          setError(null);
                        }}
                        style={pickerInputStyle(color, config)}
                      />
                    </Box>
                  </Box>
                  {!customValid && (dateValue || timeValue) && (
                    <Text size="T200" style={{ color: color.Critical.Main }}>
                      Must be at least 1 minute in the future
                    </Text>
                  )}
                  <Button
                    size="300"
                    variant="Primary"
                    radii="300"
                    disabled={busy || !customValid}
                    onClick={handleCustom}
                  >
                    <Text size="B300">Set reminder</Text>
                  </Button>
                </Box>
              ) : (
                <Button
                  size="300"
                  variant="Secondary"
                  fill="None"
                  radii="300"
                  disabled={busy}
                  onClick={() => {
                    setError(null);
                    setCustomOpen(true);
                  }}
                  before={<Icon src={Icons.Clock} size="100" />}
                >
                  <Text size="B300">Custom time…</Text>
                </Button>
              )}

              {error && (
                <Text
                  size="T200"
                  style={{ color: color.Critical.Main, paddingTop: config.space.S100 }}
                >
                  {error}
                </Text>
              )}
            </Box>
          </Dialog>
        </FocusTrap>
      </OverlayCenter>
    </Overlay>
  );
}
