import { useEffect, useRef, useState, type FormEvent } from "react";
import { Button } from "./design-system/primitives";
import { ScheduleEditor } from "./design-system/EditingWorkbench";
import {
  habitInput,
  habitPatch,
  type HabitConfig,
  type Schedule,
} from "../habits/contracts";
import { habitRequest } from "../lib/dashboard";
import { HabitColorPicker } from "./design-system/HabitColorPicker";

export type HabitStarter = {
  name: string;
  method: "manual" | "count" | "tasks";
  target?: number;
  unit?: string;
  tasks?: string;
  color?: string;
};

export function CreateHabit({
  date,
  starter,
  onClose,
  onCreated,
  editing,
}: {
  date: string;
  starter: HabitStarter;
  onClose: () => void;
  onCreated: (name: string) => void;
  editing?: { id: string; config: HabitConfig };
}) {
  const dialog = useRef<HTMLDialogElement>(null);
  const saving = useRef(false);
  const [name, setName] = useState(starter.name);
  const [method, setMethod] = useState(starter.method);
  const [target, setTarget] = useState(starter.target ?? 8);
  const [unit, setUnit] = useState(starter.unit ?? "glasses");
  const [tasks, setTasks] = useState(starter.tasks ?? "");
  const [color, setColor] = useState(starter.color ?? "#58765b");
  const [schedule, setSchedule] = useState<Schedule>(
    editing?.config.schedule ?? { type: "daily" },
  );
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState("");

  useEffect(() => {
    const previous = document.activeElement as HTMLElement | null;
    dialog.current?.showModal();
    dialog.current?.querySelector<HTMLInputElement>("#habit-name")?.focus();
    return () => {
      previous?.focus();
    };
  }, []);

  async function submit(event: FormEvent) {
    event.preventDefault();
    if (saving.current) return;
    const taskNames = tasks
      .split("\n")
      .map((name) => name.trim())
      .filter(Boolean);
    if (!editing && method === "tasks" && !taskNames.length) {
      setError("Add at least one task to get started.");
      return;
    }
    const input = {
      name,
      method,
      schedule,
      color,
      ...(method === "count"
        ? { target, unit }
        : method === "tasks" && !editing
          ? { tasks: taskNames.map((name) => ({ name })) }
          : {}),
    };
    const parsed = editing
      ? habitPatch.safeParse(input)
      : habitInput.safeParse(input);
    if (!parsed.success) {
      setError(parsed.error.issues.map((issue) => issue.message).join(" "));
      return;
    }
    saving.current = true;
    setBusy(true);
    setError("");
    try {
      await habitRequest(editing ? `/habits/${editing.id}` : "/habits", {
        method: editing ? "PATCH" : "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(parsed.data),
      });
      onCreated(parsed.data.name!);
    } catch (error) {
      setError(
        error instanceof Error ? error.message : "Could not save your habit.",
      );
      saving.current = false;
      setBusy(false);
    }
  }

  return (
    <dialog
      ref={dialog}
      className="home-create"
      aria-labelledby="create-title"
      onCancel={(event) => {
        event.preventDefault();
        if (!saving.current) onClose();
      }}
    >
      <div className="home-create-heading">
        <p className="ds-eyebrow">
          {editing ? "SHAPE YOUR RHYTHM" : "A LITTLE ROOM FOR SOMETHING GOOD"}
        </p>
        <Button
          variant="text"
          aria-label={editing ? "Close habit editor" : "Close new habit"}
          disabled={busy}
          onClick={onClose}
        >
          ×
        </Button>
      </div>
      <h2 id="create-title">
        {editing ? (
          <>
            Edit your <em>habit.</em>
          </>
        ) : (
          <>
            Make it <em>yours.</em>
          </>
        )}
      </h2>
      <p className="ds-muted">
        {editing
          ? "Changes start today. Earlier targets and schedules stay as they were."
          : "Start small. You don’t need a perfect plan."}
      </p>
      <form onSubmit={submit}>
        <fieldset disabled={busy} className="home-form-fields">
          <div className="ds-field">
            <label htmlFor="habit-name">Habit name</label>
            <input
              id="habit-name"
              required
              maxLength={200}
              placeholder="Something you want to make time for"
              value={name}
              onChange={(event) => setName(event.target.value)}
            />
          </div>
          <div className="ds-field">
            <label htmlFor="habit-method">How will you track it?</label>
            <select
              id="habit-method"
              disabled={!!editing}
              value={method}
              onChange={(event) =>
                setMethod(event.target.value as HabitStarter["method"])
              }
            >
              <option value="manual">A simple check-in</option>
              <option value="count">A count target</option>
              <option value="tasks">A list of tasks</option>
            </select>
            {editing && (
              <small>
                Tracking method stays the same. Create another habit to track it
                differently.
              </small>
            )}
          </div>
          {method === "count" && (
            <div className="ds-form-grid">
              <div className="ds-field">
                <label htmlFor="habit-target">Daily target</label>
                <input
                  id="habit-target"
                  type="number"
                  required
                  min={1}
                  max={10000}
                  step={1}
                  value={Number.isNaN(target) ? "" : target}
                  onChange={(event) => setTarget(event.target.valueAsNumber)}
                />
              </div>
              <div className="ds-field">
                <label htmlFor="habit-unit">Unit</label>
                <input
                  id="habit-unit"
                  required
                  maxLength={80}
                  value={unit}
                  onChange={(event) => setUnit(event.target.value)}
                />
              </div>
            </div>
          )}
          {method === "tasks" && !editing && (
            <div className="ds-field">
              <label htmlFor="habit-tasks">Tasks · one per line</label>
              <textarea
                id="habit-tasks"
                required
                rows={4}
                value={tasks}
                onChange={(event) => setTasks(event.target.value)}
                placeholder={"Clear desk\nPlan tomorrow\nStretch"}
              />
              <small>
                These tasks repeat on each scheduled day. Up to 100 tasks.
              </small>
            </div>
          )}
          <ScheduleEditor
            value={schedule}
            onChange={setSchedule}
            anchorDate={date}
          />
          {method === "tasks" && editing && (
            <p className="ds-footnote">
              Your existing tasks and their individual schedules are kept.
            </p>
          )}
          <HabitColorPicker
            value={color}
            onChange={setColor}
            mode={editing ? "edit" : "create"}
          />
        </fieldset>
        {error && (
          <p className="home-error" role="alert">
            {error}
          </p>
        )}
        <div className="home-form-actions">
          <Button variant="secondary" disabled={busy} onClick={onClose}>
            Cancel
          </Button>
          <Button type="submit" disabled={busy}>
            {busy
              ? editing
                ? "Saving…"
                : "Creating…"
              : editing
                ? "Save changes"
                : "Create habit"}{" "}
            <span aria-hidden="true">↗</span>
          </Button>
        </div>
      </form>
    </dialog>
  );
}
