import { useMemo, useState, type FormEvent, type ReactElement } from 'react';
import styled from '@lilith/ui-styled-components';
import { Calendar as CalendarIcon, Plus, Trash2, Pencil } from 'lucide-react';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import {
  createEvent,
  deleteEvent,
  fetchCalendars,
  fetchCalendarStats,
  fetchEvents,
  updateEvent,
  type CalendarEvent,
  type CalendarSummary,
  type CalendarStats,
  type EventInput,
} from '@/api/calendar';
import { EmptyState } from '@/components/EmptyState';
import { PageError } from '@/components/PageError';

const Root = styled.div`
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow: hidden;
`;

const PageHeading = styled.h1`
  margin: 0;
  padding: 14px 20px;
  font-size: 18px;
  font-weight: 700;
  color: #e0e0f0;
  border-bottom: 1px solid #2a2a38;
  background: #0a0a0f;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
`;

const Stats = styled.span`
  font-size: 11px;
  color: #8a8a9a;
  font-weight: 500;
`;

const Toolbar = styled.div`
  display: flex;
  gap: 8px;
  padding: 10px 20px;
  border-bottom: 1px solid #1e1e2a;
  background: #0d0d14;
`;

const PrimaryButton = styled.button`
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  font-size: 12px;
  font-weight: 600;
  color: #0a0a0f;
  background: #c9a84c;
  border: 1px solid #c9a84c;
  border-radius: 5px;
  cursor: pointer;

  &:hover { background: #d4b455; }
  &:disabled { opacity: 0.5; cursor: not-allowed; }
`;

const IconButton = styled.button`
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 4px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 4px;
  cursor: pointer;
  color: #8a8a9a;

  &:hover { color: #e0e0f0; border-color: #2a2a38; background: #13131a; }
`;

const FormCard = styled.form`
  margin: 12px 20px;
  padding: 14px;
  background: #13131a;
  border: 1px solid #2a2a38;
  border-radius: 6px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
`;

const Field = styled.label`
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 11px;
  color: #8a8a9a;
`;

const FieldFull = styled(Field)`
  grid-column: 1 / -1;
`;

const Input = styled.input`
  padding: 6px 8px;
  font-size: 12px;
  color: #e0e0f0;
  background: #0a0a0f;
  border: 1px solid #2a2a38;
  border-radius: 4px;
  outline: none;
  &:focus { border-color: #c9a84c; }
`;

const Select = styled.select`
  padding: 6px 8px;
  font-size: 12px;
  color: #e0e0f0;
  background: #0a0a0f;
  border: 1px solid #2a2a38;
  border-radius: 4px;
  outline: none;
  &:focus { border-color: #c9a84c; }
`;

const TextArea = styled.textarea`
  padding: 6px 8px;
  font-size: 12px;
  color: #e0e0f0;
  background: #0a0a0f;
  border: 1px solid #2a2a38;
  border-radius: 4px;
  outline: none;
  min-height: 60px;
  resize: vertical;
  font-family: inherit;
  &:focus { border-color: #c9a84c; }
`;

const FormActions = styled.div`
  grid-column: 1 / -1;
  display: flex;
  gap: 8px;
  justify-content: flex-end;
`;

const SecondaryButton = styled.button`
  padding: 6px 12px;
  font-size: 12px;
  color: #b0b0c0;
  background: transparent;
  border: 1px solid #2a2a38;
  border-radius: 5px;
  cursor: pointer;
  &:hover { color: #e0e0f0; border-color: #4a4a58; }
`;

const List = styled.ul`
  list-style: none;
  margin: 0;
  padding: 0;
  overflow-y: auto;
  flex: 1;
`;

const Row = styled.li`
  padding: 12px 20px;
  border-bottom: 1px solid #1e1e2a;
  display: flex;
  align-items: flex-start;
  gap: 12px;

  &:hover { background: #13131a; }
`;

const RowMain = styled.div`
  flex: 1;
  min-width: 0;
`;

const RowTitle = styled.div`
  font-size: 13px;
  font-weight: 600;
  color: #e0e0f0;
  display: flex;
  align-items: center;
  gap: 8px;
`;

const RowMeta = styled.div`
  font-size: 11px;
  color: #8a8a9a;
  margin-top: 2px;
`;

const RowActions = styled.div`
  display: flex;
  gap: 4px;
`;

const PendingBadge = styled.span`
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: #c9a84c;
  background: rgba(201,168,76,0.12);
  border: 1px solid rgba(201,168,76,0.3);
  border-radius: 3px;
  padding: 1px 5px;
  text-transform: uppercase;
`;

const SpinnerWrap = styled.div`
  padding: 20px;
  font-size: 12px;
  color: #8a8a9a;
  text-align: center;
`;

const DEVICE_ID: string | undefined = undefined;

function toLocalInput(iso: string, allDay: boolean): string {
  const d = new Date(iso);
  if (Number.isNaN(d.getTime())) return '';
  const pad = (n: number): string => String(n).padStart(2, '0');
  const yyyy = d.getFullYear();
  const mm = pad(d.getMonth() + 1);
  const dd = pad(d.getDate());
  if (allDay) return `${yyyy}-${mm}-${dd}`;
  const hh = pad(d.getHours());
  const mi = pad(d.getMinutes());
  return `${yyyy}-${mm}-${dd}T${hh}:${mi}`;
}

function fromLocalInput(value: string, allDay: boolean): string {
  if (!value) return new Date().toISOString();
  if (allDay) return new Date(`${value}T00:00:00`).toISOString();
  return new Date(value).toISOString();
}

function formatRange(ev: CalendarEvent): string {
  const start = new Date(ev.startDate);
  const end = new Date(ev.endDate);
  if (ev.isAllDay) return `${start.toLocaleDateString()} (all day)`;
  const sameDay = start.toDateString() === end.toDateString();
  if (sameDay) {
    return `${start.toLocaleDateString()} ${start.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })} – ${end.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}`;
  }
  return `${start.toLocaleString()} → ${end.toLocaleString()}`;
}

interface FormState {
  calendarIdentifier: string;
  title: string;
  notes: string;
  location: string;
  startDate: string;
  endDate: string;
  isAllDay: boolean;
  url: string;
}

function blankForm(calendars: CalendarSummary[]): FormState {
  const now = new Date();
  const later = new Date(now.getTime() + 60 * 60 * 1000);
  const first = calendars[0];
  return {
    calendarIdentifier: first ? first.identifier : '',
    title: '',
    notes: '',
    location: '',
    startDate: toLocalInput(now.toISOString(), false),
    endDate: toLocalInput(later.toISOString(), false),
    isAllDay: false,
    url: '',
  };
}

function formFromEvent(ev: CalendarEvent): FormState {
  return {
    calendarIdentifier: ev.calendarIdentifier,
    title: ev.title,
    notes: ev.notes ?? '',
    location: ev.location ?? '',
    startDate: toLocalInput(ev.startDate, ev.isAllDay),
    endDate: toLocalInput(ev.endDate, ev.isAllDay),
    isAllDay: ev.isAllDay,
    url: ev.url ?? '',
  };
}

function formToInput(form: FormState): EventInput {
  const input: EventInput = {
    calendarIdentifier: form.calendarIdentifier,
    title: form.title,
    startDate: fromLocalInput(form.startDate, form.isAllDay),
    endDate: fromLocalInput(form.endDate, form.isAllDay),
    isAllDay: form.isAllDay,
    ...(form.notes ? { notes: form.notes } : {}),
    ...(form.location ? { location: form.location } : {}),
    ...(form.url ? { url: form.url } : {}),
  };
  return input;
}

export function CalendarTab(): ReactElement {
  const qc = useQueryClient();
  const [editing, setEditing] = useState<CalendarEvent | null>(null);
  const [creating, setCreating] = useState(false);
  const [pendingIds, setPendingIds] = useState<ReadonlySet<string>>(new Set());

  const statsQ = useQuery<CalendarStats>({
    queryKey: ['calendar-stats'],
    queryFn: fetchCalendarStats,
    refetchInterval: 30_000,
  });
  const calendarsQ = useQuery<CalendarSummary[]>({
    queryKey: ['calendars', DEVICE_ID],
    queryFn: () => fetchCalendars(DEVICE_ID),
  });
  const eventsQ = useQuery<CalendarEvent[]>({
    queryKey: ['calendar-events', DEVICE_ID],
    queryFn: () => fetchEvents({ ...(DEVICE_ID ? { deviceId: DEVICE_ID } : {}), limit: 50 }),
    refetchInterval: 30_000,
  });

  const calendars = useMemo(() => calendarsQ.data ?? [], [calendarsQ.data]);
  const events = eventsQ.data ?? [];

  const [form, setForm] = useState<FormState>(() => blankForm([]));

  const startCreate = (): void => {
    setEditing(null);
    setForm(blankForm(calendars));
    setCreating(true);
  };
  const startEdit = (ev: CalendarEvent): void => {
    setCreating(false);
    setEditing(ev);
    setForm(formFromEvent(ev));
  };
  const cancel = (): void => {
    setEditing(null);
    setCreating(false);
  };

  const markPending = (id: string): void => {
    setPendingIds((prev) => {
      const next = new Set(prev);
      next.add(id);
      return next;
    });
  };

  const createMut = useMutation({
    mutationFn: (input: EventInput) => createEvent(input, DEVICE_ID ?? ''),
    onSuccess: (res) => {
      markPending(res.sendQueueId);
      qc.invalidateQueries({ queryKey: ['calendar-events'] });
      qc.invalidateQueries({ queryKey: ['calendar-stats'] });
      cancel();
    },
  });

  const updateMut = useMutation({
    mutationFn: (vars: { id: string; patch: EventInput }) =>
      updateEvent(vars.id, vars.patch, DEVICE_ID ?? ''),
    onSuccess: (_, vars) => {
      markPending(vars.id);
      qc.invalidateQueries({ queryKey: ['calendar-events'] });
      cancel();
    },
  });

  const deleteMut = useMutation({
    mutationFn: (id: string) => deleteEvent(id, DEVICE_ID ?? ''),
    onSuccess: (_, id) => {
      markPending(id);
      qc.invalidateQueries({ queryKey: ['calendar-events'] });
      qc.invalidateQueries({ queryKey: ['calendar-stats'] });
    },
  });

  const onSubmit = (e: FormEvent<HTMLFormElement>): void => {
    e.preventDefault();
    if (!form.calendarIdentifier || !form.title) return;
    const input = formToInput(form);
    if (editing) {
      updateMut.mutate({ id: editing.eventIdentifier, patch: input });
    } else {
      createMut.mutate(input);
    }
  };

  const onDelete = (ev: CalendarEvent): void => {
    if (window.confirm(`Delete "${ev.title}"?`)) {
      deleteMut.mutate(ev.eventIdentifier);
    }
  };

  const showForm = creating || editing !== null;
  const stats = statsQ.data;
  const statsLine = stats
    ? `${stats.totalEvents} event${stats.totalEvents !== 1 ? 's' : ''} · ${stats.totalCalendars} calendar${stats.totalCalendars !== 1 ? 's' : ''}${stats.lastSyncAt ? ` · synced ${new Date(stats.lastSyncAt).toLocaleTimeString()}` : ''}`
    : '';

  return (
    <Root>
      <PageHeading>
        <span>Calendar</span>
        <Stats>{statsLine}</Stats>
      </PageHeading>
      <Toolbar>
        <PrimaryButton type="button" onClick={startCreate} disabled={calendars.length === 0}>
          <Plus size={13} /> Add event
        </PrimaryButton>
      </Toolbar>

      {showForm && (
        <FormCard onSubmit={onSubmit}>
          <Field>
            <span>Calendar</span>
            <Select
              value={form.calendarIdentifier}
              onChange={(e) => setForm({ ...form, calendarIdentifier: e.target.value })}
              required
            >
              {calendars.map((c) => (
                <option key={c.identifier} value={c.identifier}>{c.title}</option>
              ))}
            </Select>
          </Field>
          <Field>
            <span>Title</span>
            <Input
              type="text"
              value={form.title}
              onChange={(e) => setForm({ ...form, title: e.target.value })}
              required
            />
          </Field>
          <Field>
            <span>Start</span>
            <Input
              type={form.isAllDay ? 'date' : 'datetime-local'}
              value={form.startDate}
              onChange={(e) => setForm({ ...form, startDate: e.target.value })}
              required
            />
          </Field>
          <Field>
            <span>End</span>
            <Input
              type={form.isAllDay ? 'date' : 'datetime-local'}
              value={form.endDate}
              onChange={(e) => setForm({ ...form, endDate: e.target.value })}
              required
            />
          </Field>
          <Field>
            <span>All day</span>
            <label style={{ display: 'flex', alignItems: 'center', gap: 6, color: '#e0e0f0', fontSize: 12 }}>
              <input
                type="checkbox"
                checked={form.isAllDay}
                onChange={(e) => setForm({ ...form, isAllDay: e.target.checked })}
              />
              <span>All-day event</span>
            </label>
          </Field>
          <Field>
            <span>Location</span>
            <Input
              type="text"
              value={form.location}
              onChange={(e) => setForm({ ...form, location: e.target.value })}
            />
          </Field>
          <FieldFull>
            <span>URL</span>
            <Input
              type="url"
              value={form.url}
              onChange={(e) => setForm({ ...form, url: e.target.value })}
            />
          </FieldFull>
          <FieldFull>
            <span>Notes</span>
            <TextArea
              value={form.notes}
              onChange={(e) => setForm({ ...form, notes: e.target.value })}
            />
          </FieldFull>
          <FormActions>
            <SecondaryButton type="button" onClick={cancel}>Cancel</SecondaryButton>
            <PrimaryButton type="submit" disabled={createMut.isPending || updateMut.isPending}>
              {editing ? 'Save changes' : 'Create event'}
            </PrimaryButton>
          </FormActions>
        </FormCard>
      )}

      {eventsQ.isLoading && <SpinnerWrap aria-live="polite">Loading events…</SpinnerWrap>}
      {eventsQ.error && <PageError message="Failed to load events" />}
      {!eventsQ.isLoading && !eventsQ.error && events.length === 0 && !showForm && (
        <EmptyState
          icon={<CalendarIcon size={36} />}
          heading="No events yet"
          sub="Click Add to create one."
        />
      )}
      {!eventsQ.isLoading && events.length > 0 && (
        <List aria-label="Events">
          {events.map((ev) => {
            const isPending =
              pendingIds.has(ev.eventIdentifier) ||
              (deleteMut.isPending && deleteMut.variables === ev.eventIdentifier);
            return (
              <Row key={ev.eventIdentifier}>
                <RowMain>
                  <RowTitle>
                    {ev.title}
                    {isPending && <PendingBadge>Pending sync</PendingBadge>}
                  </RowTitle>
                  <RowMeta>
                    {formatRange(ev)}
                    {ev.location ? ` · ${ev.location}` : ''}
                  </RowMeta>
                </RowMain>
                <RowActions>
                  <IconButton type="button" aria-label="Edit" onClick={() => startEdit(ev)}>
                    <Pencil size={14} />
                  </IconButton>
                  <IconButton type="button" aria-label="Delete" onClick={() => onDelete(ev)}>
                    <Trash2 size={14} />
                  </IconButton>
                </RowActions>
              </Row>
            );
          })}
        </List>
      )}
    </Root>
  );
}
