"use client";

import {
  AlertTriangle,
  Beaker,
  BookOpen,
  Check,
  ChevronDown,
  CircleDollarSign,
  ClipboardCheck,
  Droplets,
  FlaskConical,
  History,
  Info,
  Menu,
  ShieldCheck,
  Sparkles,
  TestTube2,
  Waves,
  X,
} from "lucide-react";
import { FormEvent, useEffect, useMemo, useState } from "react";
import { buildPoolPlan } from "./lib/pool-plan.js";

type View = "today" | "costs" | "learn";
type Appearance = "clear" | "cloudy" | "green";
type TestMethod = "drop" | "strip" | "sensor";
type ReadingKey =
  | "freeChlorine"
  | "ph"
  | "totalAlkalinity"
  | "cyanuricAcid"
  | "calciumHardness"
  | "salt";
type FormReadings = Record<ReadingKey, string>;
type PriceState = {
  liquidChlorineGallon: number;
  bakingSodaPound: number;
  saltPound: number;
  stabilizerPound: number;
};
type TargetState = {
  cyanuricAcid: number;
  salt: number;
};
type PlanAction = {
  kind: string;
  parameter: string | null;
  chemical: string | null;
  amount: string | null;
  title: string;
  detail: string;
  reason: string;
  verification: string;
  estimatedCost: number;
};
type PoolPlan = {
  status: string;
  swimStatus: "ready" | "pause";
  actions: PlanAction[];
  estimatedCost: number;
  guardrails: string[];
};
type TestLog = {
  id: string;
  createdAt: string;
  status: string;
  swimStatus: string;
  cost: number;
  readings: FormReadings;
};

const emptyReadings: FormReadings = {
  freeChlorine: "",
  ph: "",
  totalAlkalinity: "",
  cyanuricAcid: "",
  calciumHardness: "",
  salt: "",
};
const exampleReadings: FormReadings = {
  freeChlorine: "1.3",
  ph: "8.0",
  totalAlkalinity: "55",
  cyanuricAcid: "50",
  calciumHardness: "300",
  salt: "2800",
};
const defaultPrices: PriceState = {
  liquidChlorineGallon: 6.99,
  bakingSodaPound: 0.9,
  saltPound: 0.32,
  stabilizerPound: 4.5,
};
const defaultTargets: TargetState = {
  cyanuricAcid: 40,
  salt: 3200,
};
const readingFields: Array<{
  key: ReadingKey;
  short: string;
  label: string;
  unit: string;
  step: string;
  hint: string;
}> = [
  {
    key: "freeChlorine",
    short: "FC",
    label: "Free chlorine",
    unit: "ppm",
    step: "0.1",
    hint: "Sanitizer available now",
  },
  {
    key: "ph",
    short: "pH",
    label: "pH",
    unit: "",
    step: "0.1",
    hint: "Comfort and chemical activity",
  },
  {
    key: "totalAlkalinity",
    short: "TA",
    label: "Total alkalinity",
    unit: "ppm",
    step: "1",
    hint: "Buffer against pH swings",
  },
  {
    key: "cyanuricAcid",
    short: "CYA",
    label: "Cyanuric acid",
    unit: "ppm",
    step: "1",
    hint: "Sun protection for chlorine",
  },
  {
    key: "calciumHardness",
    short: "CH",
    label: "Calcium hardness",
    unit: "ppm",
    step: "1",
    hint: "Surface and scale balance",
  },
  {
    key: "salt",
    short: "SALT",
    label: "Salt",
    unit: "ppm",
    step: "10",
    hint: "Generator operating level",
  },
];
const methodLabels: Record<TestMethod, string> = {
  drop: "Drop kit",
  strip: "Test strip",
  sensor: "Sensor / store",
};
const appearanceLabels: Record<Appearance, string> = {
  clear: "Clear",
  cloudy: "Cloudy",
  green: "Green",
};
const statusCopy = {
  ready: {
    eyebrow: "Swim status",
    title: "Ready to swim",
    description: "The recorded safety readings are in range.",
  },
  pause: {
    eyebrow: "Swim status",
    title: "Pause swimming",
    description: "Complete the plan and confirm with a fresh test.",
  },
};

export function PoolCareApp() {
  const [view, setView] = useState<View>("today");
  const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
  const [poolName, setPoolName] = useState("Backyard pool");
  const [gallons, setGallons] = useState("18000");
  const [readings, setReadings] = useState<FormReadings>(emptyReadings);
  const [method, setMethod] = useState<TestMethod>("drop");
  const [appearance, setAppearance] = useState<Appearance>("clear");
  const [prices, setPrices] = useState<PriceState>(defaultPrices);
  const [targets, setTargets] = useState<TargetState>(defaultTargets);
  const [plan, setPlan] = useState<PoolPlan | null>(null);
  const [error, setError] = useState("");
  const [completedActions, setCompletedActions] = useState<number[]>([]);
  const [logs, setLogs] = useState<TestLog[]>([]);
  const [hydrated, setHydrated] = useState(false);

  useEffect(() => {
    queueMicrotask(() => {
      try {
        const saved = window.localStorage.getItem("poolside-state");
        if (saved) {
          const parsed = JSON.parse(saved);
          setPoolName(parsed.poolName ?? "Backyard pool");
          setGallons(parsed.gallons ?? "18000");
          setPrices(parsed.prices ?? defaultPrices);
          setTargets(parsed.targets ?? defaultTargets);
          setLogs(parsed.logs ?? []);
        }
      } catch {
        // Device-local storage is optional.
      } finally {
        setHydrated(true);
      }
    });
  }, []);

  useEffect(() => {
    if (!hydrated) return;
    try {
      window.localStorage.setItem(
        "poolside-state",
        JSON.stringify({ poolName, gallons, prices, targets, logs }),
      );
    } catch {
      // Storage can be unavailable in privacy-focused browser modes.
    }
  }, [gallons, hydrated, logs, poolName, prices, targets]);

  const monthSpend = useMemo(() => {
    const now = new Date();
    return logs
      .filter((log) => {
        const date = new Date(log.createdAt);
        return (
          date.getMonth() === now.getMonth() &&
          date.getFullYear() === now.getFullYear()
        );
      })
      .reduce((total, log) => total + log.cost, 0);
  }, [logs]);

  function handleSubmit(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    setError("");
    try {
      const numericReadings = Object.fromEntries(
        Object.entries(readings).map(([key, value]) => [key, Number(value)]),
      );
      const nextPlan = buildPoolPlan({
        gallons: Number(gallons),
        sanitizer: "salt",
        surface: "plaster",
        appearance,
        readings: numericReadings,
        prices,
        targets,
      }) as PoolPlan;
      setPlan(nextPlan);
      setCompletedActions([]);
      const nextLog: TestLog = {
        id: crypto.randomUUID(),
        createdAt: new Date().toISOString(),
        status: nextPlan.status,
        swimStatus: nextPlan.swimStatus,
        cost: nextPlan.estimatedCost,
        readings,
      };
      setLogs((current) => [nextLog, ...current].slice(0, 20));
      window.setTimeout(() => {
        document
          .getElementById("care-plan")
          ?.scrollIntoView({ behavior: "smooth", block: "start" });
      }, 0);
    } catch (caught) {
      setError(
        caught instanceof Error
          ? caught.message
          : "Check the readings and try again.",
      );
    }
  }

  function applyExample() {
    setReadings(exampleReadings);
    setAppearance("clear");
    setError("");
  }

  function toggleAction(index: number) {
    setCompletedActions((current) =>
      current.includes(index)
        ? current.filter((item) => item !== index)
        : [...current, index],
    );
  }

  function navigate(nextView: View) {
    setView(nextView);
    setMobileMenuOpen(false);
    window.scrollTo({ top: 0, behavior: "smooth" });
  }

  const status = plan ? statusCopy[plan.swimStatus] : null;

  return (
    <div className="app-shell">
      <aside className={`sidebar ${mobileMenuOpen ? "sidebar-open" : ""}`}>
        <div className="brand">
          <span className="brand-mark" aria-hidden="true">
            <Waves size={21} strokeWidth={2.4} />
          </span>
          <span>Poolside</span>
        </div>
        <button
          className="sidebar-close icon-button"
          type="button"
          aria-label="Close navigation"
          onClick={() => setMobileMenuOpen(false)}
        >
          <X size={20} />
        </button>
        <div className="pool-switcher">
          <span className="pool-avatar" aria-hidden="true">
            <Droplets size={18} />
          </span>
          <span>
            <strong>{poolName}</strong>
            <small>Salt · Plaster · {Number(gallons).toLocaleString()} gal</small>
          </span>
          <ChevronDown size={16} aria-hidden="true" />
        </div>
        <nav className="primary-nav" aria-label="Main navigation">
          <NavButton
            active={view === "today"}
            icon={<ClipboardCheck size={19} />}
            label="Today"
            onClick={() => navigate("today")}
          />
          <NavButton
            active={view === "costs"}
            icon={<CircleDollarSign size={19} />}
            label="Costs"
            onClick={() => navigate("costs")}
          />
          <NavButton
            active={view === "learn"}
            icon={<BookOpen size={19} />}
            label="Learn"
            onClick={() => navigate("learn")}
          />
        </nav>
        <div className="sidebar-principle">
          <ShieldCheck size={18} aria-hidden="true" />
          <p>
            <strong>One change at a time.</strong>
            <span>Measure, act, circulate, retest.</span>
          </p>
        </div>
      </aside>

      {mobileMenuOpen && (
        <button
          className="sidebar-scrim"
          aria-label="Close navigation"
          onClick={() => setMobileMenuOpen(false)}
        />
      )}

      <main className="main-shell">
        <header className="topbar">
          <button
            className="menu-button icon-button"
            type="button"
            aria-label="Open navigation"
            onClick={() => setMobileMenuOpen(true)}
          >
            <Menu size={21} />
          </button>
          <div>
            <p className="date-label">
              {new Intl.DateTimeFormat("en-US", {
                weekday: "long",
                month: "long",
                day: "numeric",
              }).format(new Date())}
            </p>
            <h1>
              {view === "today"
                ? "Today’s pool care"
                : view === "costs"
                  ? "Chemical costs"
                  : "Pool care, explained"}
            </h1>
          </div>
          {view !== "today" && (
            <button
              className="button button-primary topbar-action"
              type="button"
              onClick={() => navigate("today")}
            >
              <TestTube2 size={17} />
              <span>Log a test</span>
            </button>
          )}
        </header>

        {view === "today" && (
          <TodayView
            appearance={appearance}
            completedActions={completedActions}
            error={error}
            gallons={gallons}
            logs={logs}
            method={method}
            plan={plan}
            poolName={poolName}
            readings={readings}
            status={status}
            targets={targets}
            onAppearanceChange={setAppearance}
            onApplyExample={applyExample}
            onGallonsChange={setGallons}
            onMethodChange={setMethod}
            onPoolNameChange={setPoolName}
            onReadingChange={(key, value) =>
              setReadings((current) => ({ ...current, [key]: value }))
            }
            onSubmit={handleSubmit}
            onTargetChange={(key, value) =>
              setTargets((current) => ({ ...current, [key]: value }))
            }
            onToggleAction={toggleAction}
          />
        )}
        {view === "costs" && (
          <CostsView
            logs={logs}
            monthSpend={monthSpend}
            plan={plan}
            prices={prices}
            onPriceChange={(key, value) =>
              setPrices((current) => ({ ...current, [key]: value }))
            }
          />
        )}
        {view === "learn" && <LearnView />}
      </main>

      <nav className="mobile-nav" aria-label="Mobile navigation">
        <NavButton
          active={view === "today"}
          icon={<ClipboardCheck size={19} />}
          label="Today"
          onClick={() => navigate("today")}
        />
        <NavButton
          active={view === "costs"}
          icon={<CircleDollarSign size={19} />}
          label="Costs"
          onClick={() => navigate("costs")}
        />
        <NavButton
          active={view === "learn"}
          icon={<BookOpen size={19} />}
          label="Learn"
          onClick={() => navigate("learn")}
        />
      </nav>
    </div>
  );
}

function NavButton({
  active,
  icon,
  label,
  onClick,
}: {
  active: boolean;
  icon: React.ReactNode;
  label: string;
  onClick: () => void;
}) {
  return (
    <button
      type="button"
      className={`nav-button ${active ? "nav-button-active" : ""}`}
      onClick={onClick}
      aria-current={active ? "page" : undefined}
    >
      {icon}
      <span>{label}</span>
    </button>
  );
}

function TodayView({
  appearance,
  completedActions,
  error,
  gallons,
  logs,
  method,
  plan,
  poolName,
  readings,
  status,
  targets,
  onAppearanceChange,
  onApplyExample,
  onGallonsChange,
  onMethodChange,
  onPoolNameChange,
  onReadingChange,
  onSubmit,
  onTargetChange,
  onToggleAction,
}: {
  appearance: Appearance;
  completedActions: number[];
  error: string;
  gallons: string;
  logs: TestLog[];
  method: TestMethod;
  plan: PoolPlan | null;
  poolName: string;
  readings: FormReadings;
  status:
    | { eyebrow: string; title: string; description: string }
    | null;
  targets: TargetState;
  onAppearanceChange: (value: Appearance) => void;
  onApplyExample: () => void;
  onGallonsChange: (value: string) => void;
  onMethodChange: (value: TestMethod) => void;
  onPoolNameChange: (value: string) => void;
  onReadingChange: (key: ReadingKey, value: string) => void;
  onSubmit: (event: FormEvent<HTMLFormElement>) => void;
  onTargetChange: (key: keyof TargetState, value: number) => void;
  onToggleAction: (index: number) => void;
}) {
  const actionCount = plan?.actions.length ?? 0;
  return (
    <div className="content-stack">
      <section className="summary-grid" aria-label="Pool care summary">
        <div
          className={`status-panel ${
            plan?.swimStatus === "pause" ? "status-panel-warning" : ""
          }`}
        >
          <div className="status-icon" aria-hidden="true">
            {plan?.swimStatus === "pause" ? (
              <AlertTriangle size={25} />
            ) : (
              <Waves size={25} />
            )}
          </div>
          <div>
            <p className="eyebrow">{status?.eyebrow ?? "Next step"}</p>
            <h2>{status?.title ?? "Start with today’s readings"}</h2>
            <p>
              {status?.description ??
                "Use any reliable test method. The plan will tell you what matters first."}
            </p>
          </div>
        </div>
        <div className="metric-panel">
          <span className="metric-icon metric-icon-cost" aria-hidden="true">
            <CircleDollarSign size={19} />
          </span>
          <div>
            <p>Plan cost</p>
            <strong>${(plan?.estimatedCost ?? 0).toFixed(2)}</strong>
            <small>Based on your unit prices</small>
          </div>
        </div>
        <div className="metric-panel">
          <span className="metric-icon metric-icon-action" aria-hidden="true">
            <ClipboardCheck size={19} />
          </span>
          <div>
            <p>Today’s steps</p>
            <strong>
              {plan ? `${completedActions.length} / ${actionCount}` : "—"}
            </strong>
            <small>{plan ? "Completed" : "Build a plan first"}</small>
          </div>
        </div>
      </section>

      <div className="work-grid">
        <section className="plan-section" id="care-plan">
          <div className="section-heading">
            <div>
              <p className="eyebrow">Ordered for safety</p>
              <h2>Your care plan</h2>
            </div>
            {plan && (
              <span className="plan-count">
                {actionCount} {actionCount === 1 ? "step" : "steps"}
              </span>
            )}
          </div>
          {!plan ? (
            <div className="empty-plan">
              <span className="empty-plan-icon" aria-hidden="true">
                <FlaskConical size={28} />
              </span>
              <h3>No plan yet</h3>
              <p>
                Enter today’s measurements. Poolside will prioritize safety,
                avoid unnecessary products, and split calculated additions into
                retestable steps.
              </p>
              <button
                className="button button-secondary"
                type="button"
                onClick={onApplyExample}
              >
                <Beaker size={17} />
                Load example readings
              </button>
            </div>
          ) : (
            <div className="action-list">
              {plan.actions.map((item, index) => {
                const complete = completedActions.includes(index);
                return (
                  <article
                    className={`action-item action-${item.kind} ${
                      complete ? "action-complete" : ""
                    }`}
                    key={`${item.title}-${index}`}
                  >
                    <button
                      className="action-check"
                      type="button"
                      aria-label={
                        complete
                          ? `Mark ${item.title} incomplete`
                          : `Mark ${item.title} complete`
                      }
                      aria-pressed={complete}
                      onClick={() => onToggleAction(index)}
                    >
                      {complete ? (
                        <Check size={17} strokeWidth={3} />
                      ) : (
                        <span>{index + 1}</span>
                      )}
                    </button>
                    <div className="action-content">
                      <div className="action-heading">
                        <div>
                          {item.parameter && (
                            <p className="action-parameter">{item.parameter}</p>
                          )}
                          <h3>{item.title}</h3>
                        </div>
                        {item.estimatedCost > 0 && (
                          <span className="cost-chip">
                            ${item.estimatedCost.toFixed(2)}
                          </span>
                        )}
                      </div>
                      {item.amount && (
                        <div className="dose-row">
                          <strong>{item.amount}</strong>
                          {item.chemical && <span>{item.chemical}</span>}
                        </div>
                      )}
                      <p className="action-detail">{item.detail}</p>
                      <details className="why-details">
                        <summary>
                          <Info size={15} aria-hidden="true" />
                          Why this step
                        </summary>
                        <p>{item.reason}</p>
                      </details>
                      <div className="retest-row">
                        <History size={15} aria-hidden="true" />
                        <span>{item.verification}</span>
                      </div>
                    </div>
                  </article>
                );
              })}
              <div className="guardrail-band">
                <ShieldCheck size={19} aria-hidden="true" />
                <div>
                  <strong>Before you add anything</strong>
                  <p>{plan.guardrails.join(" ")}</p>
                </div>
              </div>
            </div>
          )}
        </section>

        <aside className="test-panel">
          <div className="section-heading">
            <div>
              <p className="eyebrow">Any trusted test method</p>
              <h2>Today’s test</h2>
            </div>
            <TestTube2 size={20} aria-hidden="true" />
          </div>
          <form onSubmit={onSubmit}>
            <div className="profile-fields">
              <label>
                <span>Pool name</span>
                <input
                  value={poolName}
                  onChange={(event) => onPoolNameChange(event.target.value)}
                  required
                />
              </label>
              <label>
                <span>Volume</span>
                <div className="unit-input">
                  <input
                    inputMode="numeric"
                    min="1000"
                    max="100000"
                    type="number"
                    value={gallons}
                    onChange={(event) => onGallonsChange(event.target.value)}
                    required
                  />
                  <span>gal</span>
                </div>
              </label>
            </div>
            <div className="target-group">
              <div className="target-group-heading">
                <span>Equipment targets</span>
                <small>Use your salt generator manual</small>
              </div>
              <div className="target-fields">
                <label>
                  <span>CYA target</span>
                  <div className="unit-input">
                    <input
                      min="30"
                      max="80"
                      step="1"
                      type="number"
                      value={targets.cyanuricAcid}
                      onChange={(event) =>
                        onTargetChange(
                          "cyanuricAcid",
                          Number(event.target.value),
                        )
                      }
                      required
                    />
                    <span>ppm</span>
                  </div>
                </label>
                <label>
                  <span>Salt target</span>
                  <div className="unit-input">
                    <input
                      min="2000"
                      max="5000"
                      step="10"
                      type="number"
                      value={targets.salt}
                      onChange={(event) =>
                        onTargetChange("salt", Number(event.target.value))
                      }
                      required
                    />
                    <span>ppm</span>
                  </div>
                </label>
              </div>
            </div>
            <fieldset>
              <legend>Test source</legend>
              <div className="segmented-control segmented-three">
                {(Object.keys(methodLabels) as TestMethod[]).map((item) => (
                  <label key={item}>
                    <input
                      type="radio"
                      name="method"
                      value={item}
                      checked={method === item}
                      onChange={() => onMethodChange(item)}
                    />
                    <span>{methodLabels[item]}</span>
                  </label>
                ))}
              </div>
            </fieldset>
            <div className="reading-grid">
              {readingFields.map((field) => (
                <label className="reading-field" key={field.key}>
                  <span className="reading-label">
                    <strong>{field.short}</strong>
                    <span>{field.label}</span>
                  </span>
                  <div className="unit-input">
                    <input
                      aria-describedby={`${field.key}-hint`}
                      inputMode="decimal"
                      min="0"
                      step={field.step}
                      type="number"
                      value={readings[field.key]}
                      onChange={(event) =>
                        onReadingChange(field.key, event.target.value)
                      }
                      required
                    />
                    {field.unit && <span>{field.unit}</span>}
                  </div>
                  <small id={`${field.key}-hint`}>{field.hint}</small>
                </label>
              ))}
            </div>
            <fieldset>
              <legend>Water appearance</legend>
              <div className="segmented-control segmented-three appearance-control">
                {(Object.keys(appearanceLabels) as Appearance[]).map((item) => (
                  <label key={item}>
                    <input
                      type="radio"
                      name="appearance"
                      value={item}
                      checked={appearance === item}
                      onChange={() => onAppearanceChange(item)}
                    />
                    <span>
                      <i className={`appearance-dot dot-${item}`} />
                      {appearanceLabels[item]}
                    </span>
                  </label>
                ))}
              </div>
            </fieldset>
            {error && (
              <div className="form-error" role="alert">
                <AlertTriangle size={17} />
                <span>{error}</span>
              </div>
            )}
            <button className="button button-primary submit-button" type="submit">
              <Sparkles size={18} />
              Build my plan
            </button>
            <button
              className="text-button"
              type="button"
              onClick={onApplyExample}
            >
              Use sample readings
            </button>
          </form>
        </aside>
      </div>

      {logs.length > 0 && (
        <section className="history-section">
          <div className="section-heading">
            <div>
              <p className="eyebrow">Device-local record</p>
              <h2>Recent tests</h2>
            </div>
          </div>
          <div className="history-table-wrap">
            <table>
              <thead>
                <tr>
                  <th>Date</th>
                  <th>FC</th>
                  <th>pH</th>
                  <th>TA</th>
                  <th>CYA</th>
                  <th>Status</th>
                  <th>Plan cost</th>
                </tr>
              </thead>
              <tbody>
                {logs.slice(0, 6).map((log) => (
                  <tr key={log.id}>
                    <td>
                      {new Intl.DateTimeFormat("en-US", {
                        month: "short",
                        day: "numeric",
                        hour: "numeric",
                        minute: "2-digit",
                      }).format(new Date(log.createdAt))}
                    </td>
                    <td>{log.readings.freeChlorine}</td>
                    <td>{log.readings.ph}</td>
                    <td>{log.readings.totalAlkalinity}</td>
                    <td>{log.readings.cyanuricAcid}</td>
                    <td>
                      <span
                        className={`table-status ${
                          log.swimStatus === "pause"
                            ? "table-status-warning"
                            : ""
                        }`}
                      >
                        {log.swimStatus === "pause" ? "Pause" : "Ready"}
                      </span>
                    </td>
                    <td>${log.cost.toFixed(2)}</td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </section>
      )}
    </div>
  );
}

function CostsView({
  logs,
  monthSpend,
  plan,
  prices,
  onPriceChange,
}: {
  logs: TestLog[];
  monthSpend: number;
  plan: PoolPlan | null;
  prices: PriceState;
  onPriceChange: (key: keyof PriceState, value: number) => void;
}) {
  const priceFields: Array<{
    key: keyof PriceState;
    label: string;
    unit: string;
  }> = [
    {
      key: "liquidChlorineGallon",
      label: "10% liquid chlorine",
      unit: "per gal",
    },
    { key: "bakingSodaPound", label: "Baking soda", unit: "per lb" },
    { key: "saltPound", label: "Pool salt", unit: "per lb" },
    { key: "stabilizerPound", label: "Dry stabilizer", unit: "per lb" },
  ];
  return (
    <div className="content-stack">
      <section className="cost-summary">
        <div>
          <p className="eyebrow">This month</p>
          <strong>${monthSpend.toFixed(2)}</strong>
          <span>planned chemical spend</span>
        </div>
        <div>
          <p className="eyebrow">Current plan</p>
          <strong>${(plan?.estimatedCost ?? 0).toFixed(2)}</strong>
          <span>using staged first doses</span>
        </div>
        <div>
          <p className="eyebrow">Tests logged</p>
          <strong>{logs.length}</strong>
          <span>on this device</span>
        </div>
      </section>
      <div className="cost-layout">
        <section className="content-panel">
          <div className="section-heading">
            <div>
              <p className="eyebrow">Use shelf prices you can verify</p>
              <h2>Your unit prices</h2>
            </div>
          </div>
          <div className="price-list">
            {priceFields.map((field) => (
              <label key={field.key}>
                <span>
                  <strong>{field.label}</strong>
                  <small>{field.unit}</small>
                </span>
                <div className="currency-input">
                  <span>$</span>
                  <input
                    min="0"
                    step="0.01"
                    type="number"
                    value={prices[field.key]}
                    onChange={(event) =>
                      onPriceChange(field.key, Number(event.target.value))
                    }
                  />
                </div>
              </label>
            ))}
          </div>
        </section>
        <section className="content-panel">
          <div className="section-heading">
            <div>
              <p className="eyebrow">Compare active ingredients</p>
              <h2>Buy the chemical, not the label</h2>
            </div>
          </div>
          <div className="buying-rules">
            <Rule
              number="01"
              title="Match concentration"
              text="A cheaper jug is not cheaper if it contains less active ingredient. Compare strength and usable quantity."
            />
            <Rule
              number="02"
              title="Price one correction"
              text="Use the staged dose cost, not the package price, to compare products."
            />
            <Rule
              number="03"
              title="Skip speculative fixes"
              text="If a reading is already in range, its chemical cost should be $0."
            />
            <Rule
              number="04"
              title="Respect shelf life"
              text="Liquid chlorine loses strength in heat and storage. A bulk deal can become false savings."
            />
          </div>
        </section>
      </div>
    </div>
  );
}

function Rule({
  number,
  title,
  text,
}: {
  number: string;
  title: string;
  text: string;
}) {
  return (
    <div className="buying-rule">
      <span>{number}</span>
      <div>
        <strong>{title}</strong>
        <p>{text}</p>
      </div>
    </div>
  );
}

function LearnView() {
  const lessons = [
    {
      short: "FC",
      title: "Free chlorine",
      text: "The chlorine still available to sanitize. Sun, swimmers, debris, and algae consume it.",
      decision: "Act quickly when it is low; verify CYA when it will not hold.",
    },
    {
      short: "pH",
      title: "pH",
      text: "A measure of acidity. It affects swimmer comfort, equipment, surfaces, and how water behaves.",
      decision: "Correct out-of-range pH in measured steps; acid demand depends on more than pH alone.",
    },
    {
      short: "TA",
      title: "Total alkalinity",
      text: "The water’s buffer against rapid pH change. Salt systems often create steady upward pH pressure.",
      decision: "Treat the trend, not one number. Baking soda raises TA; it is not a general clarifier.",
    },
    {
      short: "CYA",
      title: "Cyanuric acid",
      text: "Sun protection for chlorine outdoors. Too little wastes chlorine; too much raises the chlorine needed.",
      decision: "Add conservatively because lowering CYA usually means replacing water.",
    },
    {
      short: "CH",
      title: "Calcium hardness",
      text: "Part of the balance that protects plaster while limiting scale on surfaces and the salt cell.",
      decision: "Confirm before correcting because overdosing is difficult to reverse.",
    },
    {
      short: "SALT",
      title: "Salt",
      text: "Feedstock for the chlorine generator. The correct range belongs to the generator manufacturer.",
      decision: "Confirm independently before adding; generator displays can drift.",
    },
  ];
  return (
    <div className="content-stack">
      <section className="learn-intro">
        <div>
          <p className="eyebrow">A six-reading mental model</p>
          <h2>Read the water, not the aisle</h2>
          <p>
            Know which reading controls the next decision, which changes are
            hard to reverse, and when the correct move is to wait.
          </p>
        </div>
        <div className="learning-loop" aria-label="Maintenance loop">
          <span>1</span>
          <strong>Measure</strong>
          <i />
          <span>2</span>
          <strong>Act</strong>
          <i />
          <span>3</span>
          <strong>Retest</strong>
        </div>
      </section>
      <section className="lesson-grid">
        {lessons.map((lesson) => (
          <article className="lesson-card" key={lesson.short}>
            <span className="lesson-short">{lesson.short}</span>
            <h3>{lesson.title}</h3>
            <p>{lesson.text}</p>
            <div>
              <Info size={15} aria-hidden="true" />
              <span>{lesson.decision}</span>
            </div>
          </article>
        ))}
      </section>
      <section className="escalation-band">
        <AlertTriangle size={22} aria-hidden="true" />
        <div>
          <h3>Know when the app should stop</h3>
          <p>
            Escalate for a pool bottom you cannot see, conflicting test results,
            repeated sanitizer loss, metal stains, major leaks, draining risk,
            or any product label that conflicts with a generic calculation.
          </p>
        </div>
      </section>
    </div>
  );
}
