import { format, parseISO } from "date-fns";
import { AlertTriangle, ArrowLeft, ArrowRight, DollarSign, Flag, Smile } from "lucide-react";
import { useEffect, useRef, useState } from "react";
import { createPortal } from "react-dom";

const MILESTONE_ICONS = [
  { id: "budget", label: "Budget", icon: DollarSign },
  { id: "alert", label: "Alert", icon: AlertTriangle },
  { id: "start", label: "Start", icon: ArrowRight },
  { id: "end", label: "End", icon: ArrowLeft },
  { id: "flag", label: "Flag", icon: Flag },
  { id: "note", label: "Note", icon: Smile },
] as const;

interface MilestoneAddPopoverProps {
  anchor: { top: number; left: number };
  dueDate: string;
  onCancel: () => void;
  onCreate: (name: string, note?: string) => void;
  isSaving?: boolean;
}

export function MilestoneAddPopover({
  anchor,
  dueDate,
  onCancel,
  onCreate,
  isSaving = false,
}: MilestoneAddPopoverProps) {
  const popoverRef = useRef<HTMLDivElement>(null);
  const [name, setName] = useState("");
  const [note, setNote] = useState("");
  const [iconId, setIconId] = useState<(typeof MILESTONE_ICONS)[number]["id"]>("flag");

  useEffect(() => {
    const onKey = (event: KeyboardEvent) => {
      if (event.key === "Escape") onCancel();
    };
    const onDown = (event: MouseEvent) => {
      if (popoverRef.current?.contains(event.target as Node)) return;
      onCancel();
    };
    window.addEventListener("keydown", onKey);
    document.addEventListener("mousedown", onDown);
    return () => {
      window.removeEventListener("keydown", onKey);
      document.removeEventListener("mousedown", onDown);
    };
  }, [onCancel]);

  const style = {
    top: Math.min(anchor.top, window.innerHeight - 360),
    left: Math.min(Math.max(8, anchor.left), window.innerWidth - 320),
  };

  const dateLabel = format(parseISO(dueDate), "d MMM yyyy");

  return createPortal(
    <div className="milestone-add-popover" ref={popoverRef} style={style}>
      <header className="milestone-add-popover-header">
        <strong>Add Milestone</strong>
        <span className="muted-text">{dateLabel}</span>
        <button aria-label="Close" className="icon-button" onClick={onCancel} type="button">
          ✕
        </button>
      </header>
      <div className="milestone-icon-picker">
        {MILESTONE_ICONS.map((item) => {
          const Icon = item.icon;
          return (
            <button
              aria-label={item.label}
              className={`milestone-icon-option${iconId === item.id ? " selected" : ""}`}
              key={item.id}
              onClick={() => setIconId(item.id)}
              type="button"
            >
              <Icon size={16} />
            </button>
          );
        })}
      </div>
      <div className="milestone-add-popover-body">
        <label>
          Name
          <input
            autoFocus
            onChange={(event) => setName(event.target.value)}
            placeholder="Milestone name"
            type="text"
            value={name}
          />
        </label>
        <label>
          Note <small>(optional)</small>
          <textarea
            onChange={(event) => setNote(event.target.value)}
            placeholder="Add a note"
            rows={3}
            value={note}
          />
        </label>
      </div>
      <footer className="milestone-add-popover-footer">
        <button
          className="primary-button"
          disabled={isSaving || !name.trim()}
          onClick={() => onCreate(name.trim(), note.trim() || undefined)}
          type="button"
        >
          Create
        </button>
      </footer>
    </div>,
    document.body,
  );
}
