"use client";

import dynamic from "next/dynamic";
import { useEffect, useMemo, useState, useTransition } from "react";
import { ReminderPicker } from "@/components/reminder-picker";
import { Button } from "@/components/ui/button";
import {
  Dialog,
  DialogContent,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
  Select,
  SelectContent,
  SelectGroup,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { createEvent } from "@/modules/calendar/server/actions";
import { richTextToPlainText } from "@/components/rich-text";
import {
  getDefaultEventReminderOffsets,
  listCalendars,
  type CalendarDto,
} from "@/modules/calendar/server/queries";

const RichTextEditor = dynamic(
  () => import("@/components/rich-text/rich-text-editor").then((mod) => mod.RichTextEditor),
  {
    ssr: false,
    loading: () => (
      <div className="min-h-24 rounded-lg border border-input px-3 py-2 text-sm text-muted-foreground animate-pulse">
        Loading editor…
      </div>
    ),
  },
);

type Props = {
  open: boolean;
  onOpenChange: (open: boolean) => void;
};

export function CalendarEventCreateDialog({ open, onOpenChange }: Props) {
  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="sm:max-w-2xl">
        {open ? <CalendarEventCreateForm onDone={() => onOpenChange(false)} /> : null}
      </DialogContent>
    </Dialog>
  );
}

function CalendarEventCreateForm({ onDone }: { onDone: () => void }) {
  const [calendars, setCalendars] = useState<CalendarDto[]>([]);
  const [calendarId, setCalendarId] = useState("");
  const [title, setTitle] = useState("");
  const [startAt, setStartAt] = useState(() => toInputDateTime(new Date()));
  const [endAt, setEndAt] = useState(() => toInputDateTime(new Date(Date.now() + 60 * 60 * 1000)));
  const [location, setLocation] = useState("");
  const [notes, setNotes] = useState("");
  const [reminderOffsets, setReminderOffsets] = useState<number[]>([30]);
  const [isPending, startTransition] = useTransition();

  useEffect(() => {
    listCalendars().then((rows) => {
      setCalendars(rows);
      setCalendarId(rows[0]?.id ?? "");
    });
    getDefaultEventReminderOffsets().then(setReminderOffsets);
  }, []);

  const calendarItems = useMemo(
    () => calendars.map((c) => ({ label: c.name, value: c.id })),
    [calendars],
  );

  function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    if (!calendarId || !title.trim()) return;
    startTransition(async () => {
      await createEvent({
        calendarId,
        title: title.trim(),
        startAt: new Date(startAt),
        endAt: new Date(endAt),
        allDay: false,
        location: location || null,
        notes: richTextToPlainText(notes) ? notes : null,
        reminderOffsets,
      });
      onDone();
    });
  }

  return (
    <>
      <DialogHeader>
        <DialogTitle>New event</DialogTitle>
      </DialogHeader>
      <form id="quick-add-event-form" onSubmit={handleSubmit} className="grid gap-3">
        <div className="space-y-1.5">
          <Label htmlFor="qa-event-title">Title</Label>
          <Input
            id="qa-event-title"
            value={title}
            onChange={(e) => setTitle(e.target.value)}
            required
          />
        </div>
        <div className="space-y-1.5">
          <Label htmlFor="qa-event-calendar">Calendar</Label>
          <Select
            items={calendarItems}
            value={calendarId}
            onValueChange={(value) => setCalendarId(value ?? "")}
          >
            <SelectTrigger id="qa-event-calendar">
              <SelectValue>
                {calendars.find((c) => c.id === calendarId)?.name ?? "Select a calendar"}
              </SelectValue>
            </SelectTrigger>
            <SelectContent>
              <SelectGroup>
                {calendarItems.map((item) => (
                  <SelectItem key={item.value} value={item.value}>
                    {item.label}
                  </SelectItem>
                ))}
              </SelectGroup>
            </SelectContent>
          </Select>
        </div>
        <div className="grid gap-3 sm:grid-cols-2">
          <div className="space-y-1.5">
            <Label htmlFor="qa-event-start">Start</Label>
            <Input
              id="qa-event-start"
              type="datetime-local"
              value={startAt}
              onChange={(e) => setStartAt(e.target.value)}
              required
            />
          </div>
          <div className="space-y-1.5">
            <Label htmlFor="qa-event-end">End</Label>
            <Input
              id="qa-event-end"
              type="datetime-local"
              value={endAt}
              onChange={(e) => setEndAt(e.target.value)}
              required
            />
          </div>
        </div>
        <div className="space-y-1.5">
          <Label htmlFor="qa-event-location">Location</Label>
          <Input
            id="qa-event-location"
            value={location}
            onChange={(e) => setLocation(e.target.value)}
          />
        </div>
        <div className="space-y-1.5 min-w-0">
          <Label htmlFor="qa-event-notes">Notes</Label>
          <RichTextEditor
            id="qa-event-notes"
            aria-label="Notes"
            value={notes}
            onChange={setNotes}
            disabled={isPending}
            placeholder="Add details…"
          />
        </div>
        <ReminderPicker
          offsets={reminderOffsets}
          onChange={setReminderOffsets}
          disabled={isPending}
        />
      </form>
      <DialogFooter>
        <Button type="submit" form="quick-add-event-form" disabled={!title.trim() || isPending}>
          Save event
        </Button>
      </DialogFooter>
    </>
  );
}

function toInputDateTime(date: Date) {
  const offset = date.getTimezoneOffset();
  const local = new Date(date.getTime() - offset * 60 * 1000);
  return local.toISOString().slice(0, 16);
}
