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

/** Account behavior composed from the design system's existing form components. */
export function HabitForm({
  date,
  onCancel,
  onCreated,
  onExpired,
}: {
  date: string;
  onCancel: () => void;
  onCreated: (name: string) => void;
  onExpired: () => void;
}) {
  const form = useRef<HTMLFormElement>(null);
  const saving = useRef(false);
  const [name, setName] = useState("");
  const [method, setMethod] = useState<"manual" | "count" | "tasks">("manual");
  const [target, setTarget] = useState(8);
  const [unit, setUnit] = useState("glasses");
  const [tasks, setTasks] = useState([""]);
  const [schedule, setSchedule] = useState<Schedule>({ type: "daily" });
  const [color, setColor] = useState("#58765b");
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState("");

  useEffect(() => {
    const previous = document.activeElement as HTMLElement | null;
    form.current?.querySelector<HTMLInputElement>("input")?.focus();
    return () => previous?.focus();
  }, []);

  async function submit(event: FormEvent) {
    event.preventDefault();
    if (saving.current) return;
    const parsed = habitInput.safeParse({
      name,
      method,
      schedule,
      color,
      ...(method === "count" ? { target, unit } : {}),
      ...(method === "tasks" ? { tasks: tasks.map((name) => ({ name })) } : {}),
    });
    if (!parsed.success) {
      setError(parsed.error.issues.map((issue) => issue.message).join(" "));
      return;
    }
    saving.current = true;
    setBusy(true);
    setError("");
    try {
      await habitRequest("/habits", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(parsed.data),
      });
      onCreated(parsed.data.name);
    } catch (error) {
      if (
        error instanceof Error &&
        error.message.includes("session has expired")
      )
        onExpired();
      else
        setError(
          error instanceof Error
            ? error.message
            : "Could not create your habit.",
        );
    } finally {
      saving.current = false;
      setBusy(false);
    }
  }

  return (
    <section
      className="ds-section ds-split-section"
      aria-labelledby="new-habit-title"
      id="new-habit"
    >
      <SectionHeading
        number="A NEW HABIT"
        id="new-habit-title"
        title={
          <>
            Make it <em>yours.</em>
          </>
        }
      >
        Choose what counts as complete. Your schedule follows your account’s
        timezone.
      </SectionHeading>
      <form ref={form} className="ds-edit-content" onSubmit={submit}>
        <fieldset className="ds-task-editor-fieldset" disabled={busy}>
          <Field label="Habit name">
            {(id) => (
              <input
                id={id}
                required
                maxLength={200}
                placeholder="e.g. Read ten pages"
                value={name}
                onChange={(event) => setName(event.target.value)}
              />
            )}
          </Field>
          <Field label="How will you track it?">
            {(id) => (
              <select
                id={id}
                value={method}
                onChange={(event) =>
                  setMethod(event.target.value as typeof 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>
            )}
          </Field>
          {method === "count" && (
            <div className="ds-form-grid">
              <Field label="Daily target">
                {(id) => (
                  <input
                    id={id}
                    type="number"
                    required
                    min={1}
                    max={10000}
                    step={1}
                    value={Number.isNaN(target) ? "" : target}
                    onChange={(event) => setTarget(event.target.valueAsNumber)}
                  />
                )}
              </Field>
              <Field label="Unit">
                {(id) => (
                  <input
                    id={id}
                    required
                    maxLength={80}
                    value={unit}
                    onChange={(event) => setUnit(event.target.value)}
                  />
                )}
              </Field>
            </div>
          )}
          {method === "tasks" && (
            <div className="ds-form-section">
              {tasks.map((task, index) => (
                <Field key={index} label={`Task ${index + 1}`}>
                  {(id) => (
                    <div className="ds-input-row">
                      <input
                        id={id}
                        required
                        maxLength={200}
                        value={task}
                        onChange={(event) =>
                          setTasks((current) =>
                            current.map((value, i) =>
                              i === index ? event.target.value : value,
                            ),
                          )
                        }
                      />
                      <Button
                        variant="text"
                        aria-label={`Remove task ${index + 1}`}
                        disabled={tasks.length === 1}
                        onClick={() =>
                          setTasks((current) =>
                            current.filter((_, i) => i !== index),
                          )
                        }
                      >
                        Remove
                      </Button>
                    </div>
                  )}
                </Field>
              ))}
              <Button
                variant="secondary"
                disabled={tasks.length >= 100}
                onClick={() => setTasks((current) => [...current, ""])}
              >
                Add task +
              </Button>
              <p className="ds-form-feedback">
                Tasks repeat on each scheduled day.
              </p>
            </div>
          )}
          <ScheduleEditor
            value={schedule}
            onChange={setSchedule}
            anchorDate={date}
          />
          <HabitColorPicker value={color} onChange={setColor} mode="create" />
        </fieldset>
        {error && (
          <p className="ds-form-feedback" role="alert">
            {error}
          </p>
        )}
        <div className="ds-form-actions">
          <Button type="submit" disabled={busy}>
            {busy ? "Creating…" : "Create habit"}
          </Button>
          <Button variant="text" disabled={busy} onClick={onCancel}>
            Cancel
          </Button>
        </div>
      </form>
    </section>
  );
}
