/** Block detail + thick feedback sheet for schedule blocks. */

import { useEffect, useState } from "preact/hooks";
import {
  addPlanBlock,
  deletePlanBlock,
  getScheduleTemplates,
  postBlockFeedback,
  type ScheduledBlock,
  type ScheduleTemplate,
  type TaskKind,
} from "../api";
import { Button } from "./Button";
import { Pressable } from "./Pressable";
import { Sheet } from "./Sheet";
import { useToast } from "./Toast";

const KIND_OPTIONS: { value: TaskKind; label: string }[] = [
  { value: "earn_ship", label: "Work / earn" },
  { value: "admin_spain", label: "Trip / admin" },
  { value: "body_care", label: "Body or room" },
  { value: "move_out", label: "Move-out step" },
  { value: "food_out", label: "Food" },
  { value: "stabilize", label: "Stabilize / reset" },
  { value: "explore", label: "Try something new" },
  { value: "restore_fun", label: "Fun recharge" },
  { value: "boundary", label: "Boundary practice" },
  { value: "sleep_window", label: "Sleep wind-down" },
  { value: "other", label: "Other" },
];

function addMinutes(hhmm: string, mins: number): string {
  const [h, m] = hhmm.split(":").map(Number);
  const total = h * 60 + m + mins;
  const nh = Math.floor(((total % (24 * 60)) + 24 * 60) % (24 * 60) / 60);
  const nm = ((total % (24 * 60)) + 24 * 60) % (24 * 60) % 60;
  return `${String(nh).padStart(2, "0")}:${String(nm).padStart(2, "0")}`;
}

type Props = {
  open: boolean;
  day: string;
  block: ScheduledBlock | null;
  mode: "view" | "create";
  onClose: () => void;
  onChanged: () => void;
};

export function BlockSheet({ open, day, block, mode, onClose, onChanged }: Props) {
  const toast = useToast();
  const [did, setDid] = useState<"done" | "partial" | "skipped">("done");
  const [actualMin, setActualMin] = useState(30);
  const [quality, setQuality] = useState(3);
  const [fun, setFun] = useState(3);
  const [energy, setEnergy] = useState(0);
  const [wouldRepeat, setWouldRepeat] = useState<"yes" | "no" | "maybe" | "">("");
  const [skipReason, setSkipReason] = useState("");
  const [note, setNote] = useState("");
  const [money, setMoney] = useState("");
  const [emotions, setEmotions] = useState<string[]>([]);
  const [fseEvent, setFseEvent] = useState("");
  const [intensity, setIntensity] = useState(5);
  const [showThick, setShowThick] = useState(false);
  const [busy, setBusy] = useState(false);
  const [templates, setTemplates] = useState<ScheduleTemplate[]>([]);

  const [title, setTitle] = useState("New block");
  const [kind, setKind] = useState<TaskKind>("other");
  const [start, setStart] = useState("09:00");
  const [end, setEnd] = useState("09:30");
  const [priority, setPriority] = useState<"P0" | "P1" | "P2">("P2");
  const [intent, setIntent] = useState<ScheduledBlock["intent"]>("duty");

  useEffect(() => {
    if (!open) return;
    if (mode === "create") {
      void getScheduleTemplates()
        .then((r) => setTemplates(r.items || []))
        .catch(() => setTemplates([]));
    }
    if (mode === "view" && block) {
      setActualMin(block.feedback?.actual_min ?? block.planned_min ?? 30);
      setDid((block.feedback?.did as typeof did) || (block.status === "skipped" ? "skipped" : "done"));
      setQuality(block.feedback?.quality ?? 3);
      setFun(block.feedback?.fun ?? 3);
      setEnergy(block.feedback?.energy_after ?? 0);
      setWouldRepeat((block.feedback?.would_repeat as typeof wouldRepeat) || "");
      setSkipReason(block.feedback?.skip_reason || "");
      setNote(block.feedback?.note || "");
      setMoney(block.feedback?.money_amount != null ? String(block.feedback.money_amount) : "");
      setEmotions(block.feedback?.emotions || []);
      setFseEvent(block.feedback?.fse_event || "");
      setIntensity(block.feedback?.intensity ?? 5);
      setShowThick(false);
    }
    if (mode === "create") {
      setTitle("New block");
      setKind("other");
      setStart("09:00");
      setEnd("09:30");
      setPriority("P2");
      setIntent("duty");
    }
  }, [open, mode, block?.id]);

  const applyTemplate = (tmpl: ScheduleTemplate) => {
    setTitle(tmpl.title);
    setKind(tmpl.kind);
    setPriority((tmpl.priority as "P0" | "P1" | "P2") || "P2");
    setIntent(
      (tmpl.intent as ScheduledBlock["intent"]) ||
        (tmpl.kind === "explore"
          ? "explore"
          : tmpl.kind === "restore_fun"
            ? "restore_fun"
            : "duty"),
    );
    setEnd(addMinutes(start, tmpl.default_min || 30));
  };

  const saveFeedback = async () => {
    if (!block) return;
    setBusy(true);
    try {
      await postBlockFeedback(day, block.id, {
        did,
        actual_min: did === "skipped" ? null : actualMin,
        quality: did === "skipped" || !showThick ? null : quality,
        fun: did === "skipped" || !showThick ? null : fun,
        energy_after: showThick ? energy : null,
        money_amount: money ? Number(money) : null,
        would_repeat: wouldRepeat || null,
        skip_reason: did === "skipped" ? skipReason || "other" : null,
        note,
        emotions,
        fse_event: fseEvent,
        intensity: did === "skipped" ? null : intensity,
      });
      toast.show("Saved");
      onChanged();
      onClose();
    } catch (e) {
      toast.show(e instanceof Error ? e.message : "Save failed", "error");
    } finally {
      setBusy(false);
    }
  };

  const createBlock = async () => {
    setBusy(true);
    try {
      await addPlanBlock(day, {
        title,
        kind,
        start,
        end,
        priority,
        intent:
          kind === "explore"
            ? "explore"
            : kind === "restore_fun"
              ? "restore_fun"
              : kind === "stabilize"
                ? "measure"
                : intent,
        locked: priority === "P0",
      });
      toast.show("Block added");
      onChanged();
      onClose();
    } catch (e) {
      toast.show(e instanceof Error ? e.message : "Could not add", "error");
    } finally {
      setBusy(false);
    }
  };

  const removeBlock = async () => {
    if (!block || !confirm("Remove this block?")) return;
    setBusy(true);
    try {
      await deletePlanBlock(day, block.id);
      toast.show("Removed");
      onChanged();
      onClose();
    } catch (e) {
      toast.show(e instanceof Error ? e.message : "Delete failed", "error");
    } finally {
      setBusy(false);
    }
  };

  return (
    <Sheet
      open={open}
      tall
      title={mode === "create" ? "Add block" : block?.title || "Block"}
      onClose={onClose}
    >
      {mode === "create" ? (
        <div class="stack">
          {templates.length > 0 && (
            <>
              <span class="field-label">From template</span>
              <div class="choice-list">
                {templates.slice(0, 8).map((tmpl) => (
                  <Pressable
                    key={tmpl.id}
                    className="choice-item"
                    onClick={() => applyTemplate(tmpl)}
                  >
                    {tmpl.title}
                  </Pressable>
                ))}
              </div>
            </>
          )}
          <label class="field-label">
            Title
            <input class="field-input" value={title} onInput={(e) => setTitle((e.target as HTMLInputElement).value)} />
          </label>
          <span class="field-label">Type</span>
          <div class="choice-list">
            {KIND_OPTIONS.map((opt) => (
              <Pressable
                key={opt.value}
                className="choice-item"
                ariaPressed={kind === opt.value}
                onClick={() => setKind(opt.value)}
              >
                {opt.label}
              </Pressable>
            ))}
          </div>
          <div class="plan-time-row">
            <label class="field-label">
              Start
              <input class="field-input" type="time" value={start} onInput={(e) => setStart((e.target as HTMLInputElement).value)} />
            </label>
            <label class="field-label">
              End
              <input class="field-input" type="time" value={end} onInput={(e) => setEnd((e.target as HTMLInputElement).value)} />
            </label>
          </div>
          <span class="field-label">Priority</span>
          <div class="segment-row">
            {(["P0", "P1", "P2"] as const).map((p) => (
              <Pressable key={p} className="segment" ariaPressed={priority === p} onClick={() => setPriority(p)}>
                {p === "P0" ? "Locked" : p === "P1" ? "Important" : "Flex"}
              </Pressable>
            ))}
          </div>
          <div class="resolve-sticky">
            <Button className="btn-large" disabled={busy} onClick={createBlock}>
              {busy ? "Saving…" : "Add block"}
            </Button>
          </div>
        </div>
      ) : block ? (
        <div class="stack">
          <p class="meta-line">
            {block.start}–{block.end} · {block.label || block.kind} ·{" "}
            {block.priority === "P0" ? "Locked" : block.priority}
            {block.locked ? " · locked" : ""}
          </p>
          <span class="section-title">How did it go?</span>
          <div class="segment-row">
            {([
              ["done", "Done"],
              ["partial", "Partial"],
              ["skipped", "Skipped"],
            ] as const).map(([value, label]) => (
              <Pressable
                key={value}
                className="segment"
                ariaPressed={did === value}
                onClick={() => setDid(value)}
              >
                {label}
              </Pressable>
            ))}
          </div>
          {did !== "skipped" && (
            <label class="field-label">
              Actual minutes
              <input
                class="field-input"
                type="number"
                min={0}
                max={24 * 60}
                value={actualMin}
                onInput={(e) => setActualMin(Number((e.target as HTMLInputElement).value))}
              />
            </label>
          )}
          <label class="field-label">
            Comment
            <textarea
              class="field-textarea"
              value={note}
              onInput={(e) => setNote((e.target as HTMLTextAreaElement).value)}
              placeholder="What happened?"
            />
          </label>
          <span class="field-label">Emotions</span>
          <div class="chip-row" role="group">
            {["calm", "shame", "urge", "anxiety", "anger", "lonely", "tired", "hope"].map((em) => (
              <Pressable
                key={em}
                className="chip"
                ariaPressed={emotions.includes(em)}
                onClick={() =>
                  setEmotions((cur) =>
                    cur.includes(em) ? cur.filter((x) => x !== em) : [...cur, em],
                  )
                }
              >
                {em}
              </Pressable>
            ))}
          </div>
          <label class="field-label">
            FSE event (short phrase)
            <input
              class="field-input"
              value={fseEvent}
              onInput={(e) => setFseEvent((e.target as HTMLInputElement).value)}
              placeholder="What spiked?"
            />
          </label>
          {did !== "skipped" && (
            <label class="field-label">
              Intensity · {intensity}
              <input
                type="range"
                min={1}
                max={10}
                value={intensity}
                onInput={(e) => setIntensity(Number((e.target as HTMLInputElement).value))}
              />
            </label>
          )}
          {did === "skipped" && (
            <>
              <span class="field-label">Why skipped?</span>
              <div class="segment-row">
                {["time", "fear", "urge", "boring", "fse", "other"].map((v) => (
                  <Pressable
                    key={v}
                    className="segment"
                    ariaPressed={skipReason === v}
                    onClick={() => setSkipReason(v)}
                  >
                    {v}
                  </Pressable>
                ))}
              </div>
            </>
          )}
          <Pressable className="btn btn-plain" onClick={() => setShowThick((v) => !v)}>
            {showThick ? "Hide quality / fun / energy" : "More: quality, fun, energy, money"}
          </Pressable>
          {showThick && did !== "skipped" && (
            <>
              <span class="field-label">Quality</span>
              <div class="segment-row">
                {[1, 2, 3, 4, 5].map((n) => (
                  <Pressable key={n} className="segment" ariaPressed={quality === n} onClick={() => setQuality(n)}>
                    {n}
                  </Pressable>
                ))}
              </div>
              <span class="field-label">Fun</span>
              <div class="segment-row">
                {[1, 2, 3, 4, 5].map((n) => (
                  <Pressable key={n} className="segment" ariaPressed={fun === n} onClick={() => setFun(n)}>
                    {n}
                  </Pressable>
                ))}
              </div>
              <span class="field-label">Energy after</span>
              <div class="segment-row">
                {([-2, -1, 0, 1, 2] as const).map((v) => (
                  <Pressable
                    key={String(v)}
                    className="segment"
                    ariaPressed={energy === v}
                    onClick={() => setEnergy(v)}
                  >
                    {v > 0 ? `+${v}` : String(v)}
                  </Pressable>
                ))}
              </div>
              <span class="field-label">Would repeat?</span>
              <div class="segment-row">
                {(["yes", "maybe", "no"] as const).map((v) => (
                  <Pressable
                    key={v}
                    className="segment"
                    ariaPressed={wouldRepeat === v}
                    onClick={() => setWouldRepeat(v)}
                  >
                    {v}
                  </Pressable>
                ))}
              </div>
              <label class="field-label">
                Money (optional)
                <input
                  class="field-input"
                  type="number"
                  value={money}
                  onInput={(e) => setMoney((e.target as HTMLInputElement).value)}
                />
              </label>
            </>
          )}
          <div class="resolve-sticky">
            <Button className="btn-large" disabled={busy} onClick={saveFeedback}>
              {busy ? "Saving…" : "Save how it went"}
            </Button>
            <Button className="btn-secondary" disabled={busy} onClick={removeBlock}>
              Remove block
            </Button>
          </div>
        </div>
      ) : null}
    </Sheet>
  );
}
