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

/* =========================================================
   i18n
   ========================================================= */
const LANGS = ["ar", "en", "fr", "de"];
const LOCALE_MAP = { ar: "ar", en: "en-US", fr: "fr-FR", de: "de-DE" };
const DIR_MAP = { ar: "rtl", en: "ltr", fr: "ltr", de: "ltr" };
const LANG_NAMES = { ar: "العربية", en: "English", fr: "Français", de: "Deutsch" };
const LANG_KEY = "salary-planner:lang:v1";

const STRINGS = {
  appName: { ar: "مصروفي", en: "Masrofi", fr: "Masrofi", de: "Masrofi" },
  tagline: {
    ar: "بلانر الصالير والمصاريف",
    en: "Salary & expense planner",
    fr: "Planificateur salaire et dépenses",
    de: "Gehalts- und Ausgabenplaner",
  },
  authTaglineFull: {
    ar: "بلانر الصالير والمصاريف ديالك",
    en: "Your salary & expense planner",
    fr: "Votre planificateur salaire et dépenses",
    de: "Ihr Gehalts- und Ausgabenplaner",
  },
  loginTab: { ar: "تسجيل الدخول", en: "Log in", fr: "Connexion", de: "Anmelden" },
  registerTab: { ar: "حساب جديد", en: "New account", fr: "Nouveau compte", de: "Neues Konto" },
  nameLabel: { ar: "الاسم", en: "Name", fr: "Nom", de: "Name" },
  namePlaceholder: { ar: "مثلا: خالد", en: "e.g. Khalid", fr: "ex. Khalid", de: "z. B. Khalid" },
  emailLabel: { ar: "البريد الإلكتروني", en: "Email", fr: "E-mail", de: "E-Mail" },
  passwordLabel: { ar: "كلمة السر", en: "Password", fr: "Mot de passe", de: "Passwort" },
  registerSubmit: { ar: "إنشاء الحساب", en: "Create account", fr: "Créer le compte", de: "Konto erstellen" },
  loginSubmit: { ar: "دخول", en: "Log in", fr: "Se connecter", de: "Anmelden" },
  authHint: {
    ar: "الحساب محفوظ فهاد الجهاز/المتصفح بوحدو (localStorage)، ماشي على سيرفر — كل مستخدم عندو بياناته بوحدو.",
    en: "Your account is stored only on this device/browser (localStorage), not on a server — each user has their own data here.",
    fr: "Le compte est enregistré uniquement sur cet appareil/navigateur (localStorage), pas sur un serveur — chaque utilisateur a ses propres données ici.",
    de: "Das Konto wird nur auf diesem Gerät/Browser gespeichert (localStorage), nicht auf einem Server — jeder Nutzer hat hier seine eigenen Daten.",
  },
  errFillFields: { ar: "عمر البريد وكلمة السر", en: "Fill in email and password", fr: "Remplissez l'e-mail et le mot de passe", de: "E-Mail und Passwort ausfüllen" },
  errEmailTaken: {
    ar: "هاد البريد مسجل من قبل — دخل بلوگين بدل التسجيل",
    en: "This email is already registered — log in instead",
    fr: "Cet e-mail est déjà enregistré — connectez-vous plutôt",
    de: "Diese E-Mail ist bereits registriert — bitte anmelden",
  },
  errInvalidCreds: {
    ar: "البريد أو كلمة السر ماشي صحيحين",
    en: "Incorrect email or password",
    fr: "E-mail ou mot de passe incorrect",
    de: "E-Mail oder Passwort falsch",
  },
  greeting: { ar: "مرحبا،", en: "Hi,", fr: "Bonjour,", de: "Hallo," },
  logout: { ar: "خروج", en: "Log out", fr: "Déconnexion", de: "Abmelden" },
  prevMonth: { ar: "الشهر السابق", en: "Previous month", fr: "Mois précédent", de: "Vorheriger Monat" },
  nextMonth: { ar: "الشهر الجاي", en: "Next month", fr: "Mois suivant", de: "Nächster Monat" },
  incomeLabel: { ar: "الدخل", en: "Income", fr: "Revenus", de: "Einkommen" },
  expenseLabel: { ar: "المصاريف", en: "Expenses", fr: "Dépenses", de: "Ausgaben" },
  balanceLabel: { ar: "الرصيد", en: "Balance", fr: "Solde", de: "Saldo" },
  savingsRatioLabel: { ar: "نسبة الادخار", en: "Savings rate", fr: "Taux d'épargne", de: "Sparquote" },
  addEntryTitle: { ar: "زيد حركة جديدة", en: "Add a new entry", fr: "Ajouter une opération", de: "Neuen Eintrag hinzufügen" },
  categoryBreakdownTitle: { ar: "توزيع المصاريف حسب الفئة", en: "Expenses by category", fr: "Dépenses par catégorie", de: "Ausgaben nach Kategorie" },
  transactionsTitlePrefix: { ar: "الحركات ديال", en: "Entries for", fr: "Opérations de", de: "Einträge für" },
  expenseTab: { ar: "مصروف", en: "Expense", fr: "Dépense", de: "Ausgabe" },
  incomeTab: { ar: "دخل", en: "Income", fr: "Revenu", de: "Einnahme" },
  dateLabel: { ar: "التاريخ", en: "Date", fr: "Date", de: "Datum" },
  categoryLabel: { ar: "الفئة", en: "Category", fr: "Catégorie", de: "Kategorie" },
  sourceLabel: { ar: "المصدر", en: "Source", fr: "Source", de: "Quelle" },
  descLabel: { ar: "وصف (اختياري)", en: "Description (optional)", fr: "Description (optionnel)", de: "Beschreibung (optional)" },
  descPlaceholderExpense: {
    ar: "مثلا: سوق ديال السيمانة",
    en: "e.g. weekly groceries",
    fr: "ex. courses de la semaine",
    de: "z. B. wöchentlicher Einkauf",
  },
  descPlaceholderIncome: { ar: "مثلا: صالير غشت", en: "e.g. August salary", fr: "ex. salaire d'août", de: "z. B. Gehalt August" },
  amountLabel: { ar: "المبلغ (€)", en: "Amount (€)", fr: "Montant (€)", de: "Betrag (€)" },
  errAmount: { ar: "دخل مبلغ صحيح أكبر من صفر", en: "Enter a valid amount greater than zero", fr: "Entrez un montant valide supérieur à zéro", de: "Bitte einen gültigen Betrag größer als null eingeben" },
  errDate: { ar: "اختار التاريخ", en: "Choose a date", fr: "Choisissez une date", de: "Datum auswählen" },
  addExpenseBtn: { ar: "زيد المصروف", en: "Add expense", fr: "Ajouter la dépense", de: "Ausgabe hinzufügen" },
  addIncomeBtn: { ar: "زيد الدخل", en: "Add income", fr: "Ajouter le revenu", de: "Einnahme hinzufügen" },
  emptyCategoryHint: {
    ar: "مازال ما زدتي حتى مصروف — أول ما تزيد وحد غيبان هنا التوزيع.",
    en: "No expenses yet — add one and the breakdown will appear here.",
    fr: "Pas encore de dépense — ajoutez-en une et la répartition apparaîtra ici.",
    de: "Noch keine Ausgaben — fügen Sie eine hinzu, und die Aufschlüsselung erscheint hier.",
  },
  emptyTransactionsHint: {
    ar: "ماكاينش حركات فهاد الشهر. زيد أول واحدة من الفورم فوق.",
    en: "No entries this month yet. Add your first one from the form above.",
    fr: "Aucune opération ce mois-ci. Ajoutez-en une depuis le formulaire ci-dessus.",
    de: "Diesen Monat noch keine Einträge. Fügen Sie oben Ihren ersten hinzu.",
  },
  footerNote: {
    ar: "البيانات كتبقى محفوظة فهاتف/متصفح ديالك بوحدو (localStorage) — حيد نسخة احتياطية من وقت لآخر.",
    en: "Your data stays saved only on this phone/browser (localStorage) — take a backup from time to time.",
    fr: "Vos données restent enregistrées uniquement sur ce téléphone/navigateur (localStorage) — faites une sauvegarde de temps en temps.",
    de: "Ihre Daten bleiben nur auf diesem Telefon/Browser gespeichert (localStorage) — erstellen Sie gelegentlich ein Backup.",
  },
  exportBtn: { ar: "تحميل نسخة احتياطية", en: "Download backup", fr: "Télécharger la sauvegarde", de: "Backup herunterladen" },
  importBtn: { ar: "استرجاع نسخة", en: "Restore backup", fr: "Restaurer la sauvegarde", de: "Backup wiederherstellen" },
  importError: {
    ar: "الملف مامقروءش، تأكد بلي هو نسخة احتياطية صحيحة",
    en: "Couldn't read the file — make sure it's a valid backup",
    fr: "Impossible de lire le fichier — vérifiez qu'il s'agit d'une sauvegarde valide",
    de: "Datei konnte nicht gelesen werden — prüfen Sie, ob es ein gültiges Backup ist",
  },
  langSwitchAria: { ar: "تبديل اللغة", en: "Switch language", fr: "Changer de langue", de: "Sprache wechseln" },
};

function t(key, lang) {
  const entry = STRINGS[key];
  if (!entry) return key;
  return entry[lang] || entry.en || key;
}

const LangContext = createContext(null);
function useLang() { return useContext(LangContext); }

/* =========================================================
   Categories (id-based, translated + icon per category)
   ========================================================= */
const EXPENSE_CATEGORIES = [
  { id: "housing", icon: "🏠", ar: "السكن (كراء/قرض)", en: "Housing (rent/loan)", fr: "Logement (loyer/prêt)", de: "Wohnen (Miete/Kredit)" },
  { id: "groceries", icon: "🛒", ar: "البقالة والسوق", en: "Groceries", fr: "Courses", de: "Lebensmittel" },
  { id: "dining", icon: "🍽️", ar: "مطاعم وأكل بره", en: "Dining out", fr: "Restaurants", de: "Auswärts essen" },
  { id: "transport", icon: "🚗", ar: "النقل والمواصلات", en: "Transport", fr: "Transport", de: "Transport" },
  { id: "fuel", icon: "⛽", ar: "الوقود", en: "Fuel", fr: "Carburant", de: "Kraftstoff" },
  { id: "utilities", icon: "💡", ar: "الفواتير (كهرباء/ماء)", en: "Utilities (electricity/water)", fr: "Charges (électricité/eau)", de: "Nebenkosten (Strom/Wasser)" },
  { id: "internet", icon: "📶", ar: "الإنترنت والهاتف", en: "Internet & phone", fr: "Internet et téléphone", de: "Internet & Telefon" },
  { id: "health", icon: "🏥", ar: "الصحة والتأمين", en: "Health & insurance", fr: "Santé et assurance", de: "Gesundheit & Versicherung" },
  { id: "education", icon: "🎓", ar: "التعليم", en: "Education", fr: "Éducation", de: "Bildung" },
  { id: "entertainment", icon: "🎬", ar: "الترفيه والخروجات", en: "Entertainment", fr: "Loisirs", de: "Unterhaltung" },
  { id: "subscriptions", icon: "📱", ar: "الاشتراكات", en: "Subscriptions", fr: "Abonnements", de: "Abonnements" },
  { id: "clothing", icon: "👕", ar: "ملابس وتسوق", en: "Clothing & shopping", fr: "Vêtements et shopping", de: "Kleidung & Einkaufen" },
  { id: "debt", icon: "💳", ar: "ديون وتقسيط", en: "Debt & installments", fr: "Dettes et mensualités", de: "Schulden & Raten" },
  { id: "savings", icon: "💰", ar: "ادخار واستثمار", en: "Savings & investment", fr: "Épargne et investissement", de: "Sparen & Investieren" },
  { id: "travel", icon: "✈️", ar: "السفر", en: "Travel", fr: "Voyage", de: "Reisen" },
  { id: "gifts", icon: "🎁", ar: "هدايا", en: "Gifts", fr: "Cadeaux", de: "Geschenke" },
  { id: "pets", icon: "🐾", ar: "الحيوانات الأليفة", en: "Pets", fr: "Animaux", de: "Haustiere" },
  { id: "childcare", icon: "👶", ar: "الأطفال", en: "Childcare", fr: "Enfants", de: "Kinderbetreuung" },
  { id: "fitness", icon: "💪", ar: "الرياضة واللياقة", en: "Fitness", fr: "Sport et fitness", de: "Fitness" },
  { id: "charity", icon: "🤲", ar: "الصدقة والتبرعات", en: "Charity & donations", fr: "Charité et dons", de: "Spenden" },
  { id: "taxes", icon: "🧾", ar: "الضرائب والرسوم", en: "Taxes & fees", fr: "Impôts et frais", de: "Steuern & Gebühren" },
  { id: "other", icon: "📦", ar: "مصاريف أخرى", en: "Other expenses", fr: "Autres dépenses", de: "Sonstige Ausgaben" },
];

const INCOME_CATEGORIES = [
  { id: "salary", icon: "💼", ar: "صالير أساسي", en: "Base salary", fr: "Salaire de base", de: "Grundgehalt" },
  { id: "freelance", icon: "🧑‍💻", ar: "عمل إضافي/حر", en: "Freelance / side job", fr: "Travail indépendant", de: "Nebenjob/Freelance" },
  { id: "investment", icon: "📈", ar: "عوائد استثمار", en: "Investment returns", fr: "Revenus d'investissement", de: "Kapitalerträge" },
  { id: "gift_income", icon: "🎁", ar: "هدايا ومساعدات", en: "Gifts / support", fr: "Cadeaux / aide", de: "Geschenke/Unterstützung" },
  { id: "other_income", icon: "💵", ar: "مداخيل أخرى", en: "Other income", fr: "Autres revenus", de: "Sonstige Einnahmen" },
];

function findCategory(kind, id) {
  const list = kind === "expense" ? EXPENSE_CATEGORIES : INCOME_CATEGORIES;
  return list.find((c) => c.id === id) || null;
}
function categoryLabel(kind, id, lang) {
  const c = findCategory(kind, id);
  return c ? c[lang] || c.en : id;
}
function categoryIcon(kind, id) {
  const c = findCategory(kind, id);
  return c ? c.icon : "📦";
}

/* =========================================================
   Storage helpers
   ========================================================= */
const USERS_KEY = "salary-planner:users:v1";
const SESSION_KEY = "salary-planner:session:v1";

function entriesKeyFor(email) {
  return `salary-planner:entries:v1:${email}`;
}
function loadEntries(email) {
  try {
    const raw = localStorage.getItem(entriesKeyFor(email));
    if (!raw) return [];
    const parsed = JSON.parse(raw);
    return Array.isArray(parsed) ? parsed : [];
  } catch {
    return [];
  }
}
function saveEntries(email, entries) {
  try { localStorage.setItem(entriesKeyFor(email), JSON.stringify(entries)); } catch {}
}
function loadUsers() {
  try {
    const raw = localStorage.getItem(USERS_KEY);
    const parsed = raw ? JSON.parse(raw) : [];
    return Array.isArray(parsed) ? parsed : [];
  } catch { return []; }
}
function saveUsers(users) {
  try { localStorage.setItem(USERS_KEY, JSON.stringify(users)); } catch {}
}
function loadSession() {
  try {
    const raw = localStorage.getItem(SESSION_KEY);
    return raw ? JSON.parse(raw) : null;
  } catch { return null; }
}
function saveSession(session) {
  try {
    if (session) localStorage.setItem(SESSION_KEY, JSON.stringify(session));
    else localStorage.removeItem(SESSION_KEY);
  } catch {}
}
function simpleHash(str) {
  let h = 0;
  for (let i = 0; i < str.length; i++) { h = (Math.imul(31, h) + str.charCodeAt(i)) | 0; }
  return String(h);
}
function makeId() {
  return Math.random().toString(36).slice(2, 10) + Date.now().toString(36);
}
function todayISO() {
  return new Date().toISOString().slice(0, 10);
}
function monthKey(dateISO) {
  return dateISO.slice(0, 7);
}
function monthLabel(key, lang) {
  const [y, m] = key.split("-").map(Number);
  const d = new Date(y, m - 1, 1);
  return d.toLocaleDateString(LOCALE_MAP[lang] || "en-US", { month: "long", year: "numeric" });
}
function shiftMonth(key, delta) {
  const [y, m] = key.split("-").map(Number);
  const d = new Date(y, m - 1 + delta, 1);
  return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}`;
}
function currencyFmt(n, lang) {
  return new Intl.NumberFormat(LOCALE_MAP[lang] || "en-US", { style: "currency", currency: "EUR" }).format(n);
}

/* =========================================================
   Language switcher
   ========================================================= */
function LangSwitch({ className }) {
  const { lang, setLang } = useLang();
  return (
    <div className={`lang-switch ${className || ""}`}>
      <span aria-hidden="true">🌐</span>
      <select value={lang} onChange={(e) => setLang(e.target.value)} aria-label={t("langSwitchAria", lang)}>
        {LANGS.map((l) => <option key={l} value={l}>{LANG_NAMES[l]}</option>)}
      </select>
    </div>
  );
}

/* =========================================================
   Savings ring
   ========================================================= */
function SavingsRing({ ratio, balance }) {
  const { lang } = useLang();
  const clamped = Math.max(0, Math.min(1, ratio));
  const negative = balance < 0;
  const size = 200, stroke = 14;
  const r = (size - stroke) / 2;
  const circumference = 2 * Math.PI * r;
  const offset = circumference * (1 - clamped);
  const color = negative ? "var(--red)" : "var(--gold)";

  return (
    <div className="ring-wrap" role="img" aria-label={`${t("savingsRatioLabel", lang)} ${Math.round(ratio * 100)}%`}>
      <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
        <circle cx={size/2} cy={size/2} r={r} fill="none" stroke="var(--surface-2)" strokeWidth={stroke} />
        <circle
          cx={size/2} cy={size/2} r={r} fill="none" stroke={color} strokeWidth={stroke}
          strokeLinecap="round" strokeDasharray={circumference} strokeDashoffset={offset}
          transform={`rotate(-90 ${size/2} ${size/2})`}
          style={{ transition: "stroke-dashoffset 0.6s ease" }}
        />
      </svg>
      <div className="ring-center">
        <span className="ring-pct">{Math.round(ratio * 100)}%</span>
        <span className="ring-label">{t("savingsRatioLabel", lang)}</span>
      </div>
    </div>
  );
}

/* =========================================================
   Category bars
   ========================================================= */
function CategoryBars({ rows }) {
  const { lang } = useLang();
  const max = Math.max(1, ...rows.map((r) => r.amount));
  if (rows.length === 0) {
    return <p className="empty-hint">{t("emptyCategoryHint", lang)}</p>;
  }
  return (
    <div className="bars">
      {rows.map((r) => (
        <div className="bar-row" key={r.categoryId}>
          <div className="bar-row-top">
            <span className="bar-icon">{categoryIcon("expense", r.categoryId)}</span>
            <span className="bar-name">{categoryLabel("expense", r.categoryId, lang)}</span>
            <span className="bar-amount">{currencyFmt(r.amount, lang)}</span>
          </div>
          <div className="bar-track">
            <div className="bar-fill" style={{ width: `${(r.amount / max) * 100}%` }} />
          </div>
        </div>
      ))}
    </div>
  );
}

/* =========================================================
   Entry form
   ========================================================= */
function EntryForm({ onAdd }) {
  const { lang } = useLang();
  const [kind, setKind] = useState("expense");
  const [date, setDate] = useState(todayISO());
  const [categoryId, setCategoryId] = useState(EXPENSE_CATEGORIES[0].id);
  const [label, setLabel] = useState("");
  const [amount, setAmount] = useState("");
  const [error, setError] = useState("");

  const categories = kind === "expense" ? EXPENSE_CATEGORIES : INCOME_CATEGORIES;

  function switchKind(next) {
    setKind(next);
    setCategoryId(next === "expense" ? EXPENSE_CATEGORIES[0].id : INCOME_CATEGORIES[0].id);
    setError("");
  }

  function submit(e) {
    e.preventDefault();
    const value = parseFloat(String(amount).replace(",", "."));
    if (!value || value <= 0) { setError(t("errAmount", lang)); return; }
    if (!date) { setError(t("errDate", lang)); return; }
    const fallbackLabel = categoryLabel(kind, categoryId, lang);
    onAdd({ id: makeId(), kind, date, category: categoryId, label: label.trim() || fallbackLabel, amount: value });
    setLabel(""); setAmount(""); setError("");
  }

  return (
    <form className="entry-form" onSubmit={submit}>
      <div className="kind-toggle" role="tablist" aria-label="kind">
        <button type="button" role="tab" aria-selected={kind === "expense"}
          className={`kind-btn ${kind === "expense" ? "kind-btn--active kind-expense" : ""}`}
          onClick={() => switchKind("expense")}>{t("expenseTab", lang)}</button>
        <button type="button" role="tab" aria-selected={kind === "income"}
          className={`kind-btn ${kind === "income" ? "kind-btn--active kind-income" : ""}`}
          onClick={() => switchKind("income")}>{t("incomeTab", lang)}</button>
      </div>

      <div className="form-grid">
        <label className="field">
          <span>{t("dateLabel", lang)}</span>
          <input type="date" value={date} onChange={(e) => setDate(e.target.value)} required />
        </label>
        <label className="field">
          <span>{kind === "expense" ? t("categoryLabel", lang) : t("sourceLabel", lang)}</span>
          <select value={categoryId} onChange={(e) => setCategoryId(e.target.value)}>
            {categories.map((c) => <option key={c.id} value={c.id}>{c.icon} {c[lang] || c.en}</option>)}
          </select>
        </label>
        <label className="field field--wide">
          <span>{t("descLabel", lang)}</span>
          <input type="text" placeholder={kind === "expense" ? t("descPlaceholderExpense", lang) : t("descPlaceholderIncome", lang)}
            value={label} onChange={(e) => setLabel(e.target.value)} />
        </label>
        <label className="field">
          <span>{t("amountLabel", lang)}</span>
          <input type="text" inputMode="decimal" placeholder="0.00" value={amount}
            onChange={(e) => setAmount(e.target.value)} />
        </label>
      </div>

      {error && <p className="form-error">{error}</p>}

      <button type="submit" className={`submit-btn ${kind === "income" ? "submit-btn--income" : ""}`}>
        {kind === "expense" ? t("addExpenseBtn", lang) : t("addIncomeBtn", lang)}
      </button>
    </form>
  );
}

/* =========================================================
   Entry list
   ========================================================= */
function EntryList({ entries, onDelete }) {
  const { lang } = useLang();
  if (entries.length === 0) {
    return <p className="empty-hint">{t("emptyTransactionsHint", lang)}</p>;
  }
  const sorted = [...entries].sort((a, b) => b.date.localeCompare(a.date));
  return (
    <ul className="entry-list">
      {sorted.map((e) => (
        <li key={e.id} className={`entry-item entry-item--${e.kind}`}>
          <div className="entry-icon" aria-hidden="true">{categoryIcon(e.kind, e.category)}</div>
          <div className="entry-main">
            <div className="entry-top">
              <span className="entry-label">{e.label}</span>
              <span className={`entry-amount ${e.kind === "income" ? "entry-amount--income" : ""}`}>
                {e.kind === "income" ? "+" : "-"}{currencyFmt(e.amount, lang)}
              </span>
            </div>
            <div className="entry-sub">
              <span>{categoryLabel(e.kind, e.category, lang)}</span>
              <span className="entry-date">{e.date}</span>
            </div>
          </div>
          <button className="entry-delete" onClick={() => onDelete(e.id)} aria-label={e.label} title="×">×</button>
        </li>
      ))}
    </ul>
  );
}

/* =========================================================
   Auth screen
   ========================================================= */
function AuthScreen({ onAuth }) {
  const { lang } = useLang();
  const [mode, setMode] = useState("login");
  const [name, setName] = useState("");
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [error, setError] = useState("");

  function submit(e) {
    e.preventDefault();
    setError("");
    const cleanEmail = email.trim().toLowerCase();
    if (!cleanEmail || !password) { setError(t("errFillFields", lang)); return; }

    const users = loadUsers();

    if (mode === "register") {
      if (users.some((u) => u.email === cleanEmail)) {
        setError(t("errEmailTaken", lang));
        return;
      }
      const user = { name: name.trim() || cleanEmail.split("@")[0], email: cleanEmail, passwordHash: simpleHash(password) };
      saveUsers([...users, user]);
      saveSession({ email: user.email, name: user.name });
      onAuth({ email: user.email, name: user.name });
    } else {
      const user = users.find((u) => u.email === cleanEmail);
      if (!user || user.passwordHash !== simpleHash(password)) {
        setError(t("errInvalidCreds", lang));
        return;
      }
      saveSession({ email: user.email, name: user.name });
      onAuth({ email: user.email, name: user.name });
    }
  }

  return (
    <div className="auth-screen">
      <div className="auth-card">
        <div className="auth-lang"><LangSwitch /></div>
        <div className="auth-logo">م</div>
        <h1>{t("appName", lang)}</h1>
        <p>{t("authTaglineFull", lang)}</p>

        <div className="auth-tabs">
          <button type="button" className={`auth-tab ${mode === "login" ? "auth-tab--active" : ""}`} onClick={() => { setMode("login"); setError(""); }}>
            {t("loginTab", lang)}
          </button>
          <button type="button" className={`auth-tab ${mode === "register" ? "auth-tab--active" : ""}`} onClick={() => { setMode("register"); setError(""); }}>
            {t("registerTab", lang)}
          </button>
        </div>

        <form onSubmit={submit}>
          {mode === "register" && (
            <label className="auth-field">
              <span>{t("nameLabel", lang)}</span>
              <input type="text" value={name} onChange={(e) => setName(e.target.value)} placeholder={t("namePlaceholder", lang)} />
            </label>
          )}
          <label className="auth-field">
            <span>{t("emailLabel", lang)}</span>
            <input type="email" value={email} onChange={(e) => setEmail(e.target.value)} placeholder="you@example.com" required />
          </label>
          <label className="auth-field">
            <span>{t("passwordLabel", lang)}</span>
            <input type="password" value={password} onChange={(e) => setPassword(e.target.value)} placeholder="••••••••" required />
          </label>

          {error && <p className="auth-error">{error}</p>}

          <button type="submit" className="auth-submit">
            {mode === "register" ? t("registerSubmit", lang) : t("loginSubmit", lang)}
          </button>
        </form>

        <p className="auth-hint">{t("authHint", lang)}</p>
      </div>
    </div>
  );
}

/* =========================================================
   Main planner
   ========================================================= */
function Planner() {
  const { lang } = useLang();
  const [session, setSession] = useState(() => loadSession());
  const [entries, setEntries] = useState(() => (session ? loadEntries(session.email) : []));
  const [month, setMonth] = useState(() => new Date().toISOString().slice(0, 7));
  const fileInputRef = useRef(null);

  useEffect(() => {
    if (session) setEntries(loadEntries(session.email));
  }, [session]);

  useEffect(() => {
    if (session) saveEntries(session.email, entries);
  }, [entries, session]);

  const availableMonths = useMemo(() => {
    const set = new Set(entries.map((e) => monthKey(e.date)));
    set.add(month);
    return Array.from(set).sort().reverse();
  }, [entries, month]);

  const monthEntries = useMemo(() => entries.filter((e) => monthKey(e.date) === month), [entries, month]);

  const income = useMemo(() => monthEntries.filter((e) => e.kind === "income").reduce((s, e) => s + e.amount, 0), [monthEntries]);
  const expenses = useMemo(() => monthEntries.filter((e) => e.kind === "expense").reduce((s, e) => s + e.amount, 0), [monthEntries]);
  const balance = income - expenses;
  const savingsRatio = income > 0 ? balance / income : 0;

  const categoryRows = useMemo(() => {
    const map = new Map();
    monthEntries.filter((e) => e.kind === "expense").forEach((e) => map.set(e.category, (map.get(e.category) || 0) + e.amount));
    return Array.from(map, ([categoryId, amount]) => ({ categoryId, amount })).sort((a, b) => b.amount - a.amount);
  }, [monthEntries]);

  function addEntry(entry) { setEntries((prev) => [...prev, entry]); }
  function deleteEntry(id) { setEntries((prev) => prev.filter((e) => e.id !== id)); }
  function logout() { saveSession(null); setSession(null); }
  function goPrevMonth() { setMonth((m) => shiftMonth(m, -1)); }
  function goNextMonth() { setMonth((m) => shiftMonth(m, 1)); }

  function exportData() {
    const blob = new Blob([JSON.stringify(entries, null, 2)], { type: "application/json" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url; a.download = `masrofi-backup-${month}.json`; a.click();
    URL.revokeObjectURL(url);
  }
  function importData(e) {
    const file = e.target.files && e.target.files[0];
    if (!file) return;
    const reader = new FileReader();
    reader.onload = () => {
      try {
        const parsed = JSON.parse(String(reader.result));
        if (Array.isArray(parsed)) setEntries(parsed);
      } catch { alert(t("importError", lang)); }
    };
    reader.readAsText(file);
    e.target.value = "";
  }

  if (!session) {
    return <AuthScreen onAuth={setSession} />;
  }

  const prevGlyph = DIR_MAP[lang] === "rtl" ? "›" : "‹";
  const nextGlyph = DIR_MAP[lang] === "rtl" ? "‹" : "›";

  return (
    <div className="app">
      <div className="user-bar">
        <span>{t("greeting", lang)} <strong>{session.name}</strong></span>
        <button type="button" className="logout-btn" onClick={logout}>{t("logout", lang)}</button>
      </div>

      <header className="topbar">
        <div className="brand">
          <span className="brand-mark">م</span>
          <div><h1>{t("appName", lang)}</h1><p>{t("tagline", lang)}</p></div>
        </div>
        <div className="top-actions">
          <LangSwitch />
        </div>
      </header>

      <div className="month-nav">
        <button type="button" className="month-arrow" onClick={goPrevMonth} aria-label={t("prevMonth", lang)}>{prevGlyph}</button>
        <div className="month-picker">
          <select value={month} onChange={(e) => setMonth(e.target.value)}>
            {availableMonths.map((m) => <option key={m} value={m}>{monthLabel(m, lang)}</option>)}
          </select>
        </div>
        <button type="button" className="month-arrow" onClick={goNextMonth} aria-label={t("nextMonth", lang)}>{nextGlyph}</button>
      </div>

      <section className="hero" style={{ marginTop: 18 }}>
        <SavingsRing ratio={savingsRatio} balance={balance} />
        <div className="stat-chips">
          <div className="chip chip--income"><span className="chip-label">{t("incomeLabel", lang)}</span><span className="chip-value">{currencyFmt(income, lang)}</span></div>
          <div className="chip chip--expense"><span className="chip-label">{t("expenseLabel", lang)}</span><span className="chip-value">{currencyFmt(expenses, lang)}</span></div>
          <div className={`chip ${balance >= 0 ? "chip--balance-pos" : "chip--balance-neg"}`}><span className="chip-label">{t("balanceLabel", lang)}</span><span className="chip-value">{currencyFmt(balance, lang)}</span></div>
        </div>
      </section>

      <section className="panel">
        <h2>{t("addEntryTitle", lang)}</h2>
        <EntryForm onAdd={addEntry} />
      </section>

      <section className="panel">
        <h2>{t("categoryBreakdownTitle", lang)}</h2>
        <CategoryBars rows={categoryRows} />
      </section>

      <section className="panel">
        <div className="panel-header-row"><h2>{t("transactionsTitlePrefix", lang)} {monthLabel(month, lang)}</h2></div>
        <EntryList entries={monthEntries} onDelete={deleteEntry} />
      </section>

      <footer className="footer">
        <p>{t("footerNote", lang)}</p>
        <div className="footer-actions">
          <button onClick={exportData} className="ghost-btn">{t("exportBtn", lang)}</button>
          <button onClick={() => fileInputRef.current && fileInputRef.current.click()} className="ghost-btn">{t("importBtn", lang)}</button>
          <input ref={fileInputRef} type="file" accept="application/json" onChange={importData} hidden />
        </div>
      </footer>
    </div>
  );
}

/* =========================================================
   Root: owns language state + provides context
   ========================================================= */
function Root() {
  const [lang, setLang] = useState(() => {
    try { return localStorage.getItem(LANG_KEY) || "ar"; } catch { return "ar"; }
  });

  useEffect(() => {
    document.documentElement.lang = lang;
    document.documentElement.dir = DIR_MAP[lang] || "ltr";
    try { localStorage.setItem(LANG_KEY, lang); } catch {}
  }, [lang]);

  const ctx = useMemo(() => ({ lang, setLang }), [lang]);

  return (
    <LangContext.Provider value={ctx}>
      <Planner />
    </LangContext.Provider>
  );
}

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