import { useEffect, useState } from "react";
import { api } from "../api/client";
import type { Profile as ProfileType } from "../types/api";

function NumberField({
  label,
  value,
  onChange,
  step = 1,
}: {
  label: string;
  value: number;
  onChange: (v: number) => void;
  step?: number;
}) {
  return (
    <label>
      {label}
      <input
        type="number"
        step={step}
        value={value}
        onChange={(e) => onChange(Number(e.target.value))}
      />
    </label>
  );
}

function NullableNumberField({
  label,
  value,
  onChange,
}: {
  label: string;
  value: number | null;
  onChange: (v: number | null) => void;
}) {
  return (
    <label>
      {label}
      <input
        type="number"
        value={value ?? ""}
        onChange={(e) => onChange(e.target.value === "" ? null : Number(e.target.value))}
      />
    </label>
  );
}

export function Profile() {
  const [profile, setProfile] = useState<ProfileType | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [saved, setSaved] = useState(false);

  useEffect(() => {
    api.getProfile().then(setProfile).catch((e) => setError(String(e)));
  }, []);

  function set<K extends keyof ProfileType>(key: K, value: ProfileType[K]) {
    setProfile((p) => (p ? { ...p, [key]: value } : p));
    setSaved(false);
  }

  async function save() {
    if (!profile) return;
    setError(null);
    try {
      const updated = await api.updateProfile(profile);
      setProfile(updated);
      setSaved(true);
    } catch (e) {
      setError(String(e));
      setSaved(false);
    }
  }

  if (!profile) {
    return (
      <div className="page">
        <h2>Profile</h2>
        {error ? <p className="error">{error}</p> : <p>Loading...</p>}
      </div>
    );
  }

  return (
    <div className="page">
      <h2>Profile</h2>
      {error && <p className="error">{error}</p>}
      {saved && <p className="garmin-connection-message">Saved.</p>}

      <fieldset className="kind-editor">
        <legend>Garmin account</legend>
        <label>
          Email
          <input
            type="text"
            value={profile.GarminEmail}
            onChange={(e) => set("GarminEmail", e.target.value)}
          />
        </label>
        <label>
          Password
          <input
            type="password"
            value={profile.GarminPassword}
            onChange={(e) => set("GarminPassword", e.target.value)}
          />
        </label>
      </fieldset>

      <fieldset className="kind-editor">
        <legend>Classification</legend>
        <NumberField
          label="Rolling window (days)"
          value={profile.RollingWindowDays}
          onChange={(v) => set("RollingWindowDays", v)}
        />
      </fieldset>

      <fieldset className="kind-editor">
        <legend>Heart rate</legend>
        <NullableNumberField
          label="Max heart rate (bpm)"
          value={profile.MaxHeartRate}
          onChange={(v) => set("MaxHeartRate", v)}
        />
        <NullableNumberField
          label="Resting heart rate (bpm)"
          value={profile.RestingHeartRate}
          onChange={(v) => set("RestingHeartRate", v)}
        />
        {([1, 2, 3, 4, 5] as const).map((zone) => (
          <div key={zone} className="controls">
            <NumberField
              label={`Zone ${zone} min %HRR`}
              value={profile[`HRZone${zone}MinPct` as keyof ProfileType] as number}
              onChange={(v) => set(`HRZone${zone}MinPct` as keyof ProfileType, v as never)}
            />
            <NumberField
              label={`Zone ${zone} max %HRR`}
              value={profile[`HRZone${zone}MaxPct` as keyof ProfileType] as number}
              onChange={(v) => set(`HRZone${zone}MaxPct` as keyof ProfileType, v as never)}
            />
          </div>
        ))}
      </fieldset>

      <button onClick={save}>Save</button>
    </div>
  );
}
