const { useEffect, useMemo, useRef, useState } = React;

const STORAGE_KEY = "parrot-pulse-react-state";
const MAX_PARROTS = 2;
const SPECIES_RANGES = {
  "虎皮鹦鹉": { min: 30, max: 40 },
  "牡丹鹦鹉": { min: 40, max: 60 },
  "玄凤鹦鹉": { min: 80, max: 120 },
  "和尚鹦鹉": { min: 90, max: 140 },
  "太平洋鹦鹉": { min: 24, max: 32 },
  "塞内加尔鹦鹉": { min: 120, max: 170 },
  "非洲灰鹦鹉": { min: 380, max: 520 },
  "亚马逊鹦鹉": { min: 300, max: 500 },
  "金太阳锥尾鹦鹉": { min: 95, max: 130 },
  "葵花凤头鹦鹉": { min: 500, max: 900 },
  "金刚鹦鹉": { min: 900, max: 1500 },
};

function getTodayString() {
  const today = new Date();
  const offset = today.getTimezoneOffset() * 60 * 1000;
  return new Date(today.getTime() - offset).toISOString().slice(0, 10);
}

function generateId(prefix) {
  return `${prefix}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
}

function loadState() {
  const raw = localStorage.getItem(STORAGE_KEY);

  if (!raw) {
    const firstId = generateId("parrot");
    return {
      parrots: [
        {
          id: firstId,
          name: "Kiwi",
          species: "虎皮鹦鹉",
          birthday: "",
          sex: "",
          photo: "",
        },
      ],
      activeParrotId: firstId,
      records: [],
    };
  }

  try {
    const parsed = JSON.parse(raw);
    if (!parsed.parrots?.length) {
      throw new Error("invalid state");
    }
    return parsed;
  } catch {
    localStorage.removeItem(STORAGE_KEY);
    return loadState();
  }
}

function saveState(nextState) {
  try {
    localStorage.setItem(STORAGE_KEY, JSON.stringify(nextState));
    return { ok: true };
  } catch (error) {
    return {
      ok: false,
      message: "保存失败，可能是上传图片过大。可以换一张更小的照片，或先导出 JSON 备份后再继续。",
    };
  }
}

function formatDate(dateString) {
  return new Intl.DateTimeFormat("zh-CN", {
    month: "short",
    day: "numeric",
    weekday: "short",
  }).format(new Date(dateString));
}

function rangeText(species) {
  const range = SPECIES_RANGES[species];
  return range ? `${range.min}-${range.max}g` : "暂无内置参考";
}

function evaluateWeight(species, weight) {
  const range = SPECIES_RANGES[species];
  const numericWeight = Number(weight);

  if (!range || !weight || Number.isNaN(numericWeight)) {
    return null;
  }

  if (numericWeight < range.min) {
    return {
      tone: "alert",
      short: "低于参考区间",
      message: `当前体重低于 ${species} 常见参考区间 ${range.min}-${range.max}g，建议结合食欲、精神和排便继续观察。`,
    };
  }

  if (numericWeight > range.max) {
    return {
      tone: "alert",
      short: "高于参考区间",
      message: `当前体重高于 ${species} 常见参考区间 ${range.min}-${range.max}g，可以留意近期饮食、活动量和体态变化。`,
    };
  }

  return {
    tone: "good",
    short: "落在参考区间",
    message: `当前体重落在 ${species} 常见参考区间 ${range.min}-${range.max}g 内。`,
  };
}

function buildAlerts(parrot, records) {
  if (!parrot) return [];

  const alerts = [];
  const sorted = [...records].sort((a, b) => b.date.localeCompare(a.date));
  const latest = sorted[0];

  if (!latest) {
    alerts.push({
      tone: "soft",
      title: "还没有健康记录",
      body: "先记下第一条体重和状态，异常提醒才会开始工作。",
    });
    return alerts;
  }

  const latestWeightStatus = evaluateWeight(parrot.species, latest.weight);
  if (latestWeightStatus && latestWeightStatus.tone === "alert") {
    alerts.push({
      tone: "alert",
      title: "最近体重超出常见区间",
      body: latestWeightStatus.message,
    });
  }

  if (sorted.length >= 3) {
    const lastThree = sorted.slice(0, 3).map((item) => Number(item.weight));
    if (lastThree[0] < lastThree[1] && lastThree[1] < lastThree[2]) {
      alerts.push({
        tone: "alert",
        title: "体重连续 3 次下降",
        body: "最近三条记录都在下降，建议结合食欲、精神状态和饮食变化重点观察。",
      });
    }
  }

  if (latest.appetite === "偏差" || latest.mood === "异常" || latest.droppings === "异常") {
    alerts.push({
      tone: "alert",
      title: "最近状态里有异常项",
      body: `最近一次记录包含 ${[
        latest.appetite === "偏差" ? "食欲偏差" : "",
        latest.mood === "异常" ? "精神异常" : "",
        latest.droppings === "异常" ? "排便异常" : "",
      ]
        .filter(Boolean)
        .join("、")}，建议持续复查。`,
    });
  }

  if (!alerts.length) {
    alerts.push({
      tone: "good",
      title: "最近状态比较稳定",
      body: "目前没有明显异常趋势，可以继续按天记录，帮助你更早发现变化。",
    });
  }

  return alerts;
}

function blobToDataUrl(blob) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = () => resolve(String(reader.result || ""));
    reader.onerror = () => reject(new Error("读取图片失败"));
    reader.readAsDataURL(blob);
  });
}

function canvasToBlob(canvas, quality) {
  return new Promise((resolve, reject) => {
    canvas.toBlob(
      (blob) => {
        if (!blob) {
          reject(new Error("图片压缩失败"));
          return;
        }
        resolve(blob);
      },
      "image/jpeg",
      quality
    );
  });
}

function loadImageFromObjectUrl(url) {
  return new Promise((resolve, reject) => {
    const image = new Image();
    image.onload = () => resolve(image);
    image.onerror = () => reject(new Error("这张图片暂时处理不了，建议换成 JPG 或 PNG 再试一次"));
    image.src = url;
  });
}

async function fileToDataUrl(file, options = {}) {
  if (!file) {
    return "";
  }

  if (!file.type.startsWith("image/")) {
    throw new Error("请选择图片文件");
  }

  if (file.size > 20 * 1024 * 1024) {
    throw new Error("图片太大了，建议先换一张 20MB 以内的照片");
  }

  const { maxSize = 768, quality = 0.72 } = options;
  const objectUrl = URL.createObjectURL(file);

  try {
    const image = await loadImageFromObjectUrl(objectUrl);
    const scale = Math.min(maxSize / image.width, maxSize / image.height, 1);
    const canvas = document.createElement("canvas");
    canvas.width = Math.max(1, Math.round(image.width * scale));
    canvas.height = Math.max(1, Math.round(image.height * scale));
    const context = canvas.getContext("2d");

    if (!context) {
      throw new Error("当前浏览器暂时不能处理这张图片");
    }

    context.drawImage(image, 0, 0, canvas.width, canvas.height);
    const blob = await canvasToBlob(canvas, quality);
    return await blobToDataUrl(blob);
  } finally {
    URL.revokeObjectURL(objectUrl);
  }
}

function downloadFile(filename, content, type) {
  const blob = new Blob([content], { type });
  const url = URL.createObjectURL(blob);
  const link = document.createElement("a");
  link.href = url;
  link.download = filename;
  link.click();
  URL.revokeObjectURL(url);
}

function toCsvValue(value) {
  const text = String(value ?? "");
  const escaped = text.replace(/"/g, '""');
  return `"${escaped}"`;
}

function exportStateAsJson(state) {
  const content = JSON.stringify(state, null, 2);
  downloadFile("parrot-pulse-backup.json", content, "application/json;charset=utf-8");
}

function exportStateAsCsv(state) {
  const parrotMap = Object.fromEntries(state.parrots.map((parrot) => [parrot.id, parrot]));
  const header = [
    "parrotId",
    "parrotName",
    "species",
    "date",
    "weight",
    "appetite",
    "mood",
    "droppings",
    "notes",
    "hasPhoto",
  ];

  const rows = state.records
    .slice()
    .sort((a, b) => a.date.localeCompare(b.date))
    .map((record) => {
      const parrot = parrotMap[record.parrotId] || {};
      return [
        record.parrotId,
        parrot.name || "",
        parrot.species || "",
        record.date,
        record.weight,
        record.appetite,
        record.mood,
        record.droppings,
        record.notes || "",
        record.photo ? "yes" : "no",
      ]
        .map(toCsvValue)
        .join(",");
    });

  const content = [header.join(","), ...rows].join("\n");
  downloadFile("parrot-pulse-records.csv", content, "text/csv;charset=utf-8");
}

function WeightTrendChart({ records }) {
  if (records.length < 2) {
    return <div className="empty-state">至少记录 2 天体重后，这里会出现趋势折线图。</div>;
  }

  const ordered = [...records]
    .slice()
    .sort((a, b) => a.date.localeCompare(b.date))
    .slice(-7);
  const weights = ordered.map((record) => Number(record.weight));
  const min = Math.min(...weights);
  const max = Math.max(...weights);
  const range = Math.max(max - min, 1);
  const width = 320;
  const height = 160;
  const padding = 16;

  const points = ordered.map((record, index) => {
    const x = padding + (index * (width - padding * 2)) / Math.max(ordered.length - 1, 1);
    const y = height - padding - ((Number(record.weight) - min) / range) * (height - padding * 2);
    return {
      x,
      y,
      weight: record.weight,
      date: record.date,
    };
  });

  const path = points.map((point, index) => `${index === 0 ? "M" : "L"} ${point.x} ${point.y}`).join(" ");

  return (
    <div className="trend-chart-wrap">
      <svg viewBox={`0 0 ${width} ${height}`} className="trend-chart" role="img" aria-label="体重趋势折线图">
        <defs>
          <linearGradient id="trendLine" x1="0%" y1="0%" x2="100%" y2="0%">
            <stop offset="0%" stopColor="#f28f3b" />
            <stop offset="100%" stopColor="#6b9c59" />
          </linearGradient>
        </defs>
        {[0, 1, 2, 3].map((step) => {
          const y = padding + (step * (height - padding * 2)) / 3;
          return <line key={step} x1={padding} y1={y} x2={width - padding} y2={y} className="trend-grid-line" />;
        })}
        <path d={path} fill="none" stroke="url(#trendLine)" strokeWidth="4" strokeLinecap="round" />
        {points.map((point) => (
          <g key={point.date}>
            <circle cx={point.x} cy={point.y} r="5" className="trend-point" />
            <text x={point.x} y={point.y - 10} textAnchor="middle" className="trend-point-label">
              {point.weight}g
            </text>
          </g>
        ))}
      </svg>
      <div className="trend-axis">
        {ordered.map((record) => (
          <span key={record.date}>{record.date.slice(5)}</span>
        ))}
      </div>
    </div>
  );
}

function MobileShell({ children }) {
  return (
    <div className="mobile-shell">
      <div className="mobile-device">
        <div className="device-topbar">
          <span>9:41</span>
          <span>Parrot Pulse</span>
          <span>100%</span>
        </div>
        {children}
      </div>
    </div>
  );
}

function AppSection({ kicker, title, action, children, className = "" }) {
  return (
    <section className={`section-card ${className}`.trim()}>
      <div className="section-head">
        <div>
          <p className="section-kicker">{kicker}</p>
          <h2>{title}</h2>
        </div>
        {action || null}
      </div>
      {children}
    </section>
  );
}

function App() {
  const [state, setState] = useState(loadState);
  const [currentTab, setCurrentTab] = useState("home");
  const [selectedRecordId, setSelectedRecordId] = useState("");
  const [isEditingRecord, setIsEditingRecord] = useState(false);
  const [profileDraft, setProfileDraft] = useState({
    name: "",
    species: "虎皮鹦鹉",
    birthday: "",
    sex: "",
    photo: "",
  });
  const [recordDraft, setRecordDraft] = useState({
    date: getTodayString(),
    weight: "",
    appetite: "很好",
    mood: "活跃",
    droppings: "正常",
    notes: "",
    photo: "",
  });
  const [saveMessage, setSaveMessage] = useState("");
  const [saveTone, setSaveTone] = useState("good");
  const [uploadingTarget, setUploadingTarget] = useState("");
  const profilePhotoRef = useRef(null);
  const recordPhotoRef = useRef(null);

  const showToast = (tone, message) => {
    setSaveTone(tone);
    setSaveMessage(message);
  };

  const resetRecordDraft = () => {
    setRecordDraft({
      date: getTodayString(),
      weight: "",
      appetite: "很好",
      mood: "活跃",
      droppings: "正常",
      notes: "",
      photo: "",
    });
    setIsEditingRecord(false);
    setSelectedRecordId("");
    if (recordPhotoRef.current) {
      recordPhotoRef.current.value = "";
    }
  };

  const activeParrot = useMemo(
    () => state.parrots.find((parrot) => parrot.id === state.activeParrotId) || state.parrots[0],
    [state]
  );

  const activeRecords = useMemo(
    () =>
      state.records
        .filter((record) => record.parrotId === activeParrot?.id)
        .sort((a, b) => b.date.localeCompare(a.date)),
    [state.records, activeParrot]
  );

  const weightStatus = useMemo(
    () => evaluateWeight(profileDraft.species, recordDraft.weight),
    [profileDraft.species, recordDraft.weight]
  );

  const alerts = useMemo(
    () => buildAlerts(activeParrot, activeRecords),
    [activeParrot, activeRecords]
  );

  useEffect(() => {
    if (!activeParrot) return;
    setProfileDraft({
      name: activeParrot.name || "",
      species: activeParrot.species || "虎皮鹦鹉",
      birthday: activeParrot.birthday || "",
      sex: activeParrot.sex || "",
      photo: activeParrot.photo || "",
    });
  }, [activeParrot]);

  useEffect(() => {
    const result = saveState(state);
    if (!result.ok) {
      showToast("alert", result.message);
    }
  }, [state]);

  useEffect(() => {
    if ("serviceWorker" in navigator && window.location.protocol !== "file:") {
      navigator.serviceWorker.register("./service-worker.js").catch(() => {});
    }
  }, []);

  useEffect(() => {
    if (!saveMessage) return;
    const timer = window.setTimeout(() => {
      setSaveMessage("");
    }, 2600);
    return () => window.clearTimeout(timer);
  }, [saveMessage]);

  const addSecondParrot = () => {
    if (state.parrots.length >= MAX_PARROTS) return;

    const id = generateId("parrot");
    const nextParrot = {
      id,
      name: `Parrot ${state.parrots.length + 1}`,
      species: "玄凤鹦鹉",
      birthday: "",
      sex: "",
      photo: "",
    };

    setState((current) => ({
      ...current,
      parrots: [...current.parrots, nextParrot],
      activeParrotId: id,
    }));
  };

  const saveProfileDraft = () => {
    if (!activeParrot) {
      showToast("alert", "当前没有可保存的鹦鹉档案。");
      return;
    }

    setState((current) => ({
      ...current,
      parrots: current.parrots.map((parrot) =>
        parrot.id === activeParrot.id ? { ...parrot, ...profileDraft } : parrot
      ),
    }));
    showToast("good", "档案已保存，资料已经更新。");
    setCurrentTab("home");
  };

  const saveRecordDraft = () => {
    if (!activeParrot) {
      showToast("alert", "请先选择一只鹦鹉。");
      return;
    }

    if (!recordDraft.weight) {
      showToast("alert", "体重还没填，先补上今天的体重。");
      return;
    }

    const nextRecord = {
      id: isEditingRecord && selectedRecordId ? selectedRecordId : generateId("record"),
      parrotId: activeParrot.id,
      ...recordDraft,
    };

    setState((current) => {
      const rest = current.records.filter(
        (record) =>
          record.id !== nextRecord.id &&
          !(record.parrotId === activeParrot.id && record.date === recordDraft.date)
      );
      return {
        ...current,
        records: [...rest, nextRecord],
      };
    });

    resetRecordDraft();
    showToast("good", isEditingRecord ? "健康记录已更新。" : "健康记录已保存，已回到首页。");
    setCurrentTab("home");
  };

  const handleProfilePhotoChange = async (event) => {
    const file = event.target.files?.[0];
    if (!file) return;

    try {
      setUploadingTarget("profile");
      showToast("soft", "正在处理头像图片...");
      const photo = await fileToDataUrl(file, { maxSize: 640, quality: 0.68 });
      setProfileDraft((current) => ({ ...current, photo }));
      showToast("good", "头像已处理完成，记得点“保存当前鹦鹉档案”。");
    } catch (error) {
      showToast("alert", error.message || "头像上传失败，请换一张更小的图片再试一次。");
    } finally {
      setUploadingTarget("");
      event.target.value = "";
    }
  };

  const handleRecordPhotoChange = async (event) => {
    const file = event.target.files?.[0];
    if (!file) return;

    try {
      setUploadingTarget("record");
      showToast("soft", "正在处理记录照片...");
      const photo = await fileToDataUrl(file, { maxSize: 960, quality: 0.72 });
      setRecordDraft((current) => ({ ...current, photo }));
      showToast("good", "记录照片已处理完成，记得点“保存今天的记录”。");
    } catch (error) {
      showToast("alert", error.message || "记录照片上传失败，请换一张更小的图片再试一次。");
    } finally {
      setUploadingTarget("");
      event.target.value = "";
    }
  };

  const latestRecord = activeRecords[0];
  const selectedRecord = activeRecords.find((record) => record.id === selectedRecordId) || null;
  const latestWeightStatus = latestRecord
    ? evaluateWeight(activeParrot?.species, latestRecord.weight)
    : null;
  const todayRecord = activeRecords.find((record) => record.date === getTodayString());

  const startNewRecord = () => {
    resetRecordDraft();
    setCurrentTab("log");
  };

  const editRecord = (record) => {
    setRecordDraft({
      date: record.date,
      weight: String(record.weight),
      appetite: record.appetite,
      mood: record.mood,
      droppings: record.droppings,
      notes: record.notes || "",
      photo: record.photo || "",
    });
    setSelectedRecordId(record.id);
    setIsEditingRecord(true);
    setCurrentTab("log");
    showToast("soft", "已载入这条记录，你可以直接修改并保存。");
  };

  const deleteRecord = (recordId) => {
    const exists = state.records.some((record) => record.id === recordId);
    if (!exists) {
      showToast("alert", "这条记录已经不存在了。");
      return;
    }

    setState((current) => ({
      ...current,
      records: current.records.filter((record) => record.id !== recordId),
    }));

    if (selectedRecordId === recordId) {
      setSelectedRecordId("");
    }

    if (isEditingRecord && selectedRecordId === recordId) {
      resetRecordDraft();
    }

    showToast("good", "这条记录已经删除。");
  };
  const navItems = [
    { id: "home", label: "首页", icon: "·" },
    { id: "log", label: "记录", icon: "·" },
    { id: "trend", label: "趋势", icon: "·" },
    { id: "profile", label: "我的", icon: "·" },
  ];

  const homeView = (
    <>
      <header className="hero-card">
        <div>
          <p className="eyebrow">Parrot Health Tracker</p>
          <h1>
            <span>育鹦书</span>
            <span>更好记录鸟宝日常</span>
          </h1>
          <p className="hero-text">
            现在已经是 App flow 版首页了。你可以从这里快速进入记录、趋势和档案。
          </p>
        </div>
        <div className="hero-badge-stack">
          <div className="hero-badge">
            <strong>{activeParrot?.name || "--"}</strong>
            <span>{activeParrot?.species || "未选择品种"}</span>
          </div>
          <div className="hero-badge">
            <strong>{latestRecord ? `${latestRecord.weight}g` : "--"}</strong>
            <span>{latestWeightStatus?.short || "最近体重"}</span>
          </div>
        </div>
        <div className="quick-actions">
          <button type="button" className="primary-button" onClick={startNewRecord}>
            {todayRecord ? "补充今天记录" : "新增今日记录"}
          </button>
          <button type="button" className="ghost-button" onClick={() => setCurrentTab("profile")}>
            编辑鹦鹉档案
          </button>
        </div>
      </header>

      <section className="summary-grid">
        <article className="metric-card">
          <span>今天状态</span>
          <strong>{todayRecord ? "已记录" : "待填写"}</strong>
        </article>
        <article className="metric-card">
          <span>常见参考</span>
          <strong>{rangeText(activeParrot?.species)}</strong>
        </article>
        <article className="metric-card">
          <span>累计记录</span>
          <strong>{activeRecords.length} 天</strong>
        </article>
        <article className="metric-card">
          <span>照片记录</span>
          <strong>{activeRecords.filter((record) => record.photo).length} 张</strong>
        </article>
      </section>

      <AppSection
        kicker="Parrots"
        title="鹦鹉切换"
        action={
          <button
            type="button"
            className="ghost-button"
            onClick={addSecondParrot}
            disabled={state.parrots.length >= MAX_PARROTS}
          >
            {state.parrots.length >= MAX_PARROTS ? "最多 2 只" : "+ 添加第二只"}
          </button>
        }
      >
        <div className="parrot-switcher">
          {state.parrots.map((parrot) => (
            <button
              key={parrot.id}
              type="button"
              className={`parrot-chip ${parrot.id === activeParrot?.id ? "is-active" : ""}`}
              onClick={() => setState((current) => ({ ...current, activeParrotId: parrot.id }))}
            >
              <span className="chip-avatar">
                {parrot.photo ? <img src={parrot.photo} alt={parrot.name} /> : parrot.name.slice(0, 1)}
              </span>
              <span>
                <strong>{parrot.name}</strong>
                <small>{parrot.species}</small>
              </span>
            </button>
          ))}
        </div>
      </AppSection>

      <AppSection kicker="Today" title="今天的节奏">
        <div className="flow-card-grid">
          <button type="button" className="flow-card" onClick={startNewRecord}>
            <strong>{todayRecord ? "继续记录" : "先记体重"}</strong>
            <span>把今天的体重、精神和食欲补上。</span>
          </button>
          <button type="button" className="flow-card" onClick={() => setCurrentTab("trend")}>
            <strong>看看趋势</strong>
            <span>快速检查最近 7 次体重变化和异常提醒。</span>
          </button>
        </div>
      </AppSection>
    </>
  );

  const logView = (
    <>
      <AppSection
        kicker="Daily Log"
        title={isEditingRecord ? "编辑健康记录" : "新增健康记录"}
        action={
          isEditingRecord ? (
            <button type="button" className="ghost-button" onClick={resetRecordDraft}>
              取消编辑
            </button>
          ) : null
        }
      >
        <div className="form-stack">
          <div className="field-grid">
            <label>
              日期
              <input
                type="date"
                value={recordDraft.date}
                onChange={(event) => setRecordDraft((current) => ({ ...current, date: event.target.value }))}
              />
            </label>
            <label>
              体重（g）
              <input
                type="number"
                min="1"
                step="0.1"
                value={recordDraft.weight}
                onChange={(event) => setRecordDraft((current) => ({ ...current, weight: event.target.value }))}
                placeholder="35.4"
              />
            </label>
            <label>
              食欲
              <select
                value={recordDraft.appetite}
                onChange={(event) => setRecordDraft((current) => ({ ...current, appetite: event.target.value }))}
              >
                <option value="很好">很好</option>
                <option value="正常">正常</option>
                <option value="一般">一般</option>
                <option value="偏差">偏差</option>
              </select>
            </label>
            <label>
              精神
              <select
                value={recordDraft.mood}
                onChange={(event) => setRecordDraft((current) => ({ ...current, mood: event.target.value }))}
              >
                <option value="活跃">活跃</option>
                <option value="正常">正常</option>
                <option value="安静">安静</option>
                <option value="异常">异常</option>
              </select>
            </label>
            <label>
              排便
              <select
                value={recordDraft.droppings}
                onChange={(event) => setRecordDraft((current) => ({ ...current, droppings: event.target.value }))}
              >
                <option value="正常">正常</option>
                <option value="偏稀">偏稀</option>
                <option value="偏干">偏干</option>
                <option value="异常">异常</option>
              </select>
            </label>
          </div>

          <div className={`inline-note ${weightStatus ? `tone-${weightStatus.tone}` : ""}`}>
            {recordDraft.weight
              ? weightStatus?.message || "当前品种还没有内置参考区间。"
              : `${profileDraft.species} 的常见体重参考区间：${rangeText(profileDraft.species)}`}
          </div>

          <label>
            备注
            <textarea
              rows="4"
              value={recordDraft.notes}
              onChange={(event) => setRecordDraft((current) => ({ ...current, notes: event.target.value }))}
              placeholder="比如：换粮、洗澡、掉毛、看医生、叫声变少"
            />
          </label>

          <div className="photo-picker">
            <div className="photo-preview record">
              {recordDraft.photo ? <img src={recordDraft.photo} alt="健康记录照片" /> : <span>+</span>}
            </div>
            <div className="photo-actions">
              <button type="button" className="ghost-button" onClick={() => recordPhotoRef.current?.click()}>
                {uploadingTarget === "record" ? "正在处理..." : "上传记录照片"}
              </button>
              <input ref={recordPhotoRef} type="file" accept="image/*" hidden onChange={handleRecordPhotoChange} />
              <span>大图会自动压缩，方便手机端保存。</span>
            </div>
          </div>

          <div className="action-row">
            <button type="button" className="primary-button" onClick={saveRecordDraft}>
              {isEditingRecord ? "保存修改" : "保存今天的记录"}
            </button>
            <button type="button" className="ghost-button" onClick={() => setCurrentTab("home")}>
              返回首页
            </button>
          </div>
        </div>
      </AppSection>

      {selectedRecord ? (
        <AppSection kicker="Record" title="记录详情">
          <article className="record-card detail-card">
            <div className="record-top">
              <div>
                <strong>{formatDate(selectedRecord.date)}</strong>
                <span>{selectedRecord.weight} g</span>
              </div>
              <span
                className={`pill ${
                  evaluateWeight(activeParrot.species, selectedRecord.weight)?.tone === "alert"
                    ? "pill-alert"
                    : "pill-good"
                }`}
              >
                {evaluateWeight(activeParrot.species, selectedRecord.weight)?.short || "已记录"}
              </span>
            </div>
            <div className="tag-row">
              <span className="tag">食欲：{selectedRecord.appetite}</span>
              <span className="tag">精神：{selectedRecord.mood}</span>
              <span className="tag">排便：{selectedRecord.droppings}</span>
            </div>
            {selectedRecord.photo ? (
              <img className="record-image" src={selectedRecord.photo} alt={`${activeParrot.name} 的记录照片`} />
            ) : null}
            <p className="record-notes">{selectedRecord.notes || "今天没有额外备注。"}</p>
            <div className="action-row">
              <button type="button" className="ghost-button" onClick={() => editRecord(selectedRecord)}>
                编辑这条
              </button>
              <button type="button" className="danger-button" onClick={() => deleteRecord(selectedRecord.id)}>
                删除这条
              </button>
            </div>
          </article>
        </AppSection>
      ) : null}

      <AppSection kicker="History" title="最近记录">
        <div className="record-list">
          {activeRecords.length ? (
            activeRecords.map((record) => {
              const status = evaluateWeight(activeParrot.species, record.weight);
              return (
                <article key={record.id} className={`record-card ${selectedRecordId === record.id ? "is-selected" : ""}`}>
                  <div className="record-top">
                    <div>
                      <strong>{formatDate(record.date)}</strong>
                      <span>{record.weight} g</span>
                    </div>
                    <span className={`pill ${status?.tone === "alert" ? "pill-alert" : "pill-good"}`}>
                      {status?.short || "已记录"}
                    </span>
                  </div>
                  {record.notes ? <p className="record-snippet">{record.notes}</p> : null}
                  <div className="tag-row">
                    <span className="tag">食欲：{record.appetite}</span>
                    <span className="tag">精神：{record.mood}</span>
                    <span className="tag">排便：{record.droppings}</span>
                  </div>
                  <div className="action-row">
                    <button type="button" className="ghost-button" onClick={() => setSelectedRecordId(record.id)}>
                      查看详情
                    </button>
                    <button type="button" className="ghost-button" onClick={() => editRecord(record)}>
                      编辑
                    </button>
                    <button type="button" className="danger-button" onClick={() => deleteRecord(record.id)}>
                      删除
                    </button>
                  </div>
                </article>
              );
            })
          ) : (
            <div className="empty-state">还没有记录，先为 {activeParrot?.name || "这只鹦鹉"} 添加第一条健康日志。</div>
          )}
        </div>
      </AppSection>
    </>
  );

  const trendView = (
    <>
      <AppSection kicker="Trend" title="体重趋势折线图">
        <WeightTrendChart records={activeRecords} />
      </AppSection>
      <AppSection kicker="Alerts" title="异常提醒">
        <div className="alert-list">
          {alerts.map((alert, index) => (
            <article key={`${alert.title}-${index}`} className={`alert-card tone-${alert.tone}`}>
              <strong>{alert.title}</strong>
              <p>{alert.body}</p>
            </article>
          ))}
        </div>
      </AppSection>
    </>
  );

  const profileView = (
    <>
      <AppSection kicker="Profile" title="当前鹦鹉档案">
        <div className="form-stack">
          <div className="photo-picker">
            <div className="photo-preview large">
              {profileDraft.photo ? (
                <img src={profileDraft.photo} alt={profileDraft.name || "鹦鹉头像"} />
              ) : (
                <span>{profileDraft.name ? profileDraft.name.slice(0, 1) : "?"}</span>
              )}
            </div>
            <div className="photo-actions">
              <button type="button" className="ghost-button" onClick={() => profilePhotoRef.current?.click()}>
                {uploadingTarget === "profile" ? "正在处理..." : "上传头像"}
              </button>
              <input ref={profilePhotoRef} type="file" accept="image/*" hidden onChange={handleProfilePhotoChange} />
              <span>建议用 JPG 或 PNG，系统会自动压缩大图。</span>
            </div>
          </div>

          <div className="field-grid">
            <label>
              名字
              <input
                value={profileDraft.name}
                onChange={(event) => setProfileDraft((current) => ({ ...current, name: event.target.value }))}
                placeholder="比如 Kiwi"
              />
            </label>
            <label>
              品种
              <select
                value={profileDraft.species}
                onChange={(event) => setProfileDraft((current) => ({ ...current, species: event.target.value }))}
              >
                {Object.keys(SPECIES_RANGES).map((species) => (
                  <option key={species} value={species}>
                    {species}
                  </option>
                ))}
              </select>
            </label>
            <label>
              生日
              <input
                type="date"
                value={profileDraft.birthday}
                onChange={(event) => setProfileDraft((current) => ({ ...current, birthday: event.target.value }))}
              />
            </label>
            <label>
              性别
              <select
                value={profileDraft.sex}
                onChange={(event) => setProfileDraft((current) => ({ ...current, sex: event.target.value }))}
              >
                <option value="">未填写</option>
                <option value="公">公</option>
                <option value="母">母</option>
                <option value="未知">未知</option>
              </select>
            </label>
          </div>

          <div className="inline-note">
            <strong>{profileDraft.species}</strong> 的常见体重参考区间是{" "}
            <strong>{rangeText(profileDraft.species)}</strong>，这里作为日常记录参考，不替代诊疗判断。
          </div>

          <div className="action-row">
            <button type="button" className="primary-button" onClick={saveProfileDraft}>
              保存当前鹦鹉档案
            </button>
            <button type="button" className="ghost-button" onClick={() => setCurrentTab("home")}>
              返回首页
            </button>
          </div>
        </div>
      </AppSection>

      <AppSection kicker="Backup" title="导出与备份">
        <div className="backup-actions">
          <button type="button" className="primary-button" onClick={() => exportStateAsJson(state)}>
            导出 JSON
          </button>
          <button type="button" className="ghost-button" onClick={() => exportStateAsCsv(state)}>
            导出 CSV
          </button>
        </div>
        <p className="support-text">JSON 适合完整备份，CSV 适合拿去表格里继续整理。</p>
      </AppSection>
    </>
  );

  const tabViews = {
    home: homeView,
    log: logView,
    trend: trendView,
    profile: profileView,
  };

  return (
    <MobileShell>
      <div className="app-screen">
        {saveMessage ? (
          <section className={`toast-card tone-${saveTone}`}>
            <strong>{saveTone === "good" ? "已完成" : saveTone === "soft" ? "处理中" : "出了点问题"}</strong>
            <p>{saveMessage}</p>
          </section>
        ) : null}

        <div className="view-stack">{tabViews[currentTab]}</div>
        <nav className="bottom-nav">
          {navItems.map((item) => (
            <button
              key={item.id}
              type="button"
              className={`nav-item ${currentTab === item.id ? "is-active" : ""}`}
              onClick={() => setCurrentTab(item.id)}
            >
              <span>{item.icon}</span>
              <small>{item.label}</small>
            </button>
          ))}
        </nav>
      </div>
    </MobileShell>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
