const { useState, useEffect, useRef } = React;

const PAPER = "#EFE9DC";
const PAPER_CARD = "#F8F4EA";
const INK = "#24304A";
const INK_SOFT = "#63697A";
const CREDIT = "#2F5D4E";
const DEBIT = "#A13D2E";
const GOLD = "#B08D3F";
const LINE = "#D8CFBC";

const FALLBACK_CATEGORIES = ["עסק פרטי", "קמפ", 'בית חב"ד'];

const todayStr = () => new Date().toISOString().split("T")[0];

function formatILS(n) {
  const num = Number(n) || 0;
  return `${num.toLocaleString("he-IL", { maximumFractionDigits: 2 })} ₪`;
}

function formatDateDisplay(dateVal) {
  if (!dateVal) return "";
  const d = new Date(dateVal);
  return d.toLocaleDateString("he-IL", { day: "2-digit", month: "2-digit", year: "numeric" });
}

function safeFileName(str) {
  return (str || "תמונה").replace(/[^א-תa-zA-Z0-9 ]/g, "").trim() || "תמונה";
}

function downloadUrl(url, filename) {
  const a = document.createElement("a");
  a.href = url;
  a.download = filename;
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
}

function resizeImageToBlob(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = (e) => {
      const img = new Image();
      img.onload = () => {
        const maxDim = 1200;
        let width = img.width;
        let height = img.height;
        if (width > maxDim || height > maxDim) {
          if (width > height) {
            height = Math.round((height * maxDim) / width);
            width = maxDim;
          } else {
            width = Math.round((width * maxDim) / height);
            height = maxDim;
          }
        }
        const canvas = document.createElement("canvas");
        canvas.width = width;
        canvas.height = height;
        const ctx = canvas.getContext("2d");
        ctx.drawImage(img, 0, 0, width, height);
        canvas.toBlob(
          (blob) => {
            if (blob) resolve(blob);
            else reject(new Error("שגיאה בעיבוד תמונה"));
          },
          "image/jpeg",
          0.8
        );
      };
      img.onerror = () => reject(new Error("שגיאת טעינת תמונה"));
      img.src = e.target.result;
    };
    reader.onerror = () => reject(new Error("שגיאת קריאת קובץ"));
    reader.readAsDataURL(file);
  });
}

function emptyForm() {
  return {
    date: todayStr(),
    type: "expense",
    category: "",
    description: "",
    source: "",
    amount: "",
    needsReimbursement: false,
    hasWarranty: false,
    warrantyMonths: "",
    photoFile: null,
    photoPreviewUrl: null,
    hadExistingPhoto: false,
    removeExistingPhoto: false,
  };
}

function GlobalStyle() {
  return (
    <style>{`
      @import url('https://fonts.googleapis.com/css2?family=Frank+Ruhl+Libre:wght@500;700&family=Assistant:wght@400;500;600;700&display=swap');
      .font-display { font-family: 'Frank Ruhl Libre', 'Times New Roman', serif; }
      .font-body { font-family: 'Assistant', -apple-system, sans-serif; }
      .tabular-amt { font-variant-numeric: tabular-nums; }
      input:focus, select:focus, textarea:focus {
        outline: 2px solid #B08D3F;
        outline-offset: 1px;
      }
      button:focus-visible {
        outline: 2px solid #B08D3F;
        outline-offset: 2px;
      }
      @media (prefers-reduced-motion: reduce) {
        * { transition: none !important; animation: none !important; }
      }
    `}</style>
  );
}

function Icon({ children, size, style }) {
  return (
    <svg
      width={size || 18}
      height={size || 18}
      viewBox="0 0 24 24"
      fill="none"
      stroke="currentColor"
      strokeWidth="2"
      strokeLinecap="round"
      strokeLinejoin="round"
      style={style}
    >
      {children}
    </svg>
  );
}
const IconPlus = (p) => (
  <Icon {...p}>
    <line x1="12" y1="5" x2="12" y2="19" />
    <line x1="5" y1="12" x2="19" y2="12" />
  </Icon>
);
const IconList = (p) => (
  <Icon {...p}>
    <line x1="8" y1="6" x2="21" y2="6" />
    <line x1="8" y1="12" x2="21" y2="12" />
    <line x1="8" y1="18" x2="21" y2="18" />
    <line x1="3" y1="6" x2="3.01" y2="6" />
    <line x1="3" y1="12" x2="3.01" y2="12" />
    <line x1="3" y1="18" x2="3.01" y2="18" />
  </Icon>
);
const IconShield = (p) => (
  <Icon {...p}>
    <path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" />
    <polyline points="9 12 11 14 15 10" />
  </Icon>
);
const IconCamera = (p) => (
  <Icon {...p}>
    <path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z" />
    <circle cx="12" cy="13" r="4" />
  </Icon>
);
const IconTrash = (p) => (
  <Icon {...p}>
    <polyline points="3 6 5 6 21 6" />
    <path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6" />
    <path d="M10 11v6" />
    <path d="M14 11v6" />
    <path d="M9 6V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2" />
  </Icon>
);
const IconX = (p) => (
  <Icon {...p}>
    <line x1="18" y1="6" x2="6" y2="18" />
    <line x1="6" y1="6" x2="18" y2="18" />
  </Icon>
);
const IconCheck = (p) => (
  <Icon {...p}>
    <polyline points="20 6 9 17 4 12" />
  </Icon>
);
const IconImageOff = (p) => (
  <Icon {...p}>
    <line x1="2" y1="2" x2="22" y2="22" />
    <path d="M10.41 5H21a1 1 0 0 1 1 1v10.59" />
    <path d="M3.59 3.59A1 1 0 0 0 3 4.41V19a1 1 0 0 0 1 1h14.59" />
    <circle cx="8.5" cy="8.5" r="1.5" />
    <path d="M21 15l-5-5-4 4" />
  </Icon>
);
const IconDownload = (p) => (
  <Icon {...p}>
    <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
    <polyline points="7 10 12 15 17 10" />
    <line x1="12" y1="15" x2="12" y2="3" />
  </Icon>
);
const IconWallet = (p) => (
  <Icon {...p}>
    <path d="M21 12V7H5a2 2 0 0 1 0-4h14v4" />
    <path d="M3 5v14a2 2 0 0 0 2 2h16v-5" />
    <path d="M18 12a2 2 0 0 0 0 4h4v-4z" />
  </Icon>
);
const IconLogOut = (p) => (
  <Icon {...p}>
    <path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4" />
    <polyline points="16 17 21 12 16 7" />
    <line x1="21" y1="12" x2="9" y2="12" />
  </Icon>
);

function PhotoThumb({ photo, size, onDownload, placeholderIcon: PlaceholderIcon, placeholderColor }) {
  const dim = size === "sm" ? "w-12 h-12" : "w-14 h-14";
  const iconSize = size === "sm" ? 16 : 20;
  if (!photo) {
    if (PlaceholderIcon) {
      return (
        <div
          className={`${dim} rounded-full flex items-center justify-center flex-shrink-0`}
          style={{ border: `2px solid ${placeholderColor || INK_SOFT}` }}
        >
          <PlaceholderIcon size={iconSize} style={{ color: placeholderColor || INK_SOFT }} />
        </div>
      );
    }
    return (
      <div className={`${dim} rounded-md flex-shrink-0 flex items-center justify-center`} style={{ background: PAPER }}>
        <IconImageOff size={iconSize} style={{ color: INK_SOFT }} />
      </div>
    );
  }
  return (
    <button onClick={onDownload} className="relative flex-shrink-0">
      <img src={photo} alt="" className={`${dim} rounded-md object-cover`} style={{ border: `1px solid ${LINE}` }} />
      <span className="absolute -bottom-1 -left-1 rounded-full p-0.5" style={{ background: INK, color: "#fff" }}>
        <IconDownload size={9} />
      </span>
    </button>
  );
}

function EntryCard({ entry, onEdit, onToggleReimburse, onDelete, onDownloadImage, confirming, onArmDelete, onCancelDelete }) {
  const isIncome = entry.type === "income";
  const color = isIncome ? CREDIT : DEBIT;
  return (
    <div className="flex items-start gap-3 px-3 py-3" style={{ borderBottom: `1px solid ${LINE}` }}>
      <PhotoThumb photo={entry.photo} size="sm" onDownload={() => onDownloadImage(entry)} />
      <button onClick={onEdit} className="flex-1 text-right min-w-0">
        <div className="flex items-center justify-between gap-2">
          <span className="text-sm font-semibold truncate">{entry.description}</span>
          <span className="tabular-amt font-bold text-sm whitespace-nowrap" style={{ color }}>
            {isIncome ? "+" : "-"}
            {formatILS(entry.amount)}
          </span>
        </div>
        <div className="flex items-center gap-2 mt-1 flex-wrap">
          <span className="text-xs" style={{ color: INK_SOFT }}>{formatDateDisplay(entry.date)}</span>
          <span className="text-xs px-1.5 py-0.5 rounded-full" style={{ background: `${GOLD}22`, color: INK }}>
            {entry.category}
          </span>
          {entry.source ? <span className="text-xs" style={{ color: INK_SOFT }}>{entry.source}</span> : null}
          {entry.hasWarranty ? <IconShield size={12} style={{ color: GOLD }} /> : null}
        </div>
      </button>
      <div className="flex flex-col items-center gap-1.5 flex-shrink-0">
        {entry.needsReimbursement ? (
          <button
            onClick={onToggleReimburse}
            className="text-xs px-2 py-1 rounded-full font-medium whitespace-nowrap"
            style={{
              background: entry.reimbursementDone ? `${CREDIT}22` : `${GOLD}22`,
              color: entry.reimbursementDone ? CREDIT : GOLD,
            }}
          >
            {entry.reimbursementDone ? "הוחזר" : "החזר?"}
          </button>
        ) : null}
        {confirming ? (
          <div className="flex gap-1">
            <button onClick={onDelete} className="p-1 rounded" style={{ background: DEBIT, color: "#fff" }}>
              <IconCheck size={12} />
            </button>
            <button onClick={onCancelDelete} className="p-1 rounded" style={{ border: `1px solid ${LINE}` }}>
              <IconX size={12} />
            </button>
          </div>
        ) : (
          <button onClick={onArmDelete} className="p-1" style={{ color: INK_SOFT }}>
            <IconTrash size={14} />
          </button>
        )}
      </div>
    </div>
  );
}

function WarrantyCard({ item, onDownloadImage }) {
  const expired = item.days < 0;
  const soon = !expired && item.days <= 30;
  const statusColor = expired ? DEBIT : soon ? GOLD : CREDIT;
  const statusText = expired ? "פג תוקף" : `נותרו ${item.days} ימים`;
  return (
    <div className="flex items-center gap-3 rounded-lg p-3" style={{ background: PAPER, border: `1px solid ${LINE}` }}>
      <PhotoThumb
        photo={item.photo}
        size="lg"
        onDownload={() => onDownloadImage(item)}
        placeholderIcon={IconShield}
        placeholderColor={statusColor}
      />
      <div className="flex-1 min-w-0">
        <div className="text-sm font-semibold truncate">{item.description}</div>
        <div className="text-xs mt-0.5" style={{ color: INK_SOFT }}>
          {item.category} • נרכש {formatDateDisplay(item.date)}
        </div>
        <div className="text-xs mt-0.5" style={{ color: INK_SOFT }}>
          בתוקף עד {formatDateDisplay(item.expiry)}
        </div>
      </div>
      <div
        className="text-xs font-bold px-2 py-1 rounded-full whitespace-nowrap flex-shrink-0"
        style={{ background: `${statusColor}22`, color: statusColor }}
      >
        {statusText}
      </div>
    </div>
  );
}

function ReimbursementCard({ entry, onToggle, onDownloadImage }) {
  const done = entry.reimbursementDone;
  const statusColor = done ? CREDIT : GOLD;
  return (
    <div className="flex items-center gap-3 rounded-lg p-3" style={{ background: PAPER, border: `1px solid ${LINE}` }}>
      <PhotoThumb
        photo={entry.photo}
        size="lg"
        onDownload={() => onDownloadImage(entry)}
        placeholderIcon={IconWallet}
        placeholderColor={statusColor}
      />
      <div className="flex-1 min-w-0">
        <div className="text-sm font-semibold truncate">{entry.description}</div>
        <div className="text-xs mt-0.5" style={{ color: INK_SOFT }}>
          {entry.category} • {formatDateDisplay(entry.date)}
        </div>
        <div className="tabular-amt text-sm font-bold mt-0.5" style={{ color: entry.type === "income" ? CREDIT : DEBIT }}>
          {formatILS(entry.amount)}
        </div>
      </div>
      <button
        onClick={onToggle}
        className="text-xs font-bold px-2.5 py-1.5 rounded-full whitespace-nowrap flex-shrink-0"
        style={{ background: `${statusColor}22`, color: statusColor }}
      >
        {done ? "הוחזר" : "ממתין"}
      </button>
    </div>
  );
}

function LoadingScreen() {
  return (
    <div style={{ background: PAPER }} className="min-h-screen flex items-center justify-center font-body" dir="rtl">
      <GlobalStyle />
      <div style={{ color: INK }} className="text-sm font-medium">
        טוען...
      </div>
    </div>
  );
}

function LoginScreen({ needsSetup, onSuccess }) {
  const [password, setPassword] = useState("");
  const [confirmPassword, setConfirmPassword] = useState("");
  const [error, setError] = useState("");
  const [loading, setLoading] = useState(false);

  async function handleSubmit(e) {
    e.preventDefault();
    setError("");
    if (needsSetup && password !== confirmPassword) {
      setError("הסיסמאות אינן תואמות");
      return;
    }
    setLoading(true);
    try {
      const url = needsSetup ? "api/setup.php" : "api/login.php";
      const res = await fetch(url, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ password }),
      });
      const data = await res.json();
      if (res.ok && data.success) {
        onSuccess();
      } else {
        setError((data && data.error) || "שגיאה, נסה שוב");
      }
    } catch (err) {
      setError("שגיאת תקשורת עם השרת");
    }
    setLoading(false);
  }

  return (
    <div style={{ background: PAPER, minHeight: "100vh" }} dir="rtl" className="font-body flex items-center justify-center px-5">
      <GlobalStyle />
      <form
        onSubmit={handleSubmit}
        className="w-full rounded-xl p-6"
        style={{ background: PAPER_CARD, border: `1px solid ${LINE}`, maxWidth: "24rem" }}
      >
        <h1 className="font-display text-3xl font-bold text-center mb-1" style={{ color: INK }}>
          פנקס
        </h1>
        <p className="text-sm text-center mb-6" style={{ color: INK_SOFT }}>
          {needsSetup ? "קביעת סיסמת כניסה למערכת" : "כניסה למערכת"}
        </p>
        <input
          type="password"
          value={password}
          onChange={(e) => setPassword(e.target.value)}
          placeholder="סיסמה"
          autoFocus
          className="w-full rounded-lg px-3 py-2.5 text-sm mb-3"
          style={{ background: PAPER, border: `1px solid ${LINE}`, color: INK }}
        />
        {needsSetup ? (
          <input
            type="password"
            value={confirmPassword}
            onChange={(e) => setConfirmPassword(e.target.value)}
            placeholder="אימות סיסמה"
            className="w-full rounded-lg px-3 py-2.5 text-sm mb-3"
            style={{ background: PAPER, border: `1px solid ${LINE}`, color: INK }}
          />
        ) : null}
        {error ? (
          <div className="text-sm font-medium mb-3" style={{ color: DEBIT }}>
            {error}
          </div>
        ) : null}
        <button
          type="submit"
          disabled={loading}
          className="w-full py-3 rounded-lg font-bold text-base"
          style={{ background: INK, color: PAPER_CARD, opacity: loading ? 0.7 : 1 }}
        >
          {loading ? "רגע..." : needsSetup ? "קביעת סיסמה" : "כניסה"}
        </button>
      </form>
    </div>
  );
}

function App() {
  const [authState, setAuthState] = useState("loading");
  const [entries, setEntries] = useState([]);
  const [categories, setCategories] = useState(FALLBACK_CATEGORIES);
  const [tab, setTab] = useState("add");
  const [form, setForm] = useState(emptyForm());
  const [editingId, setEditingId] = useState(null);
  const [showNewCat, setShowNewCat] = useState(false);
  const [newCatValue, setNewCatValue] = useState("");
  const [confirmDeleteId, setConfirmDeleteId] = useState(null);
  const [savedFlash, setSavedFlash] = useState(false);
  const [formError, setFormError] = useState("");
  const [submitting, setSubmitting] = useState(false);
  const [filters, setFilters] = useState({ type: "all", category: "all", from: "", to: "" });
  const [reimbFilter, setReimbFilter] = useState("all");
  const fileInputRef = useRef(null);

  useEffect(() => {
    checkSession();
  }, []);

  async function checkSession() {
    try {
      const res = await fetch("api/session.php");
      const data = await res.json();
      if (data.needsSetup) {
        setAuthState("needs-setup");
      } else if (!data.authenticated) {
        setAuthState("needs-login");
      } else {
        await loadAllData();
        setAuthState("ready");
      }
    } catch (err) {
      setAuthState("needs-login");
    }
  }

  async function loadAllData() {
    try {
      const [entriesRes, catsRes] = await Promise.all([fetch("api/entries.php"), fetch("api/categories.php")]);
      const entriesData = await entriesRes.json();
      const catsData = await catsRes.json();
      setEntries(Array.isArray(entriesData) ? entriesData : []);
      setCategories(catsData && catsData.length ? catsData : FALLBACK_CATEGORIES);
    } catch (err) {
      console.error("שגיאה בטעינת נתונים", err);
    }
  }

  async function handleLoginSuccess() {
    await loadAllData();
    setAuthState("ready");
  }

  async function handleLogout() {
    try {
      await fetch("api/logout.php", { method: "POST" });
    } catch (err) {
      // ignore
    }
    setEntries([]);
    setAuthState("needs-login");
  }

  function resetForm() {
    setForm(emptyForm());
    setEditingId(null);
    setShowNewCat(false);
    setNewCatValue("");
    setFormError("");
  }

  function startEdit(entry) {
    setForm({
      date: entry.date,
      type: entry.type,
      category: entry.category,
      description: entry.description,
      source: entry.source || "",
      amount: String(entry.amount),
      needsReimbursement: entry.needsReimbursement,
      hasWarranty: entry.hasWarranty,
      warrantyMonths: entry.warrantyMonths != null ? String(entry.warrantyMonths) : "",
      photoFile: null,
      photoPreviewUrl: entry.photo || null,
      hadExistingPhoto: !!entry.photo,
      removeExistingPhoto: false,
    });
    setEditingId(entry.id);
    setTab("add");
    setFormError("");
  }

  async function handleSubmit() {
    if (!form.category) {
      setFormError("צריך לבחור קטגוריה");
      return;
    }
    if (!form.description.trim()) {
      setFormError("צריך לתאר במה מדובר");
      return;
    }
    if (!form.amount || Number(form.amount) <= 0) {
      setFormError("צריך להזין סכום תקין");
      return;
    }
    setFormError("");
    setSubmitting(true);

    const fd = new FormData();
    fd.append("date", form.date);
    fd.append("type", form.type);
    fd.append("category", form.category);
    fd.append("description", form.description);
    fd.append("source", form.source || "");
    fd.append("amount", form.amount);
    fd.append("needsReimbursement", form.needsReimbursement ? "true" : "false");
    fd.append("hasWarranty", form.hasWarranty ? "true" : "false");
    if (form.hasWarranty) {
      fd.append("warrantyMonths", form.warrantyMonths || "0");
    }
    if (form.photoFile) {
      fd.append("photo", form.photoFile, "upload.jpg");
    }
    if (form.removeExistingPhoto) {
      fd.append("removePhoto", "true");
    }

    const url = editingId ? `api/entries.php?id=${editingId}` : "api/entries.php";
    try {
      const res = await fetch(url, { method: "POST", body: fd });
      const data = await res.json();
      if (!res.ok || !data.success) {
        setFormError((data && data.error) || "שגיאה בשמירה");
        setSubmitting(false);
        return;
      }
      await loadAllData();
      const wasEditing = !!editingId;
      resetForm();
      if (wasEditing) {
        setTab("list");
      } else {
        setSavedFlash(true);
        setTimeout(() => setSavedFlash(false), 1800);
      }
    } catch (err) {
      setFormError("שגיאת תקשורת עם השרת");
    }
    setSubmitting(false);
  }

  async function addCategory() {
    const v = newCatValue.trim();
    if (!v) return;
    try {
      await fetch("api/categories.php", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ name: v }),
      });
      const catsRes = await fetch("api/categories.php");
      setCategories(await catsRes.json());
    } catch (err) {
      console.error("שגיאה בהוספת קטגוריה", err);
    }
    setForm((f) => ({ ...f, category: v }));
    setNewCatValue("");
    setShowNewCat(false);
  }

  async function toggleReimbursed(id) {
    setEntries((prev) => prev.map((e) => (e.id === id ? { ...e, reimbursementDone: !e.reimbursementDone } : e)));
    try {
      await fetch(`api/entries.php?action=toggle-reimbursement&id=${id}`, { method: "POST" });
    } catch (err) {
      console.error("שגיאה בעדכון סטטוס החזר", err);
      await loadAllData();
    }
  }

  async function deleteEntry(id) {
    setConfirmDeleteId(null);
    setEntries((prev) => prev.filter((e) => e.id !== id));
    try {
      await fetch(`api/entries.php?id=${id}`, { method: "DELETE" });
    } catch (err) {
      console.error("שגיאה במחיקה", err);
      await loadAllData();
    }
  }

  async function handlePhotoChange(e) {
    const file = e.target.files && e.target.files[0];
    if (!file) return;
    try {
      const blob = await resizeImageToBlob(file);
      const previewUrl = URL.createObjectURL(blob);
      setForm((f) => ({ ...f, photoFile: blob, photoPreviewUrl: previewUrl, removeExistingPhoto: false }));
    } catch (err) {
      console.error("שגיאה בטעינת תמונה", err);
    }
    e.target.value = "";
  }

  function handleRemovePhoto() {
    setForm((f) => {
      if (f.photoFile && f.photoPreviewUrl) {
        URL.revokeObjectURL(f.photoPreviewUrl);
      }
      return { ...f, photoFile: null, photoPreviewUrl: null, removeExistingPhoto: f.hadExistingPhoto };
    });
  }

  function downloadEntryImage(entry) {
    if (!entry.photo) return;
    downloadUrl(entry.photo, `${safeFileName(entry.description)}-${entry.date}.jpg`);
  }

  const filteredEntries = entries
    .filter((e) => {
      if (filters.type !== "all" && e.type !== filters.type) return false;
      if (filters.category !== "all" && e.category !== filters.category) return false;
      if (filters.from && e.date < filters.from) return false;
      if (filters.to && e.date > filters.to) return false;
      return true;
    })
    .sort((a, b) => (a.date < b.date ? 1 : a.date > b.date ? -1 : b.createdAt - a.createdAt));

  const totalIncome = filteredEntries.filter((e) => e.type === "income").reduce((s, e) => s + e.amount, 0);
  const totalExpense = filteredEntries.filter((e) => e.type === "expense").reduce((s, e) => s + e.amount, 0);
  const net = totalIncome - totalExpense;

  function exportToExcel() {
    if (filteredEntries.length === 0) return;
    const rows = filteredEntries.map((e) => ({
      "תאריך": formatDateDisplay(e.date),
      "סוג": e.type === "income" ? "הכנסה" : "הוצאה",
      "קטגוריה": e.category,
      "תיאור": e.description,
      "מקור": e.source || "",
      "סכום": e.amount,
      "דרוש החזר": e.needsReimbursement ? "כן" : "לא",
      "בוצע החזר": e.needsReimbursement ? (e.reimbursementDone ? "כן" : "לא") : "",
      "יש אחריות": e.hasWarranty ? "כן" : "לא",
      "תקופת אחריות בחודשים": e.hasWarranty ? e.warrantyMonths : "",
    }));
    const ws = XLSX.utils.json_to_sheet(rows);
    const wb = XLSX.utils.book_new();
    XLSX.utils.book_append_sheet(wb, ws, "רשומות");
    XLSX.writeFile(wb, `פנקס-${todayStr()}.xlsx`);
  }

  const overallIncome = entries.filter((e) => e.type === "income").reduce((s, e) => s + e.amount, 0);
  const overallExpense = entries.filter((e) => e.type === "expense").reduce((s, e) => s + e.amount, 0);
  const overallNet = overallIncome - overallExpense;

  const warrantyItems = entries
    .filter((e) => e.hasWarranty)
    .map((e) => {
      const purchase = new Date(e.date);
      const expiry = new Date(purchase);
      expiry.setMonth(expiry.getMonth() + (e.warrantyMonths || 0));
      const days = Math.ceil((expiry - new Date()) / 86400000);
      return { ...e, expiry, days };
    })
    .sort((a, b) => a.days - b.days);

  const allReimbursable = entries.filter((e) => e.needsReimbursement);
  const reimbursementItems = allReimbursable
    .filter((e) => {
      if (reimbFilter === "pending") return !e.reimbursementDone;
      if (reimbFilter === "done") return e.reimbursementDone;
      return true;
    })
    .sort((a, b) => {
      if (a.reimbursementDone !== b.reimbursementDone) return a.reimbursementDone ? 1 : -1;
      return a.date < b.date ? -1 : a.date > b.date ? 1 : 0;
    });
  const pendingReimbTotal = allReimbursable.filter((e) => !e.reimbursementDone).reduce((s, e) => s + e.amount, 0);
  const doneReimbTotal = allReimbursable.filter((e) => e.reimbursementDone).reduce((s, e) => s + e.amount, 0);

  const filtersActive = filters.type !== "all" || filters.category !== "all" || filters.from || filters.to;
  const hasAnyPhoto = entries.some((e) => e.photo);

  if (authState === "loading") {
    return <LoadingScreen />;
  }
  if (authState === "needs-setup" || authState === "needs-login") {
    return <LoginScreen needsSetup={authState === "needs-setup"} onSuccess={handleLoginSuccess} />;
  }

  return (
    <div style={{ background: PAPER, minHeight: "100vh" }} dir="rtl">
      <GlobalStyle />
      <div className="font-body max-w-md mx-auto" style={{ color: INK }}>
        <header className="px-5 pt-7 pb-4" style={{ borderBottom: `3px double ${LINE}` }}>
          <div className="flex items-center justify-between gap-3">
            <div>
              <h1 className="font-display text-3xl font-bold leading-tight">פנקס</h1>
              <p className="text-sm mt-0.5" style={{ color: INK_SOFT }}>מעקב הכנסות והוצאות</p>
            </div>
            <div className="flex items-center gap-3">
              <div className="text-left">
                <div className="text-xs" style={{ color: INK_SOFT }}>יתרה כוללת</div>
                <div className="tabular-amt font-bold text-lg" style={{ color: overallNet >= 0 ? CREDIT : DEBIT }}>
                  {formatILS(overallNet)}
                </div>
              </div>
              <button onClick={handleLogout} className="p-1.5" style={{ color: INK_SOFT }} title="יציאה">
                <IconLogOut size={18} />
              </button>
            </div>
          </div>
        </header>

        <nav className="flex px-3 pt-3 gap-1">
          {[
            { id: "add", label: "הוספה", icon: IconPlus },
            { id: "list", label: "רשימה", icon: IconList },
            { id: "reimb", label: "החזרים", icon: IconWallet },
            { id: "warranty", label: "אחריות", icon: IconShield },
          ].map(({ id, label, icon: TabIcon }) => {
            const active = tab === id;
            return (
              <button
                key={id}
                onClick={() => setTab(id)}
                className="flex-1 flex flex-col items-center justify-center gap-0.5 py-2 text-xs font-semibold rounded-t-lg transition-colors"
                style={{
                  background: active ? PAPER_CARD : "transparent",
                  color: active ? INK : INK_SOFT,
                  borderTop: active ? `2px solid ${GOLD}` : "2px solid transparent",
                  borderLeft: active ? `1px solid ${LINE}` : "1px solid transparent",
                  borderRight: active ? `1px solid ${LINE}` : "1px solid transparent",
                }}
              >
                <TabIcon size={15} />
                {label}
              </button>
            );
          })}
        </nav>

        <main className="rounded-t-xl" style={{ background: PAPER_CARD, minHeight: "55vh" }}>
          {tab === "add" && (
            <div className="p-5 space-y-5">
              {editingId ? (
                <div className="flex items-center justify-between rounded-lg px-3 py-2 text-sm" style={{ background: `${GOLD}22` }}>
                  <span className="font-medium">עריכת רשומה קיימת</span>
                  <button onClick={resetForm} className="underline font-medium">
                    ביטול עריכה
                  </button>
                </div>
              ) : null}

              <div className="grid grid-cols-2 gap-2">
                <button
                  onClick={() => setForm((f) => ({ ...f, type: "income" }))}
                  className="py-3 rounded-lg font-semibold text-sm transition-all"
                  style={{
                    background: form.type === "income" ? CREDIT : "transparent",
                    color: form.type === "income" ? "#fff" : CREDIT,
                    border: `1.5px solid ${CREDIT}`,
                  }}
                >
                  הכנסה
                </button>
                <button
                  onClick={() => setForm((f) => ({ ...f, type: "expense" }))}
                  className="py-3 rounded-lg font-semibold text-sm transition-all"
                  style={{
                    background: form.type === "expense" ? DEBIT : "transparent",
                    color: form.type === "expense" ? "#fff" : DEBIT,
                    border: `1.5px solid ${DEBIT}`,
                  }}
                >
                  הוצאה
                </button>
              </div>

              <div>
                <label className="block text-xs font-semibold mb-1" style={{ color: INK_SOFT }}>
                  תאריך
                </label>
                <input
                  type="date"
                  value={form.date}
                  onChange={(e) => setForm((f) => ({ ...f, date: e.target.value }))}
                  className="w-full rounded-lg px-3 py-2.5 text-sm"
                  style={{ background: PAPER, border: `1px solid ${LINE}`, color: INK }}
                />
              </div>

              <div>
                <label className="block text-xs font-semibold mb-1" style={{ color: INK_SOFT }}>
                  קטגוריה
                </label>
                {!showNewCat ? (
                  <div className="flex flex-wrap gap-2">
                    {categories.map((c) => (
                      <button
                        key={c}
                        onClick={() => setForm((f) => ({ ...f, category: c }))}
                        className="px-3 py-1.5 rounded-full text-sm font-medium"
                        style={{
                          background: form.category === c ? GOLD : PAPER,
                          color: form.category === c ? "#fff" : INK,
                          border: `1px solid ${form.category === c ? GOLD : LINE}`,
                        }}
                      >
                        {c}
                      </button>
                    ))}
                    <button
                      onClick={() => setShowNewCat(true)}
                      className="px-3 py-1.5 rounded-full text-sm font-medium"
                      style={{ color: INK_SOFT, border: `1px dashed ${INK_SOFT}` }}
                    >
                      + קטגוריה חדשה
                    </button>
                  </div>
                ) : (
                  <div className="flex gap-2">
                    <input
                      autoFocus
                      value={newCatValue}
                      onChange={(e) => setNewCatValue(e.target.value)}
                      placeholder="שם הקטגוריה"
                      className="flex-1 rounded-lg px-3 py-2 text-sm"
                      style={{ background: PAPER, border: `1px solid ${LINE}`, color: INK }}
                      onKeyDown={(e) => {
                        if (e.key === "Enter") addCategory();
                      }}
                    />
                    <button onClick={addCategory} className="px-3 rounded-lg" style={{ background: GOLD, color: "#fff" }}>
                      <IconCheck size={16} />
                    </button>
                    <button
                      onClick={() => {
                        setShowNewCat(false);
                        setNewCatValue("");
                      }}
                      className="px-3 rounded-lg"
                      style={{ border: `1px solid ${LINE}` }}
                    >
                      <IconX size={16} />
                    </button>
                  </div>
                )}
              </div>

              <div>
                <label className="block text-xs font-semibold mb-1" style={{ color: INK_SOFT }}>
                  מהות ההכנסה או ההוצאה
                </label>
                <textarea
                  value={form.description}
                  onChange={(e) => setForm((f) => ({ ...f, description: e.target.value }))}
                  rows={2}
                  placeholder="לדוגמה: קניית ציוד לפעילות קיץ"
                  className="w-full rounded-lg px-3 py-2.5 text-sm resize-none"
                  style={{ background: PAPER, border: `1px solid ${LINE}`, color: INK }}
                />
              </div>

              <div className="grid grid-cols-2 gap-3">
                <div>
                  <label className="block text-xs font-semibold mb-1" style={{ color: INK_SOFT }}>
                    מקור
                  </label>
                  <input
                    value={form.source}
                    onChange={(e) => setForm((f) => ({ ...f, source: e.target.value }))}
                    placeholder="לדוגמה: תרומה"
                    className="w-full rounded-lg px-3 py-2.5 text-sm"
                    style={{ background: PAPER, border: `1px solid ${LINE}`, color: INK }}
                  />
                </div>
                <div>
                  <label className="block text-xs font-semibold mb-1" style={{ color: INK_SOFT }}>
                    סכום (₪)
                  </label>
                  <input
                    type="number"
                    inputMode="decimal"
                    value={form.amount}
                    onChange={(e) => setForm((f) => ({ ...f, amount: e.target.value }))}
                    placeholder="0"
                    className="w-full rounded-lg px-3 py-2.5 text-sm tabular-amt"
                    style={{ background: PAPER, border: `1px solid ${LINE}`, color: INK }}
                  />
                </div>
              </div>

              <div className="space-y-3">
                <label className="flex items-center justify-between rounded-lg px-3 py-2.5" style={{ background: PAPER, border: `1px solid ${LINE}` }}>
                  <span className="text-sm font-medium">דרוש החזר</span>
                  <input
                    type="checkbox"
                    checked={form.needsReimbursement}
                    onChange={(e) => setForm((f) => ({ ...f, needsReimbursement: e.target.checked }))}
                    className="w-5 h-5"
                    style={{ accentColor: GOLD }}
                  />
                </label>

                <label className="flex items-center justify-between rounded-lg px-3 py-2.5" style={{ background: PAPER, border: `1px solid ${LINE}` }}>
                  <span className="text-sm font-medium">יש אחריות על המוצר</span>
                  <input
                    type="checkbox"
                    checked={form.hasWarranty}
                    onChange={(e) => setForm((f) => ({ ...f, hasWarranty: e.target.checked }))}
                    className="w-5 h-5"
                    style={{ accentColor: GOLD }}
                  />
                </label>
                {form.hasWarranty ? (
                  <div>
                    <label className="block text-xs font-semibold mb-1" style={{ color: INK_SOFT }}>
                      תקופת אחריות (בחודשים)
                    </label>
                    <input
                      type="number"
                      inputMode="numeric"
                      value={form.warrantyMonths}
                      onChange={(e) => setForm((f) => ({ ...f, warrantyMonths: e.target.value }))}
                      placeholder="לדוגמה: 12"
                      className="w-full rounded-lg px-3 py-2.5 text-sm"
                      style={{ background: PAPER, border: `1px solid ${LINE}`, color: INK }}
                    />
                  </div>
                ) : null}
              </div>

              <div>
                <label className="block text-xs font-semibold mb-1" style={{ color: INK_SOFT }}>
                  תמונה
                </label>
                {form.photoPreviewUrl ? (
                  <div className="relative inline-block">
                    <img
                      src={form.photoPreviewUrl}
                      alt="תצוגה מקדימה"
                      className="w-28 h-28 object-cover rounded-lg"
                      style={{ border: `1px solid ${LINE}` }}
                    />
                    <button
                      onClick={handleRemovePhoto}
                      className="absolute -top-2 -right-2 rounded-full p-1"
                      style={{ background: DEBIT, color: "#fff" }}
                    >
                      <IconX size={14} />
                    </button>
                  </div>
                ) : (
                  <button
                    onClick={() => fileInputRef.current && fileInputRef.current.click()}
                    className="flex items-center gap-2 px-4 py-3 rounded-lg text-sm font-medium"
                    style={{ border: `1px dashed ${INK_SOFT}`, color: INK_SOFT }}
                  >
                    <IconCamera size={18} />
                    העלאת תמונה
                  </button>
                )}
                <input ref={fileInputRef} type="file" accept="image/*" onChange={handlePhotoChange} className="hidden" />
              </div>

              {formError ? (
                <div className="text-sm font-medium" style={{ color: DEBIT }}>
                  {formError}
                </div>
              ) : null}

              <button
                onClick={handleSubmit}
                disabled={submitting}
                className="w-full py-3.5 rounded-lg font-bold text-base"
                style={{ background: INK, color: PAPER_CARD, opacity: submitting ? 0.7 : 1 }}
              >
                {submitting ? "שומר..." : editingId ? "עדכון רשומה" : "שמירת רשומה"}
              </button>

              {savedFlash ? (
                <div className="text-center text-sm font-semibold" style={{ color: CREDIT }}>
                  נשמר בהצלחה
                </div>
              ) : null}
            </div>
          )}

          {tab === "list" && (
            <div className="p-5 space-y-4">
              <div className="space-y-2">
                <div className="grid grid-cols-2 gap-2">
                  <select
                    value={filters.type}
                    onChange={(e) => setFilters((f) => ({ ...f, type: e.target.value }))}
                    className="rounded-lg px-3 py-2 text-sm"
                    style={{ background: PAPER, border: `1px solid ${LINE}`, color: INK }}
                  >
                    <option value="all">כל הסוגים</option>
                    <option value="income">הכנסות</option>
                    <option value="expense">הוצאות</option>
                  </select>
                  <select
                    value={filters.category}
                    onChange={(e) => setFilters((f) => ({ ...f, category: e.target.value }))}
                    className="rounded-lg px-3 py-2 text-sm"
                    style={{ background: PAPER, border: `1px solid ${LINE}`, color: INK }}
                  >
                    <option value="all">כל הקטגוריות</option>
                    {categories.map((c) => (
                      <option key={c} value={c}>
                        {c}
                      </option>
                    ))}
                  </select>
                </div>
                <div className="grid grid-cols-2 gap-2">
                  <input
                    type="date"
                    value={filters.from}
                    onChange={(e) => setFilters((f) => ({ ...f, from: e.target.value }))}
                    className="rounded-lg px-3 py-2 text-sm"
                    style={{ background: PAPER, border: `1px solid ${LINE}`, color: INK }}
                  />
                  <input
                    type="date"
                    value={filters.to}
                    onChange={(e) => setFilters((f) => ({ ...f, to: e.target.value }))}
                    className="rounded-lg px-3 py-2 text-sm"
                    style={{ background: PAPER, border: `1px solid ${LINE}`, color: INK }}
                  />
                </div>
                {filtersActive ? (
                  <button
                    onClick={() => setFilters({ type: "all", category: "all", from: "", to: "" })}
                    className="text-xs underline"
                    style={{ color: INK_SOFT }}
                  >
                    איפוס סינון
                  </button>
                ) : null}
              </div>

              <div className="grid grid-cols-3 gap-2">
                <div className="rounded-lg p-3 text-center" style={{ background: `${CREDIT}14` }}>
                  <div className="text-xs" style={{ color: INK_SOFT }}>
                    הכנסות
                  </div>
                  <div className="tabular-amt font-bold text-sm mt-0.5" style={{ color: CREDIT }}>
                    {formatILS(totalIncome)}
                  </div>
                </div>
                <div className="rounded-lg p-3 text-center" style={{ background: `${DEBIT}14` }}>
                  <div className="text-xs" style={{ color: INK_SOFT }}>
                    הוצאות
                  </div>
                  <div className="tabular-amt font-bold text-sm mt-0.5" style={{ color: DEBIT }}>
                    {formatILS(totalExpense)}
                  </div>
                </div>
                <div className="rounded-lg p-3 text-center" style={{ background: `${GOLD}18` }}>
                  <div className="text-xs" style={{ color: INK_SOFT }}>
                    מאזן
                  </div>
                  <div className="tabular-amt font-bold text-sm mt-0.5" style={{ color: net >= 0 ? CREDIT : DEBIT }}>
                    {formatILS(net)}
                  </div>
                </div>
              </div>

              <button
                onClick={exportToExcel}
                disabled={filteredEntries.length === 0}
                className="w-full flex items-center justify-center gap-2 py-2.5 rounded-lg text-sm font-semibold transition-colors"
                style={{
                  background: filteredEntries.length === 0 ? PAPER : INK,
                  color: filteredEntries.length === 0 ? INK_SOFT : PAPER_CARD,
                }}
              >
                <IconDownload size={16} />
                הורדה לאקסל ({filteredEntries.length} רשומות)
              </button>

              {hasAnyPhoto ? (
                <a
                  href="api/download-images.php"
                  className="w-full flex items-center justify-center gap-2 py-2.5 rounded-lg text-sm font-semibold"
                  style={{ border: `1px solid ${LINE}`, color: INK, textDecoration: "none" }}
                >
                  <IconDownload size={16} />
                  הורדת כל התמונות (ZIP)
                </a>
              ) : null}

              <div className="rounded-lg overflow-hidden" style={{ border: `1px solid ${LINE}` }}>
                {filteredEntries.length === 0 ? (
                  <div className="text-center py-10 px-4 text-sm" style={{ color: INK_SOFT }}>
                    {entries.length === 0 ? "עדיין אין רשומות. אפשר להוסיף אחת בלשונית הוספה." : "אין רשומות התואמות לסינון שנבחר."}
                  </div>
                ) : (
                  filteredEntries.map((entry) => (
                    <EntryCard
                      key={entry.id}
                      entry={entry}
                      onEdit={() => startEdit(entry)}
                      onToggleReimburse={() => toggleReimbursed(entry.id)}
                      onDelete={() => deleteEntry(entry.id)}
                      onDownloadImage={downloadEntryImage}
                      confirming={confirmDeleteId === entry.id}
                      onArmDelete={() => setConfirmDeleteId(entry.id)}
                      onCancelDelete={() => setConfirmDeleteId(null)}
                    />
                  ))
                )}
              </div>
            </div>
          )}

          {tab === "reimb" && (
            <div className="p-5 space-y-4">
              <div className="flex rounded-lg overflow-hidden" style={{ border: `1px solid ${LINE}` }}>
                {[
                  { id: "all", label: "הכל" },
                  { id: "pending", label: "ממתין" },
                  { id: "done", label: "הוחזר" },
                ].map(({ id, label }) => (
                  <button
                    key={id}
                    onClick={() => setReimbFilter(id)}
                    className="flex-1 py-2 text-sm font-semibold transition-colors"
                    style={{
                      background: reimbFilter === id ? GOLD : PAPER,
                      color: reimbFilter === id ? "#fff" : INK,
                    }}
                  >
                    {label}
                  </button>
                ))}
              </div>

              <div className="grid grid-cols-2 gap-2">
                <div className="rounded-lg p-3 text-center" style={{ background: `${GOLD}18` }}>
                  <div className="text-xs" style={{ color: INK_SOFT }}>
                    ממתין להחזר
                  </div>
                  <div className="tabular-amt font-bold text-sm mt-0.5" style={{ color: GOLD }}>
                    {formatILS(pendingReimbTotal)}
                  </div>
                </div>
                <div className="rounded-lg p-3 text-center" style={{ background: `${CREDIT}14` }}>
                  <div className="text-xs" style={{ color: INK_SOFT }}>
                    הוחזר
                  </div>
                  <div className="tabular-amt font-bold text-sm mt-0.5" style={{ color: CREDIT }}>
                    {formatILS(doneReimbTotal)}
                  </div>
                </div>
              </div>

              <div className="space-y-2">
                {reimbursementItems.length === 0 ? (
                  <div className="text-center py-10 px-4 text-sm" style={{ color: INK_SOFT }}>
                    {allReimbursable.length === 0
                      ? "אין רשומות עם דרישת החזר. סימון מתבצע בעת הוספת רשומה."
                      : "אין רשומות בסינון הנוכחי."}
                  </div>
                ) : (
                  reimbursementItems.map((entry) => (
                    <ReimbursementCard
                      key={entry.id}
                      entry={entry}
                      onToggle={() => toggleReimbursed(entry.id)}
                      onDownloadImage={downloadEntryImage}
                    />
                  ))
                )}
              </div>
            </div>
          )}

          {tab === "warranty" && (
            <div className="p-5 space-y-3">
              {warrantyItems.length === 0 ? (
                <div className="text-center py-10 px-4 text-sm" style={{ color: INK_SOFT }}>
                  אין מוצרים עם אחריות רשומה. סימון אחריות מתבצע בעת הוספת רשומה.
                </div>
              ) : (
                warrantyItems.map((item) => (
                  <WarrantyCard key={item.id} item={item} onDownloadImage={downloadEntryImage} />
                ))
              )}
            </div>
          )}
        </main>
      </div>
    </div>
  );
}

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