// wallet.jsx — Shahdad financial center
// UI-only in v31.90. The server must remain the authority for balances,
// transactions, invoices, payment methods and every charge attempt.

const WALLET_CENTER_CONFIG = Object.freeze({
  version: "31.90",
  currency: "IRR_TOMAN",
  displayUnit: "toman",
  settlementUnit: "rial",
  minCharge: 100000,
  maxCharge: 50000000,
  dailyChargeLimit: 50000000,
  quickAmounts: [200000, 500000, 1000000, 2000000],
  gateway: {
    status: "disconnected",
    provider: null,
    acceptsCardData: false,
  },
});

const WALLET_COPY = {
  fa: {
    kicker: "مرکز مالی شهداد",
    title: "کیف پول و پرداخت‌ها",
    subtitle: "مانده، شارژ حساب، گردش مالی و اسناد پرداخت را یک‌جا مدیریت کنید.",
    guest: "حساب مهمان",
    active: "کیف پول آماده اتصال",
    guestHint: "برای شارژ، دریافت فاکتور رسمی و مشاهده گردش واقعی وارد حساب شوید.",
    signIn: "ورود و فعال‌سازی کیف پول",
    available: "مانده قابل استفاده",
    held: "مبالغ در انتظار",
    credit: "اعتبار هدیه",
    dailyLimit: "سقف شارژ روزانه",
    chargeNow: "شارژ حساب",
    balanceSource: "مانده فقط پس از پاسخ تأییدشده سرور نمایش داده می‌شود.",
    chargeTitle: "شارژ سریع حساب",
    chargeSub: "مبلغ پیشنهادی را انتخاب کنید یا مبلغ دلخواه بنویسید.",
    customAmount: "مبلغ دلخواه",
    amountPlaceholder: "مثلاً ۵۰۰٬۰۰۰",
    toman: "تومان",
    rial: "ریال",
    gateway: "درگاه بانکی",
    invoice: "واریز سازمانی",
    gatewaySub: "انتقال به درگاه امن پس از تأیید مبلغ",
    invoiceSub: "ساخت درخواست واریز و فاکتور برای سازمان",
    payable: "مبلغ انتخاب‌شده",
    gatewayAmount: "معادل مبلغ درگاه",
    continueGuest: "ورود و ادامه شارژ",
    continueGateway: "بررسی آمادگی درگاه",
    continueInvoice: "بررسی صدور درخواست واریز",
    invalidAmount: "مبلغ را فقط به‌صورت عدد صحیح و بدون علامت وارد کنید.",
    minError: "حداقل مبلغ شارژ ۱۰۰٬۰۰۰ تومان است.",
    maxError: "حداکثر مبلغ هر شارژ ۵۰٬۰۰۰٬۰۰۰ تومان است.",
    gatewayOffline: "درگاه پرداخت هنوز متصل نشده است؛ هیچ مبلغی کسر و هیچ تراکنشی ثبت نشد.",
    invoiceOffline: "صدور درخواست واریز سازمانی به بک‌اند مالی متصل نشده است؛ هیچ سندی ثبت نشد.",
    loginNotice: "برای ادامه عملیات مالی، ابتدا وارد حساب شهداد شوید.",
    draftNote: "این نسخه برای ارزیابی رابط مالی است. مانده و ردیف‌های نمونه، داده واقعی حساب شما نیستند.",
    activity: "گردش حساب",
    bills: "صورتحساب‌ها",
    methods: "روش‌های پرداخت",
    controls: "کنترل مالی",
    all: "همه",
    income: "واریز",
    expense: "برداشت",
    sampleData: "نمونه رابط",
    transaction: "شرح تراکنش",
    reference: "شناسه",
    date: "تاریخ",
    amount: "مبلغ",
    status: "وضعیت",
    success: "موفق",
    paid: "پرداخت‌شده",
    refunded: "بازگشت‌خورده",
    invoiceTitle: "اسناد و صورتحساب‌های مالی",
    invoiceSubTitle: "پیش‌فاکتور، فاکتور و رسید خدمات در این بخش نگهداری می‌شود.",
    viewSample: "مشاهده نمونه",
    noRealInvoice: "برای این حساب هنوز صورتحساب واقعی ثبت نشده است.",
    paymentMethodsTitle: "مسیرهای پرداخت",
    paymentMethodsSub: "اطلاعات کارت بانکی در شهداد ذخیره نمی‌شود.",
    primaryMethod: "روش پیشنهادی",
    unavailable: "در انتظار اتصال",
    manage: "مدیریت",
    budgetTitle: "بودجه و هشدارها",
    monthlyBudget: "بودجه ماهانه خدمات",
    lowBalance: "هشدار کاهش مانده",
    invoiceEmail: "ارسال فاکتور به ایمیل",
    autoCharge: "شارژ خودکار",
    autoChargeHint: "پس از اتصال درگاه و تأیید صریح کاربر فعال می‌شود.",
    temporarySettings: "تنظیمات این پیش‌نمایش موقت است و به‌عنوان داده مالی ذخیره نمی‌شود.",
    financeTools: "ابزارهای مالی",
    refund: "درخواست بازپرداخت",
    export: "خروجی گردش حساب",
    escrow: "حساب امانی پرونده",
    organization: "تسویه سازمانی",
    toolNotice: "این مسیر طراحی شده و پس از اتصال سرویس مالی فعال می‌شود.",
    securityTitle: "مرز امن پرداخت",
    securityText: "شهداد اطلاعات کامل کارت را دریافت یا ذخیره نمی‌کند. مبلغ نهایی پیش از انتقال به درگاه، هم به تومان و هم به ریال نمایش داده می‌شود.",
    pluto: "پلوتون",
    hideBalance: "پنهان‌کردن مانده",
    showBalance: "نمایش مانده",
    hide: "پنهان‌کردن",
    show: "نمایش",
    serverSettlement: "تسویه فقط با تأیید سمت سرور",
    currentPlan: "پلن فعلی",
    dismiss: "بستن پیام",
    creditCode: "کد اعتبار شهداد",
    creditCodeSub: "اعمال اعتبار هدیه یا سازمانی با ثبت سمت سرور",
    budgetUsage: "۳۲٪ مصرف نمونه از بودجه انتخابی",
    lowBalanceHint: "وقتی مانده کمتر از ۲۰۰ هزار تومان شد",
    invoiceEmailHint: "پس از صدور سند واقعی",
  },
  ar: {
    kicker: "مركز شهداد المالي",
    title: "المحفظة والمدفوعات",
    subtitle: "أدِر رصيدك وشحن حسابك وحركتك المالية ومستندات الدفع من مكان واحد.",
    guest: "حساب ضيف",
    active: "المحفظة جاهزة للربط",
    guestHint: "سجّل الدخول لشحن الرصيد واستلام الفواتير الرسمية وعرض الحركة الفعلية.",
    signIn: "تسجيل الدخول وتفعيل المحفظة",
    available: "الرصيد المتاح",
    held: "المبالغ المعلّقة",
    credit: "رصيد المكافآت",
    dailyLimit: "الحد اليومي لشحن الرصيد",
    chargeNow: "شحن الرصيد",
    balanceSource: "لا يظهر الرصيد إلا بعد استجابة موثّقة من الخادم.",
    chargeTitle: "شحن سريع للرصيد",
    chargeSub: "اختر مبلغًا مقترحًا أو أدخل مبلغًا مخصصًا.",
    customAmount: "مبلغ مخصص",
    amountPlaceholder: "مثلاً ٥٠٠٬٠٠٠",
    toman: "تومان",
    rial: "ريال",
    gateway: "بوابة الدفع البنكية",
    invoice: "إيداع مؤسسي",
    gatewaySub: "الانتقال إلى بوابة الدفع الآمنة بعد تأكيد المبلغ",
    invoiceSub: "إنشاء طلب إيداع وفاتورة للمؤسسة",
    payable: "المبلغ المحدد",
    gatewayAmount: "المبلغ المكافئ لدى بوابة الدفع",
    continueGuest: "تسجيل الدخول ومتابعة الشحن",
    continueGateway: "التحقق من جاهزية البوابة",
    continueInvoice: "التحقق من جاهزية طلب الإيداع",
    invalidAmount: "أدخل المبلغ بأرقام صحيحة فقط ومن دون إشارات.",
    minError: "الحد الأدنى للشحن هو ١٠٠٬٠٠٠ تومان.",
    maxError: "الحد الأقصى لكل عملية شحن هو ٥٠٬٠٠٠٬٠٠٠ تومان.",
    gatewayOffline: "بوابة الدفع غير متصلة بعد؛ لم يُخصم أي مبلغ ولم تُسجَّل أي معاملة.",
    invoiceOffline: "طلبات الإيداع المؤسسي غير متصلة بالنظام المالي الخلفي؛ لم يُنشأ أي مستند.",
    loginNotice: "سجّل الدخول أولاً لمتابعة الإجراءات المالية.",
    draftNote: "هذه النسخة معاينة للواجهة المالية. الأرصدة والصفوف التجريبية ليست بيانات حسابك الفعلية.",
    activity: "حركة الحساب",
    bills: "الفواتير",
    methods: "طرق الدفع",
    controls: "التحكم المالي",
    all: "الكل",
    income: "إيداع",
    expense: "خصم",
    sampleData: "بيانات تجريبية",
    transaction: "وصف المعاملة",
    reference: "الرقم المرجعي",
    date: "التاريخ",
    amount: "المبلغ",
    status: "الحالة",
    success: "ناجحة",
    paid: "مدفوعة",
    refunded: "مُستردّة",
    invoiceTitle: "المستندات والفواتير المالية",
    invoiceSubTitle: "تُحفظ عروض الأسعار والفواتير وإيصالات الخدمات في هذا القسم.",
    viewSample: "عرض نموذج",
    noRealInvoice: "لم تُسجَّل أي فاتورة فعلية لهذا الحساب بعد.",
    paymentMethodsTitle: "مسارات الدفع",
    paymentMethodsSub: "لا يحفظ شهداد بيانات البطاقة البنكية كاملة.",
    primaryMethod: "الطريقة الموصى بها",
    unavailable: "بانتظار الربط",
    manage: "إدارة",
    budgetTitle: "الميزانية والتنبيهات",
    monthlyBudget: "ميزانية الخدمات الشهرية",
    lowBalance: "تنبيه انخفاض الرصيد",
    invoiceEmail: "إرسال الفواتير عبر البريد الإلكتروني",
    autoCharge: "الشحن التلقائي",
    autoChargeHint: "يتاح بعد ربط بوابة الدفع والحصول على موافقة صريحة من المستخدم.",
    temporarySettings: "إعدادات هذه المعاينة مؤقتة ولا تُحفظ كبيانات مالية.",
    financeTools: "الأدوات المالية",
    refund: "طلب استرداد",
    export: "تصدير حركة الحساب",
    escrow: "حساب ضمان القضية",
    organization: "التسوية المؤسسية",
    toolNotice: "هذا المسار مصمم وسيُفعّل بعد ربط الخدمة المالية.",
    securityTitle: "نطاق الدفع الآمن",
    securityText: "لا يستلم شهداد بيانات البطاقة كاملة ولا يخزنها. يُعرض المبلغ النهائي بالتومان والريال قبل الانتقال إلى بوابة الدفع.",
    pluto: "بلوتو",
    hideBalance: "إخفاء الرصيد",
    showBalance: "إظهار الرصيد",
    hide: "إخفاء",
    show: "إظهار",
    serverSettlement: "لا تتم التسوية إلا بعد تحقق الخادم",
    currentPlan: "الخطة الحالية",
    dismiss: "إغلاق الرسالة",
    creditCode: "رمز رصيد شهداد",
    creditCodeSub: "تطبيق رصيد مكافأة أو رصيد مؤسسي موثّق من الخادم",
    budgetUsage: "استهلاك تجريبي بنسبة ٣٢٪ من الميزانية المحددة",
    lowBalanceHint: "عندما ينخفض الرصيد عن ٢٠٠٬٠٠٠ تومان",
    invoiceEmailHint: "بعد إصدار مستند فعلي",
  },
  en: {
    kicker: "Shahdad Financial Center",
    title: "Wallet & payments",
    subtitle: "Manage balance, account funding, activity and billing documents in one place.",
    guest: "Guest account",
    active: "Wallet ready for integration",
    guestHint: "Sign in to fund the wallet, receive official invoices and view real activity.",
    signIn: "Sign in and activate wallet",
    available: "Available balance",
    held: "Pending funds",
    credit: "Reward credit",
    dailyLimit: "Daily funding limit",
    chargeNow: "Fund account",
    balanceSource: "Balance appears only after a server-verified response.",
    chargeTitle: "Quick account funding",
    chargeSub: "Choose a suggested amount or enter a custom amount.",
    customAmount: "Custom amount",
    amountPlaceholder: "e.g. 500,000",
    toman: "Toman",
    rial: "Rial",
    gateway: "Bank gateway",
    invoice: "Organization deposit",
    gatewaySub: "Continue to the secure gateway after confirming the amount",
    invoiceSub: "Create a deposit request and organization invoice",
    payable: "Selected amount",
    gatewayAmount: "Gateway equivalent",
    continueGuest: "Sign in to continue",
    continueGateway: "Check gateway readiness",
    continueInvoice: "Check deposit-request readiness",
    invalidAmount: "Enter a whole, unsigned numeric amount.",
    minError: "The minimum funding amount is 100,000 Toman.",
    maxError: "The maximum amount per funding attempt is 50,000,000 Toman.",
    gatewayOffline: "The gateway is not connected yet. No money was charged and no transaction was created.",
    invoiceOffline: "Organization deposits are not connected to the finance backend. No document was created.",
    loginNotice: "Sign in to continue with financial actions.",
    draftNote: "This version is a financial UI preview. Sample rows and balances are not your real account data.",
    activity: "Activity",
    bills: "Invoices",
    methods: "Payment methods",
    controls: "Controls",
    all: "All",
    income: "Credits",
    expense: "Debits",
    sampleData: "UI sample",
    transaction: "Transaction",
    reference: "Reference",
    date: "Date",
    amount: "Amount",
    status: "Status",
    success: "Successful",
    paid: "Paid",
    refunded: "Refunded",
    invoiceTitle: "Financial documents and invoices",
    invoiceSubTitle: "Quotes, invoices and service receipts will be stored here.",
    viewSample: "View sample",
    noRealInvoice: "No real invoice has been recorded for this account yet.",
    paymentMethodsTitle: "Payment routes",
    paymentMethodsSub: "Shahdad never stores complete bank-card details.",
    primaryMethod: "Recommended",
    unavailable: "Pending connection",
    manage: "Manage",
    budgetTitle: "Budget and alerts",
    monthlyBudget: "Monthly service budget",
    lowBalance: "Low-balance alert",
    invoiceEmail: "Email invoices",
    autoCharge: "Automatic funding",
    autoChargeHint: "Available only after gateway integration and explicit user consent.",
    temporarySettings: "Preview settings are temporary and are not stored as financial data.",
    financeTools: "Financial tools",
    refund: "Request a refund",
    export: "Export activity",
    escrow: "Case escrow",
    organization: "Organization settlement",
    toolNotice: "This path is designed and will activate after finance-service integration.",
    securityTitle: "Secure payment boundary",
    securityText: "Shahdad does not receive or store complete card details. The final amount is shown in both Toman and Rial before gateway transfer.",
    pluto: "Pluto",
    hideBalance: "Hide balance",
    showBalance: "Show balance",
    hide: "Hide",
    show: "Show",
    serverSettlement: "Server-verified settlement only",
    currentPlan: "Current plan",
    dismiss: "Dismiss",
    creditCode: "Shahdad credit code",
    creditCodeSub: "Apply server-verified reward or organization credit",
    budgetUsage: "32% sample usage of the selected budget",
    lowBalanceHint: "When balance drops below 200,000 Toman",
    invoiceEmailHint: "After a real document is issued",
  },
};

const walletText = (lang, key) => (WALLET_COPY[lang] || WALLET_COPY.en)[key] || WALLET_COPY.en[key] || key;
const walletLocale = (lang) => lang === "fa" ? "fa-IR" : lang === "ar" ? "ar-EG" : "en-US";
const walletFormatNumber = (value, lang) =>
  new Intl.NumberFormat(walletLocale(lang), { maximumFractionDigits: 0 }).format(Number(value) || 0);
const walletNormalizeDigits = (value) => String(value ?? "")
  .replace(/[۰-۹]/g, (digit) => "۰۱۲۳۴۵۶۷۸۹".indexOf(digit))
  .replace(/[٠-٩]/g, (digit) => "٠١٢٣٤٥٦٧٨٩".indexOf(digit));
const walletParseAmount = (value) => {
  const normalized = walletNormalizeDigits(value).trim();
  if (!normalized) return 0;
  const digitsOnly = /^\d+$/.test(normalized);
  const grouped = /^\d{1,3}(?:[,\u066c ]\d{3})+$/.test(normalized);
  if (!digitsOnly && !grouped) return Number.NaN;
  const digits = normalized.replace(/[,\u066c ]/g, "");
  const amount = Number(digits);
  return Number.isSafeInteger(amount) ? amount : Number.NaN;
};
const walletFormatMoney = (value, lang) => `${walletFormatNumber(value, lang)} ${walletText(lang, "toman")}`;

const getWalletSummary = (session) => {
  // The current session is browser-persisted and cannot be a financial authority.
  // Keep every balance unknown until a server-owned wallet endpoint is integrated.
  return {
    availableBalance: null,
    heldBalance: null,
    rewardCredit: null,
    source: "unavailable",
    isGuest: !session || session.isGuest,
  };
};

const WALLET_DEMO_TRANSACTIONS = [
  { id: "SHD-CHG-10428", kind: "income", title: { fa: "شارژ کیف پول", ar: "شحن المحفظة", en: "Wallet funding" }, amount: 500000, date: { fa: "۱۴۰۵/۰۴/۲۱ · ۱۰:۴۲", ar: "٢٠٢٦/٠٧/١٢ · ١٠:٤٢", en: "2026-07-12 · 10:42" }, status: "success" },
  { id: "SHD-CNS-10411", kind: "expense", title: { fa: "رزرو مشاوره متنی", ar: "حجز استشارة نصية", en: "Text consultation booking" }, amount: -180000, date: { fa: "۱۴۰۵/۰۴/۱۹ · ۱۶:۱۰", ar: "٢٠٢٦/٠٧/١٠ · ١٦:١٠", en: "2026-07-10 · 16:10" }, status: "paid" },
  { id: "SHD-CNT-10386", kind: "expense", title: { fa: "تحلیل قرارداد", ar: "تحليل عقد", en: "Contract analysis" }, amount: -350000, date: { fa: "۱۴۰۵/۰۴/۱۷ · ۰۹:۲۵", ar: "٢٠٢٦/٠٧/٠٨ · ٠٩:٢٥", en: "2026-07-08 · 09:25" }, status: "paid" },
  { id: "SHD-RFD-10352", kind: "income", title: { fa: "بازگشت وجه مشاوره", ar: "استرداد مبلغ الاستشارة", en: "Consultation refund" }, amount: 180000, date: { fa: "۱۴۰۵/۰۴/۱۴ · ۱۲:۰۸", ar: "٢٠٢٦/٠٧/٠٥ · ١٢:٠٨", en: "2026-07-05 · 12:08" }, status: "refunded" },
];

const WALLET_DEMO_INVOICES = [
  { id: "INV-1405-0182", title: { fa: "پیش‌فاکتور مشاوره تخصصی", ar: "عرض سعر لاستشارة متخصصة", en: "Specialist consultation quote" }, amount: 790000, date: { fa: "۱۴۰۵/۰۴/۲۱", ar: "٢٠٢٦/٠٧/١٢", en: "2026-07-12" }, kind: { fa: "پیش‌فاکتور", ar: "عرض سعر", en: "Quote" } },
  { id: "INV-1405-0174", title: { fa: "فاکتور تحلیل قرارداد", ar: "فاتورة تحليل عقد", en: "Contract analysis invoice" }, amount: 350000, date: { fa: "۱۴۰۵/۰۴/۱۷", ar: "٢٠٢٦/٠٧/٠٨", en: "2026-07-08" }, kind: { fa: "فاکتور", ar: "فاتورة", en: "Invoice" } },
  { id: "INV-1405-0161", title: { fa: "رسید رزرو جلسه", ar: "إيصال حجز جلسة", en: "Session booking receipt" }, amount: 180000, date: { fa: "۱۴۰۵/۰۴/۱۴", ar: "٢٠٢٦/٠٧/٠٥", en: "2026-07-05" }, kind: { fa: "رسید", ar: "إيصال", en: "Receipt" } },
];

const WALLET_AR_PLAN_NAMES = {
  pluto: "بلوتو",
  moon: "القمر",
  earth: "الأرض",
  sun: "الشمس",
  constellation: "المنظومة",
  galaxy: "المجرة",
};

const WalletCenterView = ({ lang = "fa", session, onRequireAuth }) => {
  const summary = getWalletSummary(session);
  const currentPlan = window.ShahdadPlans?.getCurrentPlan?.(session);
  const currentPlanName = currentPlan
    ? (lang === "ar" ? WALLET_AR_PLAN_NAMES[currentPlan.id] || window.ShahdadPlans.localize(lang, currentPlan.name) : window.ShahdadPlans.localize(lang, currentPlan.name))
    : walletText(lang, "pluto");
  const [tab, setTab] = React.useState("activity");
  const [filter, setFilter] = React.useState("all");
  const [quickAmount, setQuickAmount] = React.useState(500000);
  const [customAmount, setCustomAmount] = React.useState("");
  const [method, setMethod] = React.useState("gateway");
  const [amountTouched, setAmountTouched] = React.useState(false);
  const [feedback, setFeedback] = React.useState(null);
  const [showBalance, setShowBalance] = React.useState(true);
  const [monthlyBudget, setMonthlyBudget] = React.useState("3000000");
  const [lowBalanceAlert, setLowBalanceAlert] = React.useState(true);
  const [invoiceEmail, setInvoiceEmail] = React.useState(true);
  const amountInputRef = React.useRef(null);
  const tabListRef = React.useRef(null);
  const customValue = walletParseAmount(customAmount);
  const hasCustomAmount = customAmount.trim().length > 0;
  const selectedAmount = hasCustomAmount && Number.isFinite(customValue) ? customValue : hasCustomAmount ? 0 : quickAmount;
  const amountError = hasCustomAmount && !Number.isFinite(customValue)
    ? walletText(lang, "invalidAmount")
    : selectedAmount < WALLET_CENTER_CONFIG.minCharge
    ? walletText(lang, "minError")
    : selectedAmount > WALLET_CENTER_CONFIG.maxCharge
      ? walletText(lang, "maxError")
      : "";
  const filteredTransactions = WALLET_DEMO_TRANSACTIONS.filter((item) => filter === "all" || item.kind === filter);
  const chargeInputId = React.useId();
  const chargeHelpId = React.useId();
  const notice = (kind, text) => setFeedback({ kind, text });

  const handleCharge = (event) => {
    event.preventDefault();
    setAmountTouched(true);
    if (amountError) {
      notice("error", amountError);
      amountInputRef.current?.focus();
      return;
    }
    if (summary.isGuest) {
      notice("info", walletText(lang, "loginNotice"));
      if (onRequireAuth) onRequireAuth();
      return;
    }
    notice(
      "warning",
      method === "invoice" ? walletText(lang, "invoiceOffline") : walletText(lang, "gatewayOffline"),
    );
  };

  const handleCustomAmount = (event) => {
    setCustomAmount(event.currentTarget.value);
    setAmountTouched(false);
    setFeedback(null);
  };

  const openFinancialTool = () => notice("info", walletText(lang, "toolNotice"));
  const statusLabel = (status) => walletText(lang, status);
  const tabItems = [
    { id: "activity", icon: "clock", label: walletText(lang, "activity") },
    { id: "bills", icon: "doc", label: walletText(lang, "bills") },
    { id: "methods", icon: "card", label: walletText(lang, "methods") },
    { id: "controls", icon: "settings", label: walletText(lang, "controls") },
  ];
  const selectTabFromKeyboard = (event) => {
    if (!["ArrowRight", "ArrowLeft", "Home", "End"].includes(event.key)) return;
    event.preventDefault();
    const currentIndex = tabItems.findIndex((item) => item.id === tab);
    let nextIndex = currentIndex;
    if (event.key === "Home") nextIndex = 0;
    if (event.key === "End") nextIndex = tabItems.length - 1;
    if (event.key === "ArrowRight") nextIndex = (currentIndex + (lang !== "en" ? -1 : 1) + tabItems.length) % tabItems.length;
    if (event.key === "ArrowLeft") nextIndex = (currentIndex + (lang !== "en" ? 1 : -1) + tabItems.length) % tabItems.length;
    const nextTab = tabItems[nextIndex].id;
    setTab(nextTab);
    window.requestAnimationFrame(() => {
      tabListRef.current?.querySelector(`[data-wallet-tab="${nextTab}"]`)?.focus();
    });
  };

  return (
    <div className="wallet-center">
      <section className="wc-hero" aria-labelledby="wallet-center-title">
        <div className="wc-hero-copy">
          <span className="wc-kicker"><Ic.coin size={15}/>{walletText(lang, "kicker")}</span>
          <h2 id="wallet-center-title">{walletText(lang, "title")}</h2>
          <p>{walletText(lang, "subtitle")}</p>
        </div>
        <div className={"wc-account-state " + (summary.isGuest ? "guest" : "active")}>
          <span><Ic.shieldCheck size={16}/>{summary.isGuest ? walletText(lang, "guest") : walletText(lang, "active")}</span>
          <small>{walletText(lang, "balanceSource")}</small>
        </div>
      </section>

      <div className="wc-draft-note" role="note">
        <Ic.info size={16}/>
        <span>{walletText(lang, "draftNote")}</span>
      </div>

      {summary.isGuest &&
      <section className="wc-auth-banner" aria-label={walletText(lang, "guest")}>
        <div className="wc-auth-icon"><Ic.shield size={22}/></div>
        <div>
          <strong>{walletText(lang, "guest")}</strong>
          <span>{walletText(lang, "guestHint")}</span>
        </div>
        <button type="button" className="wc-secondary-cta" onClick={() => onRequireAuth && onRequireAuth()}>
          {walletText(lang, "signIn")}<Ic.chevL size={15}/>
        </button>
      </section>}

      <section className="wc-primary-grid">
        <article className="wc-balance-card">
          <header>
            <div>
              <span>{walletText(lang, "available")}</span>
              <strong className="fa-num" aria-label={showBalance && Number.isFinite(summary.availableBalance) ? walletFormatMoney(summary.availableBalance, lang) : undefined}>
                {showBalance && Number.isFinite(summary.availableBalance) ? walletFormatNumber(summary.availableBalance, lang) : showBalance ? "—" : "••••••"}
                <small>{walletText(lang, "toman")}</small>
              </strong>
            </div>
            <button
              type="button"
              className="wc-visibility"
              aria-pressed={!showBalance}
              aria-label={showBalance ? walletText(lang, "hideBalance") : walletText(lang, "showBalance")}
              onClick={() => setShowBalance((current) => !current)}
            >
              {showBalance ? walletText(lang, "hide") : walletText(lang, "show")}
            </button>
          </header>
          <div className="wc-balance-metrics">
            <div><span>{walletText(lang, "held")}</span><b className="fa-num"><bdi dir="ltr">{showBalance && Number.isFinite(summary.heldBalance) ? walletFormatMoney(summary.heldBalance, lang) : showBalance ? "—" : "••••"}</bdi></b></div>
            <div><span>{walletText(lang, "credit")}</span><b className="fa-num"><bdi dir="ltr">{showBalance && Number.isFinite(summary.rewardCredit) ? walletFormatMoney(summary.rewardCredit, lang) : showBalance ? "—" : "••••"}</bdi></b></div>
            <div><span>{walletText(lang, "dailyLimit")}</span><b className="fa-num"><bdi dir="ltr">{walletFormatMoney(WALLET_CENTER_CONFIG.dailyChargeLimit, lang)}</bdi></b></div>
          </div>
          <div className="wc-balance-foot">
            <span><Ic.shieldCheck size={15}/>{walletText(lang, "serverSettlement")}</span>
            <span>{walletText(lang, "currentPlan")}: {currentPlanName}</span>
          </div>
        </article>

        <form className="wc-charge-card" onSubmit={handleCharge} noValidate>
          <header>
            <div>
              <h3>{walletText(lang, "chargeTitle")}</h3>
              <p>{walletText(lang, "chargeSub")}</p>
            </div>
            <Ic.plus size={20}/>
          </header>

          <div className="wc-quick-amounts" aria-label={walletText(lang, "chargeTitle")}>
            {WALLET_CENTER_CONFIG.quickAmounts.map((amount) =>
            <button
              type="button"
              key={amount}
              aria-pressed={!customAmount && quickAmount === amount}
              onClick={() => {
                setQuickAmount(amount);
                setCustomAmount("");
                setAmountTouched(false);
                setFeedback(null);
              }}
            >
              <b className="fa-num">{walletFormatNumber(amount, lang)}</b>
              <span>{walletText(lang, "toman")}</span>
            </button>)}
          </div>

          <div className={"wc-amount-field " + (amountTouched && amountError ? "has-error" : "")}>
            <label htmlFor={chargeInputId}>{walletText(lang, "customAmount")}</label>
            <div>
              <input
                ref={amountInputRef}
                id={chargeInputId}
                value={customAmount}
                onChange={handleCustomAmount}
                onBlur={() => {
                  setAmountTouched(true);
                  if (Number.isFinite(customValue) && customValue > 0) {
                    setCustomAmount(walletFormatNumber(customValue, lang));
                  }
                }}
                inputMode="numeric"
                autoComplete="off"
                placeholder={walletText(lang, "amountPlaceholder")}
                aria-invalid={amountTouched && Boolean(amountError)}
                aria-describedby={chargeHelpId}
              />
              <span>{walletText(lang, "toman")}</span>
            </div>
            <small id={chargeHelpId}>
              {amountTouched && amountError
                ? amountError
                : `${walletFormatMoney(WALLET_CENTER_CONFIG.minCharge, lang)} — ${walletFormatMoney(WALLET_CENTER_CONFIG.maxCharge, lang)}`}
            </small>
          </div>

          <fieldset className="wc-methods">
            <legend>{walletText(lang, "methods")}</legend>
            <button type="button" className={method === "gateway" ? "on" : ""} aria-pressed={method === "gateway"} onClick={() => setMethod("gateway")}>
              <Ic.card size={18}/><span><b>{walletText(lang, "gateway")}</b><small>{walletText(lang, "gatewaySub")}</small></span>
            </button>
            <button type="button" className={method === "invoice" ? "on" : ""} aria-pressed={method === "invoice"} onClick={() => setMethod("invoice")}>
              <Ic.building size={18}/><span><b>{walletText(lang, "invoice")}</b><small>{walletText(lang, "invoiceSub")}</small></span>
            </button>
          </fieldset>

          <div className="wc-charge-summary">
            <div><span>{walletText(lang, "payable")}</span><b className="fa-num">{walletFormatMoney(selectedAmount, lang)}</b></div>
            <div><span>{walletText(lang, "gatewayAmount")}</span><b className="fa-num">{walletFormatNumber(selectedAmount * 10, lang)} {walletText(lang, "rial")}</b></div>
          </div>

          <button type="submit" className="wc-primary-cta">
            {summary.isGuest
              ? walletText(lang, "continueGuest")
              : method === "invoice"
                ? walletText(lang, "continueInvoice")
                : walletText(lang, "continueGateway")}
            <Ic.chevL size={16}/>
          </button>
        </form>
      </section>

      {feedback &&
      <div className={"wc-feedback " + feedback.kind} role={feedback.kind === "error" ? "alert" : "status"} aria-live="polite">
        {feedback.kind === "error" ? <Ic.shieldAlert size={17}/> : <Ic.info size={17}/>}
        <span>{feedback.text}</span>
        <button type="button" onClick={() => setFeedback(null)} aria-label={walletText(lang, "dismiss")}><Ic.close size={15}/></button>
      </div>}

      <div ref={tabListRef} className="wc-tabs" role="tablist" aria-label={walletText(lang, "title")}>
        {tabItems.map((item) => {
          const Icon = Ic[item.icon] || Ic.coin;
          return (
            <button
              type="button"
              key={item.id}
              role="tab"
              id={`wallet-tab-${item.id}`}
              aria-selected={tab === item.id}
              aria-controls={tab === item.id ? `wallet-panel-${item.id}` : undefined}
              tabIndex={tab === item.id ? 0 : -1}
              data-wallet-tab={item.id}
              className={tab === item.id ? "on" : ""}
              onClick={() => setTab(item.id)}
              onKeyDown={selectTabFromKeyboard}
            >
              <Icon size={16}/><span>{item.label}</span>
            </button>
          );
        })}
      </div>

      <section className="wc-tab-panel" role="tabpanel" id={`wallet-panel-${tab}`} aria-labelledby={`wallet-tab-${tab}`}>
        {tab === "activity" &&
        <div className="wc-activity">
          <div className="wc-section-head">
            <div><h3>{walletText(lang, "activity")}</h3><p>{walletText(lang, "draftNote")}</p></div>
            <div className="wc-filters" aria-label={walletText(lang, "activity")}>
              {["all", "income", "expense"].map((item) =>
              <button type="button" key={item} className={filter === item ? "on" : ""} aria-pressed={filter === item} onClick={() => setFilter(item)}>
                {walletText(lang, item)}
              </button>)}
            </div>
          </div>
          <div className="wc-table-wrap" tabIndex="0" aria-label={walletText(lang, "activity")}>
            <table className="wc-table">
              <thead><tr>
                <th>{walletText(lang, "transaction")}</th>
                <th>{walletText(lang, "reference")}</th>
                <th>{walletText(lang, "date")}</th>
                <th>{walletText(lang, "amount")}</th>
                <th>{walletText(lang, "status")}</th>
              </tr></thead>
              <tbody>
                {filteredTransactions.map((item) =>
                <tr key={item.id}>
                  <td data-label={walletText(lang, "transaction")}><span className={"wc-transaction-icon " + item.kind}>{item.kind === "income" ? <Ic.plus size={14}/> : <Ic.chevL size={14}/>}</span><div><b>{item.title[lang] || item.title.en}</b><small>{walletText(lang, "sampleData")}</small></div></td>
                  <td data-label={walletText(lang, "reference")} className="wc-reference"><bdi dir="ltr">{item.id}</bdi></td>
                  <td data-label={walletText(lang, "date")} className="fa-num"><bdi dir="ltr">{item.date[lang] || item.date.en}</bdi></td>
                  <td data-label={walletText(lang, "amount")} className={"wc-amount " + item.kind}><bdi dir="ltr">{item.amount > 0 ? "+" : "−"}{walletFormatMoney(Math.abs(item.amount), lang)}</bdi></td>
                  <td data-label={walletText(lang, "status")}><span className={"wc-status " + item.status}>{statusLabel(item.status)}</span></td>
                </tr>)}
              </tbody>
            </table>
          </div>
        </div>}

        {tab === "bills" &&
        <div className="wc-bills">
          <div className="wc-section-head">
            <div><h3>{walletText(lang, "invoiceTitle")}</h3><p>{walletText(lang, "invoiceSubTitle")}</p></div>
            <span className="wc-empty-label">{walletText(lang, "noRealInvoice")}</span>
          </div>
          <div className="wc-invoice-grid">
            {WALLET_DEMO_INVOICES.map((invoice) =>
            <article key={invoice.id}>
              <div className="wc-invoice-icon"><Ic.doc size={20}/></div>
              <div><span>{invoice.kind[lang] || invoice.kind.en}</span><h4>{invoice.title[lang] || invoice.title.en}</h4><small className="fa-num"><bdi dir="ltr">{invoice.id} · {invoice.date[lang] || invoice.date.en}</bdi></small></div>
              <b className="fa-num"><bdi dir="ltr">{walletFormatMoney(invoice.amount, lang)}</bdi></b>
              <button type="button" aria-label={`${walletText(lang, "viewSample")}: ${invoice.title[lang] || invoice.title.en}`} onClick={openFinancialTool}>{walletText(lang, "viewSample")}</button>
            </article>)}
          </div>
        </div>}

        {tab === "methods" &&
        <div className="wc-payment-methods">
          <div className="wc-section-head">
            <div><h3>{walletText(lang, "paymentMethodsTitle")}</h3><p>{walletText(lang, "paymentMethodsSub")}</p></div>
          </div>
          <div className="wc-method-grid">
            <article className="primary">
              <div><Ic.card size={22}/><span>{walletText(lang, "primaryMethod")}</span></div>
              <h4>{walletText(lang, "gateway")}</h4>
              <p>{walletText(lang, "gatewaySub")}</p>
              <small><i></i>{walletText(lang, "unavailable")}</small>
              <button type="button" aria-label={`${walletText(lang, "manage")}: ${walletText(lang, "gateway")}`} onClick={openFinancialTool}>{walletText(lang, "manage")}</button>
            </article>
            <article>
              <div><Ic.building size={22}/></div>
              <h4>{walletText(lang, "invoice")}</h4>
              <p>{walletText(lang, "invoiceSub")}</p>
              <small><i></i>{walletText(lang, "unavailable")}</small>
              <button type="button" aria-label={`${walletText(lang, "manage")}: ${walletText(lang, "invoice")}`} onClick={openFinancialTool}>{walletText(lang, "manage")}</button>
            </article>
            <article>
              <div><Ic.shieldCheck size={22}/></div>
              <h4>{walletText(lang, "creditCode")}</h4>
              <p>{walletText(lang, "creditCodeSub")}</p>
              <small><i></i>{walletText(lang, "unavailable")}</small>
              <button type="button" aria-label={`${walletText(lang, "manage")}: ${walletText(lang, "creditCode")}`} onClick={openFinancialTool}>{walletText(lang, "manage")}</button>
            </article>
          </div>
        </div>}

        {tab === "controls" &&
        <div className="wc-controls-grid">
          <article className="wc-budget-card">
            <header><div><h3>{walletText(lang, "budgetTitle")}</h3><p>{walletText(lang, "temporarySettings")}</p></div><Ic.barchart size={20}/></header>
            <label>
              <span>{walletText(lang, "monthlyBudget")}</span>
              <div>
                <input
                  value={monthlyBudget}
                  inputMode="numeric"
                  aria-label={walletText(lang, "monthlyBudget")}
                  onChange={(event) => setMonthlyBudget(event.currentTarget.value)}
                  onBlur={() => {
                    const parsed = walletParseAmount(monthlyBudget);
                    if (Number.isFinite(parsed) && parsed > 0) setMonthlyBudget(walletFormatNumber(parsed, lang));
                  }}
                />
                <b>{walletText(lang, "toman")}</b>
              </div>
            </label>
            <div className="wc-budget-bar" aria-label={walletText(lang, "monthlyBudget")}><span style={{width:"32%"}}></span></div>
            <small>{walletText(lang, "budgetUsage")}</small>
            <div className="wc-switch-list">
              <button type="button" role="switch" aria-checked={lowBalanceAlert} onClick={() => setLowBalanceAlert((value) => !value)}><span><b>{walletText(lang, "lowBalance")}</b><small>{walletText(lang, "lowBalanceHint")}</small></span><i className={lowBalanceAlert ? "on" : ""}></i></button>
              <button type="button" role="switch" aria-checked={invoiceEmail} onClick={() => setInvoiceEmail((value) => !value)}><span><b>{walletText(lang, "invoiceEmail")}</b><small>{walletText(lang, "invoiceEmailHint")}</small></span><i className={invoiceEmail ? "on" : ""}></i></button>
              <button type="button" role="switch" aria-checked={false} disabled><span><b>{walletText(lang, "autoCharge")}</b><small>{walletText(lang, "autoChargeHint")}</small></span><i></i></button>
            </div>
          </article>

          <article className="wc-tools-card">
            <header><div><h3>{walletText(lang, "financeTools")}</h3><p>{walletText(lang, "toolNotice")}</p></div><Ic.calc size={20}/></header>
            <div>
              {[
                ["refund", "shieldAlert", walletText(lang, "refund")],
                ["export", "doc", walletText(lang, "export")],
                ["escrow", "shieldCheck", walletText(lang, "escrow")],
                ["organization", "building", walletText(lang, "organization")],
              ].map(([id, icon, label]) => {
                const Icon = Ic[icon] || Ic.coin;
                return <button type="button" key={id} onClick={openFinancialTool}><span><Icon size={17}/></span><b>{label}</b><Ic.chevL size={14}/></button>;
              })}
            </div>
          </article>
        </div>}
      </section>

      <footer className="wc-security-note">
        <Ic.shieldCheck size={19}/>
        <div><strong>{walletText(lang, "securityTitle")}</strong><span>{walletText(lang, "securityText")}</span></div>
      </footer>
    </div>
  );
};

window.ShahdadWallet = Object.freeze({
  config: WALLET_CENTER_CONFIG,
  getSummary: getWalletSummary,
  parseAmount: walletParseAmount,
  formatMoney: walletFormatMoney,
});
window.WalletCenterView = WalletCenterView;
