import { useEffect, useState } from "react";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import type { Bootstrap, Item } from "../../types.js";
import { TYPES, helpers, enrichItems } from "../../types.js";
import { getToday, getStoredTimezone } from "../../tz.js";
import { api } from "../../api.js";
import { Btn, Field, Input, Select } from "../primitives/index.js";
import { ScanField, type ScanResult } from "../ScanField.js";
import { ModalBackdrop, ModalHeader, ModalFooter } from "./ModalChrome.js";
import { useToast } from "../Toast.js";

const AUDIT_MODE_LABELS: Record<string, { title: string; desc: string }> = {
  weigh: {
    title: "Reweigh on a scale",
    desc: "Place the jar (minus tare) and record the new weight.",
  },
  estimate: {
    title: "Visual estimate",
    desc: "Eyeball the remaining amount — quick and approximate.",
  },
  presence: {
    title: "Confirm presence",
    desc: "Verify the item is still where you left it. Count units if applicable.",
  },
};

export function AuditFlow({
  data,
  onClose,
  item: initialItem,
}: {
  data: Bootstrap;
  onClose: () => void;
  item: Item | null;
}) {
  const qc = useQueryClient();
  const { toast } = useToast();
  const allItems = enrichItems(data);
  const overdueFirst = [...allItems]
    .filter((i) => i.status === "active")
    .sort((a, b) => helpers.daysSinceCheck(b) - helpers.daysSinceCheck(a));

  const [itemId, setItemId] = useState(initialItem?.id ?? "");
  const [date, setDate] = useState(getToday(getStoredTimezone()));
  const [confirmedBy, setConfirmedBy] = useState<"asset" | "visual">("asset");

  const item = allItems.find((i) => i.id === itemId);
  const cfg = item ? TYPES.find((t) => t.id === item.type) : undefined;

  const initialValueFor = (i: Item | undefined): string => {
    if (!i) return "0";
    if (i.kind === "discrete") {
      return String(i.countLastAudit ?? i.countOriginal);
    }
    return helpers.estimatedRemaining(i, getToday(getStoredTimezone())).toFixed(2);
  };
  const [value, setValue] = useState<string>(initialValueFor(item));
  const isConcentrate = item?.type === "Concentrate";
  const [inputMode, setInputMode] = useState<"direct" | "container">(
    item?.containerWeight != null ? "container" : "direct",
  );
  const [containerTotal, setContainerTotal] = useState("");
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    setValue(initialValueFor(item));
    setInputMode(item?.containerWeight != null ? "container" : "direct");
    setContainerTotal("");
  }, [itemId]); // eslint-disable-line react-hooks/exhaustive-deps

  const tare = item ? helpers.tare(item) : null;
  const derivedRemaining =
    tare != null && containerTotal !== ""
      ? parseFloat(containerTotal) - tare
      : null;

  const effectiveValue =
    inputMode === "container" && derivedRemaining != null
      ? derivedRemaining
      : Number(value);
  const effectiveMode =
    inputMode === "container" ? "weigh" : (cfg?.auditMode ?? "weigh");

  const audit = useMutation({
    mutationFn: () =>
      api.auditInventoryItem(itemId, {
        date,
        mode: effectiveMode,
        value: effectiveValue,
        confirmedBy: cfg?.auditMode === "presence" ? confirmedBy : undefined,
      }),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ["bootstrap"] });
      toast(`Audit saved — next due in ${cfg?.cadenceDays ?? "?"}d`);
      onClose();
    },
    onError: (e: Error) => setError(e.message),
  });

  const handleScan = (result: ScanResult) => {
    if (result.kind === "item") {
      setItemId(result.item.id);
    }
  };

  const auditMode = cfg?.auditMode ?? "weigh";
  const ml = inputMode === "container"
    ? { title: "Weigh container", desc: "Place the sealed jar on a scale and enter the total weight. Product remaining is calculated from the tare." }
    : AUDIT_MODE_LABELS[auditMode] ?? AUDIT_MODE_LABELS.weigh!;

  const last = item ? helpers.lastAudit(item) : null;
  const prevValue = item
    ? item.kind === "discrete"
      ? item.countLastAudit ?? item.countOriginal
      : last
        ? last.value
        : item.weight
    : 0;

  const delta = effectiveValue - prevValue;

  return (
    <ModalBackdrop onClose={onClose}>
      <div
        style={{
          width: "min(720px, 96vw)",
          margin: "40px 20px",
          background: "var(--bg)",
          border: "1px solid var(--line)",
          borderRadius: "var(--r-lg)",
          boxShadow: "var(--shadow-lg)",
        }}
      >
        <ModalHeader title={item ? ml.title : "Audit"} eyebrow="" onClose={onClose} />

        <div style={{ padding: 32 }}>
          <ScanField
            items={overdueFirst}
            products={[]}
            matchedLabel={item ? `${item.assetId} · ${item.name}` : null}
            onMatch={handleScan}
            mode="assetId"
          />

          {!item ? (
            <div style={{ marginTop: 24, textAlign: "center", color: "var(--ink-3)", fontSize: 13, fontStyle: "italic", padding: "24px 0" }}>
              Scan an asset ID to continue.
            </div>
          ) : (
            <>
              <div
                style={{
                  marginTop: 16,
                  padding: 16,
                  background: "var(--bg-2)",
                  border: "1px solid var(--line)",
                  borderRadius: "var(--r-md)",
                }}
              >
                <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
                  <div>
                    <div className="serif" style={{ fontSize: 20, fontWeight: 500 }}>
                      {item.name}
                    </div>
                    <div style={{ fontSize: 12, color: "var(--ink-3)" }}>
                      <span className="mono">{item.assetId}</span> · {item.type} · {item.kind} · cadence every {cfg?.cadenceDays}d
                    </div>
                  </div>
                  <div style={{ textAlign: "right" }}>
                    <div className="mono" style={{ fontSize: 11, color: "var(--ink-3)" }}>LAST CHECKED</div>
                    <div className="serif" style={{ fontSize: 18 }}>
                      {last ? `${helpers.daysSinceCheck(item)}d ago` : "Never"}
                    </div>
                  </div>
                </div>
                <div style={{ fontSize: 12, color: "var(--ink-2)", marginTop: 10, fontStyle: "italic" }}>
                  {ml.desc}
                </div>
              </div>

              {tare != null && !isConcentrate && (
                <div style={{ display: "flex", gap: 8, marginTop: 16 }}>
                  <Btn
                    variant={inputMode === "container" ? "primary" : "ghost"}
                    onClick={() => setInputMode("container")}
                  >
                    Weigh container
                  </Btn>
                  <Btn
                    variant={inputMode === "direct" ? "primary" : "ghost"}
                    onClick={() => setInputMode("direct")}
                  >
                    Direct entry
                  </Btn>
                </div>
              )}

              <div
                style={{
                  display: "grid",
                  gridTemplateColumns: auditMode === "presence" ? "1fr 1fr 1fr" : "1fr 1fr",
                  gap: 16,
                  marginTop: 24,
                }}
              >
                {inputMode === "container" && tare != null ? (
                  <Field label="Container weight now (g)">
                    <Input
                      type="number"
                      step="0.01"
                      value={containerTotal}
                      onChange={(e) => setContainerTotal(e.target.value)}
                    />
                  </Field>
                ) : (
                  <Field
                    label={
                      item.kind === "discrete"
                        ? `Count now (${cfg?.unit})`
                        : auditMode === "weigh"
                          ? `Weight now (${cfg?.unit})`
                          : `Estimate now (${cfg?.unit})`
                    }
                  >
                    <Input
                      type="number"
                      step={item.kind === "discrete" ? "1" : "0.1"}
                      value={value}
                      onChange={(e) => setValue(e.target.value)}
                    />
                  </Field>
                )}
                <Field label="Date">
                  <Input type="date" value={date} onChange={(e) => setDate(e.target.value)} />
                </Field>
                {auditMode === "presence" && (
                  <Field label="Confirmed by">
                    <Select
                      value={confirmedBy}
                      onChange={(e) => setConfirmedBy(e.target.value as typeof confirmedBy)}
                    >
                      <option value="asset">Asset id</option>
                      <option value="visual">Visual ID</option>
                    </Select>
                  </Field>
                )}
              </div>

              {inputMode === "container" && tare != null && (
                <div style={{ marginTop: 8, fontSize: 12, color: "var(--ink-3)" }}>
                  Tare (empty jar): {tare.toFixed(2)}g
                  {derivedRemaining != null && (
                    <span style={{ color: derivedRemaining >= 0 ? "var(--sage)" : "var(--terracotta)" }}>
                      {" · "}Product remaining: {derivedRemaining.toFixed(2)}g
                    </span>
                  )}
                </div>
              )}

              <div
                style={{
                  marginTop: 20,
                  padding: 14,
                  background: "var(--surface)",
                  border: "1px solid var(--line)",
                  borderRadius: "var(--r-md)",
                  display: "grid",
                  gridTemplateColumns: "1fr 1fr 1fr",
                  gap: 16,
                }}
              >
                <div>
                  <div className="smallcaps" style={{ color: "var(--ink-3)" }}>Was</div>
                  <div className="serif" style={{ fontSize: 22 }}>
                    {item.kind === "discrete" ? prevValue : prevValue.toFixed(2)} {cfg?.unit}
                  </div>
                </div>
                <div>
                  <div className="smallcaps" style={{ color: "var(--ink-3)" }}>Now</div>
                  <div className="serif" style={{ fontSize: 22, color: "var(--sage)" }}>
                    {effectiveValue.toFixed(item.kind === "discrete" ? 0 : 2)} {cfg?.unit}
                  </div>
                </div>
                <div>
                  <div className="smallcaps" style={{ color: "var(--ink-3)" }}>Δ since last</div>
                  <div
                    className="serif"
                    style={{
                      fontSize: 22,
                      color: delta < 0 ? "var(--terracotta)" : "var(--ink)",
                    }}
                  >
                    {delta.toFixed(item.kind === "discrete" ? 0 : 2)} {cfg?.unit}
                  </div>
                </div>
              </div>
            </>
          )}

          {error && (
            <div style={{ marginTop: 14, fontSize: 12, color: "var(--terracotta)" }}>{error}</div>
          )}
        </div>

        <ModalFooter>
          <div style={{ fontSize: 12, color: "var(--ink-3)" }}>
            {item ? `Next audit due in ${cfg?.cadenceDays}d` : ""}
          </div>
          <div style={{ display: "flex", gap: 8 }}>
            <Btn variant="ghost" onClick={onClose}>Cancel</Btn>
            <Btn
              variant="primary"
              icon="check"
              disabled={audit.isPending || !item}
              onClick={() => audit.mutate()}
            >
              {audit.isPending ? "Saving…" : "Save audit"}
            </Btn>
          </div>
        </ModalFooter>
      </div>
    </ModalBackdrop>
  );
}
