"use client";

/**
 * MobileWaterLogForm — measurement entry screen.
 *
 * Visual structure (Apple HIG form):
 *   - Sticky top nav: back chevron + "Log Reading" title.
 *   - Sticky headgate card under the nav — picks a tap target
 *     bigger than the iOS minimum (44pt) and lets the user confirm
 *     which headgate they're logging against at a glance.
 *   - Section: MEASUREMENT
 *       - HUGE numeric input (44pt font) — the visual focus of the
 *         screen. `inputMode="decimal"` brings up the iOS numeric
 *         keyboard with the decimal key.
 *       - Segmented control for units (CFS / GPM / gal / ac-in /
 *         ac-ft). The default selection is the headgate's configured
 *         unit.
 *       - Live "thresholds" hint below the input (e.g. "Normal range:
 *         2–8 CFS").
 *   - Section: TIMESTAMP (read-only, auto-updating every second so
 *     the user can verify they're logging against "now").
 *   - Section: NOTES (optional, 500-char multiline).
 *   - Sticky submit bar at the bottom — green primary button per
 *     HIG success semantics. Slides up out of the keyboard's way
 *     because the bar is `position: sticky; bottom: 0`.
 */
import {
  useEffect,
  useMemo,
  useRef,
  useState,
  type FormEvent,
} from "react";
import { SegmentedControl } from "./SegmentedControl";
import type { FieldHeadgate, MobileUnit } from "./types";
import { MOBILE_UNITS } from "./types";
import { ChevronLeft, Clock, Gauge, Pencil, Pin, Spinner } from "./icons";
import {
  formatLongTimestamp,
  formatMeasurement,
  headgateSubtitle,
} from "./format";

type Props = {
  headgate: FieldHeadgate;
  onSubmit: (input: { measurement: number; unit: string; notes: string }) => Promise<void>;
  onChangeHeadgate: () => void;
  onLogout: () => void;
  /** Optional preset units — defaults to MOBILE_UNITS. */
  units?: ReadonlyArray<MobileUnit | string>;
};

const NOTES_MAX = 500;

export function MobileWaterLogForm({
  headgate,
  onSubmit,
  onChangeHeadgate,
  onLogout,
  units = MOBILE_UNITS,
}: Props) {
  // ── State ────────────────────────────────────────────────────────
  const [measurement, setMeasurement] = useState("");
  const [unit, setUnit] = useState<string>(
    units.includes(headgate.unit) ? headgate.unit : units[0],
  );
  const [notes, setNotes] = useState("");
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [now, setNow] = useState<Date>(() => new Date());
  const measurementRef = useRef<HTMLInputElement>(null);

  // ── Auto-focus the measurement input on mount so the keyboard
  //    rises immediately.
  useEffect(() => {
    const t = window.setTimeout(() => measurementRef.current?.focus(), 80);
    return () => window.clearTimeout(t);
  }, []);

  // ── Live clock — re-renders every second. The setInterval is
  //    cheap (one DOM update per second on a hidden element) and
  //    gives the user confidence the timestamp reflects "now".
  useEffect(() => {
    const id = window.setInterval(() => setNow(new Date()), 1000);
    return () => window.clearInterval(id);
  }, []);

  // ── Threshold hint derived from the headgate. ────────────────────
  const thresholdHint = useMemo(() => {
    const h = headgate.high_threshold;
    const l = headgate.low_threshold;
    if (h == null && l == null) return null;
    if (h != null && l != null) {
      return `Normal range: ${l} – ${h} ${unit}`;
    }
    if (h != null) return `Alert above ${h} ${unit}`;
    return `Alert below ${l} ${unit}`;
  }, [headgate, unit]);

  const submitted = (e?: FormEvent) => {
    e?.preventDefault();
    if (submitting) return;
    const value = parseFloat(measurement);
    if (!Number.isFinite(value) || value < 0) {
      setError("Enter a measurement greater than or equal to 0");
      return;
    }
    if (value > 1_000_000) {
      setError("That value is implausibly large");
      return;
    }
    setSubmitting(true);
    setError(null);
    onSubmit({ measurement: value, unit, notes })
      .catch((err) => {
        setError(
          err instanceof Error ? err.message : "Couldn't submit. Try again.",
        );
        setSubmitting(false);
      });
    // On success the parent swaps to the success screen.
  };

  const subtitle = headgateSubtitle(headgate);
  const canSubmit =
    measurement.trim().length > 0 &&
    Number.isFinite(parseFloat(measurement)) &&
    parseFloat(measurement) >= 0 &&
    !submitting;

  return (
    <div
      className="flex h-full flex-col bg-[#F2F2F7]"
      style={{
        paddingTop: "env(safe-area-inset-top)",
      }}
    >
      {/* ── Top nav ────────────────────────────────────────────── */}
      <header
        className="sticky top-0 z-30 flex h-11 items-center border-b border-[rgba(60,60,67,0.12)] bg-[rgba(255,255,255,0.85)] px-2"
        style={{
          paddingTop: "env(safe-area-inset-top)",
          height: "calc(44px + env(safe-area-inset-top))",
          backdropFilter: "blur(20px) saturate(180%)",
          WebkitBackdropFilter: "blur(20px) saturate(180%)",
        }}
      >
        <button
          type="button"
          onClick={onChangeHeadgate}
          aria-label="Back to headgates"
          className="flex h-9 w-9 items-center justify-center rounded-full text-[#14532d] active:bg-[rgba(120,120,128,0.16)]"
        >
          <ChevronLeft size={22} />
        </button>
        <h1
          className="absolute left-1/2 -translate-x-1/2 text-[17px] font-semibold text-[#1d1d1f]"
          style={{
            fontFamily:
              "-apple-system, BlinkMacSystemFont, 'SF Pro Display', 'Segoe UI', Roboto, sans-serif",
          }}
        >
          Log Reading
        </h1>
        <span className="w-9" />
      </header>

      {/* ── Scrollable form body ───────────────────────────────── */}
      <form
        onSubmit={submitted}
        className="flex flex-1 flex-col"
        // Allow the form to grow so the sticky submit bar can sit at
        // the bottom on tall viewports.
      >
        <div className="flex-1 overflow-y-auto px-4 pb-[max(env(safe-area-inset-bottom),1rem)] pt-3">
          {/* ── Headgate summary card (sticky) ──────────────── */}
          <button
            type="button"
            onClick={onChangeHeadgate}
            aria-label="Change headgate"
            className="mb-5 flex w-full items-center gap-3 rounded-[14px] bg-white p-3 text-left active:bg-[rgba(120,120,128,0.10)]"
            style={{
              boxShadow: "0 1px 2px rgba(0,0,0,0.04), 0 1px 0 rgba(0,0,0,0.02)",
            }}
          >
            <div className="flex h-11 w-11 shrink-0 items-center justify-center rounded-[10px] bg-[rgba(20,83,45,0.10)] text-[#14532d]">
              <Gauge size={22} />
            </div>
            <div className="min-w-0 flex-1">
              <div
                className="truncate text-[17px] font-semibold leading-[1.2] text-[#1d1d1f]"
                style={{
                  fontFamily:
                    "-apple-system, BlinkMacSystemFont, 'SF Pro Display', 'Segoe UI', Roboto, sans-serif",
                }}
              >
                {headgate.name}
              </div>
              <div className="mt-0.5 flex items-center gap-1.5 text-[13px] text-[rgba(60,60,67,0.6)]">
                <Pin size={12} className="shrink-0 opacity-60" />
                <span className="truncate">{subtitle}</span>
              </div>
            </div>
            <span className="rounded-full bg-[rgba(20,83,45,0.10)] px-2.5 py-1 text-[12px] font-semibold text-[#14532d]">
              {headgate.unit}
            </span>
          </button>

          {/* ── Measurement section ─────────────────────────── */}
          <SectionHeader>Measurement</SectionHeader>
          <div className="mb-2 overflow-hidden rounded-[14px] bg-white p-5 shadow-[0_1px_2px_rgba(0,0,0,0.04),0_1px_0_rgba(0,0,0,0.02)]">
            <div className="flex items-baseline gap-2">
              <input
                ref={measurementRef}
                type="number"
                inputMode="decimal"
                step="any"
                min={0}
                value={measurement}
                onChange={(e) => {
                  setMeasurement(e.target.value);
                  if (error) setError(null);
                }}
                placeholder="0"
                aria-label="Measurement value"
                className="min-w-0 flex-1 appearance-none bg-transparent text-[44px] font-bold leading-[1.05] tracking-tight text-[#1d1d1f] outline-none placeholder:text-[rgba(60,60,67,0.25)]"
                style={{
                  fontFamily:
                    "-apple-system, BlinkMacSystemFont, 'SF Pro Display', 'Segoe UI', Roboto, sans-serif",
                  // Hide the native spinner buttons — they crowd a
                  // small mobile screen and feel non-native.
                  MozAppearance: "textfield",
                }}
              />
              <span className="shrink-0 pb-2 text-[20px] font-semibold text-[rgba(60,60,67,0.5)]">
                {unit}
              </span>
            </div>
            {thresholdHint && (
              <p className="mt-3 border-t border-[rgba(60,60,67,0.10)] pt-3 text-[13px] text-[rgba(60,60,67,0.6)]">
                {thresholdHint}
              </p>
            )}
          </div>

          {/* Unit segmented control */}
          <div className="mb-5">
            <SegmentedControl
              ariaLabel="Unit"
              value={unit as MobileUnit}
              onChange={(v: string) => setUnit(v)}
              options={units.map((u) => ({ value: u as string, label: u }))}
            />
          </div>

          {/* ── Timestamp section ───────────────────────────── */}
          <SectionHeader>Timestamp</SectionHeader>
          <div className="mb-5 flex items-center gap-3 rounded-[14px] bg-white p-4 shadow-[0_1px_2px_rgba(0,0,0,0.04),0_1px_0_rgba(0,0,0,0.02)]">
            <div className="flex h-9 w-9 items-center justify-center rounded-full bg-[rgba(20,83,45,0.10)] text-[#14532d]">
              <Clock size={18} />
            </div>
            <div className="min-w-0 flex-1">
              <div className="text-[15px] font-semibold text-[#1d1d1f]">
                Logged now
              </div>
              <div className="mt-0.5 truncate text-[13px] text-[rgba(60,60,67,0.6)]">
                {formatLongTimestamp(now)}
              </div>
            </div>
          </div>

          {/* ── Notes section ────────────────────────────────── */}
          <SectionHeader>
            Notes <span className="font-normal text-[rgba(60,60,67,0.45)]">— optional</span>
          </SectionHeader>
          <div className="mb-5 rounded-[14px] bg-white shadow-[0_1px_2px_rgba(0,0,0,0.04),0_1px_0_rgba(0,0,0,0.02)]">
            <label className="flex items-start gap-3 p-4">
              <Pencil
                size={18}
                className="mt-0.5 shrink-0 text-[rgba(60,60,67,0.45)]"
              />
              <textarea
                value={notes}
                onChange={(e) => setNotes(e.target.value.slice(0, NOTES_MAX))}
                rows={3}
                maxLength={NOTES_MAX}
                placeholder="Anything the supervisor should know about this reading?"
                className="min-h-[68px] w-full resize-none bg-transparent text-[16px] leading-[1.4] text-[#1d1d1f] outline-none placeholder:text-[rgba(60,60,67,0.4)]"
                style={{
                  fontFamily:
                    "-apple-system, BlinkMacSystemFont, 'SF Pro Display', 'Segoe UI', Roboto, sans-serif",
                }}
              />
            </label>
            <div className="flex items-center justify-between border-t border-[rgba(60,60,67,0.10)] px-4 py-2 text-[12px] text-[rgba(60,60,67,0.45)]">
              <span>Visible to admins only</span>
              <span>
                {notes.length}/{NOTES_MAX}
              </span>
            </div>
          </div>

          {/* Inline error */}
          {error && (
            <div
              role="alert"
              className="mb-3 rounded-[12px] bg-[rgba(255,59,48,0.10)] px-4 py-3 text-[15px] text-[#7f1d1d]"
            >
              {error}
            </div>
          )}
        </div>

        {/* ── Sticky submit bar ───────────────────────────────── */}
        <div
          className="sticky bottom-0 z-20 border-t border-[rgba(60,60,67,0.10)] bg-[rgba(255,255,255,0.92)] px-4 py-3"
          style={{
            paddingBottom: "max(env(safe-area-inset-bottom), 0.75rem)",
            backdropFilter: "blur(20px) saturate(180%)",
            WebkitBackdropFilter: "blur(20px) saturate(180%)",
          }}
        >
          <button
            type="submit"
            disabled={!canSubmit}
            className={[
              "flex h-[58px] w-full items-center justify-center gap-2 rounded-[14px] text-[17px] font-semibold",
              "transition-[transform,background-color,opacity] duration-200",
              "active:scale-[0.985]",
              canSubmit
                ? "bg-[#34C759] text-white shadow-[0_6px_18px_rgba(52,199,89,0.32),inset_0_1px_0_rgba(255,255,255,0.18)]"
                : "bg-[rgba(120,120,128,0.16)] text-[rgba(60,60,67,0.4)]",
            ].join(" ")}
          >
            {submitting ? (
              <>
                <Spinner
                  size={20}
                  className="text-white"
                  style={{ animation: "spin 0.8s linear infinite" }}
                />
                Submitting…
              </>
            ) : (
              <>
                Submit Log
                {measurement && Number.isFinite(parseFloat(measurement)) && (
                  <span className="ml-1 opacity-80">
                    · {formatMeasurement(parseFloat(measurement))} {unit}
                  </span>
                )}
              </>
            )}
          </button>
          <div className="mt-2 flex items-center justify-center">
            <button
              type="button"
              onClick={onLogout}
              className="text-[12px] font-medium text-[rgba(60,60,67,0.45)] active:text-[#14532d]"
            >
              Sign out
            </button>
          </div>
        </div>
      </form>
    </div>
  );
}

// ── Section header (HIG inset-grouped style) ───────────────────────────

function SectionHeader({ children }: { children: React.ReactNode }) {
  return (
    <h2 className="mb-1.5 px-3 text-[13px] font-semibold uppercase tracking-[0.06em] text-[rgba(60,60,67,0.55)]">
      {children}
    </h2>
  );
}

export default MobileWaterLogForm;