(() => {
// U05 — consolidated settlements, management-fee payments, collection rules, operational report results. Fictional data.
const NS = window.AmlakPlusDesignSystem_b3aa85;
const { PageHeader, SummaryStrip, Money, StatusBadge, Button, Tabs, DataTable, Alert, Dialog, Field, Select, TextInput, Checkbox, SaveStatus, StateView, KeyValueList, SegmentedControl, Icon } = NS;
const D = window.AP_DATA;
const val = (e) => (e && e.target ? (e.target.type === 'checkbox' ? e.target.checked : e.target.value) : e);
const fmt = (n) => Number(n || 0).toLocaleString('en-US', { maximumFractionDigits: 2 });
const go = (r, p) => window.apGo && window.apGo(r, p);
const ownerAcc = (oid) => [{ value: 'oa-' + oid, label: 'حساب المالك — ' + ((D.owners.find((o) => o.id === oid) || {}).name || '') }];
const officeAcc = D.accounts.filter((a) => a.recipient === 'office').map((a) => ({ value: a.label, label: a.label }));

function useSave(onSaved) {
  const [state, setState] = React.useState('idle');
  return [state, (fn) => { setState('saving'); setTimeout(() => { fn && fn(); setState('saved'); setTimeout(onSaved, 400); }, 800); }];
}
const Foot = ({ state, onClose, step, setStep, label, onNext, danger }) => <><SaveStatus state={state} /><div style={{ display: 'flex', gap: 8 }}>{step === 'review' ? <Button variant="secondary" onClick={() => setStep('form')} disabled={state === 'saving'}>تعديل</Button> : <Button variant="secondary" onClick={onClose} disabled={state === 'saving'}>إلغاء</Button>}<Button variant={danger ? 'danger' : 'primary'} loading={state === 'saving'} onClick={onNext}>{label}</Button></div></>;

// ---------- G6 · Consolidated settlement: batch by period ----------
D.settleSources = D.settleSources || {
  o1: [{ id: 's1', label: 'عمارة الندى 3 / 204 — خالد العتيبي', opening: 0, movement: 3000, available: 3000 }, { id: 's2', label: 'عمارة الندى 3 / 101 — فيصل الشمري', opening: 3000, movement: 3000, available: 6000 }, { id: 's3', label: 'عمارة الياسمين 7 / 102 — ناصر القحطاني', opening: 0, movement: 3000, available: 3000 }],
  o2: [{ id: 's4', label: 'عمارة الملقا 12 / 301 — ريم الشهري', opening: 0, movement: 2500, available: 2500 }],
  o3: [], o4: [{ id: 's5', label: 'عمارة الحمراء / 2 — ماجد العمري', opening: 1200, movement: 2400, available: 3600 }]
};
function SettlementBatchDialog({ onClose, onSaved }) {
  const [owner, setOwner] = React.useState('o1');
  const [v, setV] = React.useState({ from: '2026-09-01', to: '2026-09-23', source: '', destination: '', note: '' });
  const src = D.settleSources[owner] || [];
  const [pick, setPick] = React.useState({});
  const row = (s) => pick[s.id] || { use: true, amount: String(s.available) };
  const [step, setStep] = React.useState('form');
  const [tried, setTried] = React.useState(false);
  const [state, save] = useSave(onSaved);
  const set = (k) => (e) => setV((x) => ({ ...x, [k]: val(e) }));
  const setRow = (s, k) => (e) => setPick((p) => ({ ...p, [s.id]: { ...row(s), [k]: val(e) } }));
  const chosen = src.filter((s) => row(s).use);
  const over = chosen.filter((s) => !(Number(row(s).amount) > 0) || Number(row(s).amount) > s.available);
  const total = chosen.reduce((t, s) => t + (Number(row(s).amount) || 0), 0);
  const bad = !chosen.length || over.length || !v.source || !v.destination || v.note.trim().length < 2 || v.from > v.to;
  const o = D.owners.find((x) => x.id === owner);
  const next = () => { setTried(true); if (bad) return; if (step === 'form') return setStep('review'); save(() => { D.settlements = [{ id: 'st' + Date.now(), owner: o.name, ownerId: owner, period: 'سبتمبر 2026', collected: total, deductions: 0, fee: 0, net: total, delivered: 0, status: 'draft' }, ...D.settlements]; }); };
  return (
    <Dialog title={step === 'review' ? 'معاينة مسودة التصفية' : 'تصفية مجمعة حسب فترة'} subtitle={o.name} width={720} onClose={onClose} busy={state === 'saving'}
      footer={<Foot state={state} onClose={onClose} step={step} setStep={setStep} onNext={next} label={step === 'review' ? 'إنشاء المسودة' : 'معاينة المسودة'} />}>
      {step === 'review' ? <div style={{ display: 'grid', gap: 14 }}>
        <KeyValueList layout="rows" items={[{ label: 'المالك', value: o.name, strong: true }, { label: 'الفترة', value: <bdi className="ap-num">{v.from.split('-').reverse().join('/')} – {v.to.split('-').reverse().join('/')}</bdi> }, { label: 'من حساب', value: v.source }, { label: 'إلى حساب', value: v.destination }, { label: 'البيان', value: v.note }]} />
        <DataTable caption="بنود المسودة" rows={chosen} footer columns={[{ key: 'l', header: 'المصدر', render: (s) => s.label, footer: 'الإجمالي' }, { key: 'a', header: 'المبلغ', numeric: true, render: (s) => <Money value={Number(row(s).amount)} />, footer: <Money value={total} /> }]} />
        <Alert tone="neutral">تُنشأ مسودة فقط. التمويل والأتعاب غير المسددة تُراجع في المسودة، ثم الاعتماد، ثم التسليم كخطوة مستقلة.</Alert>
      </div> : <div style={{ display: 'grid', gap: 14 }}>
        <div className="kit-form">
          <Field label="المالك" className="is-full"><Select value={owner} onChange={(e) => { setOwner(val(e)); setPick({}); }} options={D.owners.map((x) => ({ value: x.id, label: x.name }))} /></Field>
          <Field label="الفترة من" required><TextInput type="date" value={v.from} max={v.to} onChange={set('from')} /></Field>
          <Field label="إلى" required error={v.from > v.to ? 'قبل تاريخ البداية' : undefined}><TextInput type="date" value={v.to} max="2026-09-23" onChange={set('to')} /></Field>
          <Field label="حساب دفع المكتب" required error={tried && !v.source ? 'اختر الحساب' : undefined}><Select value={v.source} onChange={set('source')} placeholder="اختر الحساب" options={officeAcc} /></Field>
          <Field label="حساب استلام المالك" required error={tried && !v.destination ? 'اختر الحساب' : undefined}><Select value={v.destination} onChange={set('destination')} placeholder="اختر الحساب" options={ownerAcc(owner).map((a) => ({ value: a.label, label: a.label }))} /></Field>
        </div>
        <p className="kit-scope" style={{ margin: 0 }}>تُجمع الحركات المرحّلة حتى نهاية الفترة مع الرصيد السابق، بحد أقصى المتاح الآن. المصروف المدفوع من الرصيد مخصوم بالفعل.</p>
        {!src.length ? <StateView boxed kind="empty" icon="HandCoins" title="لا رصيد متاح للتصفية" text="لا حركات مطابقة لملكية هذا المالك برصيد موجب." /> : <DataTable caption="مصادر الرصيد" rows={src} columns={[
          { key: 'u', header: 'المصدر', render: (s) => <Checkbox label={s.label} checked={row(s).use} onChange={setRow(s, 'use')} /> },
          { key: 'o', header: 'مرحل سابق', numeric: true, render: (s) => <Money value={s.opening} tone={s.opening ? undefined : 'muted'} /> },
          { key: 'm', header: 'حركة الفترة', numeric: true, render: (s) => <Money value={s.movement} /> },
          { key: 'a', header: 'المبلغ للتصفية', render: (s) => <div style={{ width: 120 }}><TextInput ltr inputMode="decimal" disabled={!row(s).use} aria-label={'المبلغ — ' + s.label} value={row(s).amount} onChange={setRow(s, 'amount')} />{row(s).use && over.includes(s) ? <small className="kit-f-missing">بين 0.01 و {fmt(s.available)}</small> : <small style={{ color: 'var(--text-3)' }}>متاح {fmt(s.available)}</small>}</div> }
        ]} />}
        <Field label="بيان التصفية" required error={tried && v.note.trim().length < 2 ? 'مطلوب' : undefined}><TextInput value={v.note} onChange={set('note')} placeholder="مثال: تصفية سبتمبر 2026" /></Field>
        {src.length > 0 && <div className="kit-due-banner"><span>إجمالي المسودة</span><Money value={total} size="lg" /></div>}
      </div>}
    </Dialog>
  );
}

// ---------- G7 · Management-fee payments ----------
D.fees = D.fees || [
  { id: 'mf1', ownerId: 'o1', period: 'يوليو 2026', amount: 2250, paid: 2250 }, { id: 'mf2', ownerId: 'o1', period: 'أغسطس 2026', amount: 2400, paid: 900 }, { id: 'mf3', ownerId: 'o1', period: 'سبتمبر 2026', amount: 2300, paid: 0 },
  { id: 'mf4', ownerId: 'o2', period: 'أغسطس 2026', amount: 1500, paid: 0 }, { id: 'mf5', ownerId: 'o4', period: 'أغسطس 2026', amount: 1800, paid: 1800 }
];
D.feePayments = D.feePayments || [
  { id: 'fp1', ownerId: 'o1', date: '05/08/2026', amount: 2250, ref: 'TRX-7781', status: 'PAID', doc: 'MF-000014' },
  { id: 'fp2', ownerId: 'o1', date: '10/09/2026', amount: 900, ref: 'TRX-8012', status: 'PAID', doc: 'MF-000019' },
  { id: 'fp3', ownerId: 'o4', date: '02/09/2026', amount: 1800, ref: 'شيك 4410', status: 'PAID', doc: 'MF-000017' },
  { id: 'fp4', ownerId: 'o2', date: '01/09/2026', amount: 1500, ref: 'TRX-7990', status: 'REVERSED', doc: 'MF-000016', reason: 'الحوالة مرتجعة من البنك' }
];
const oname = (id) => (D.owners.find((o) => o.id === id) || {}).name;
const feeLeft = (oid) => D.fees.filter((f) => f.ownerId === oid).reduce((s, f) => s + f.amount - f.paid, 0);
function allocateFees(oid, amount) { let left = amount; const out = []; D.fees.filter((f) => f.ownerId === oid && f.amount > f.paid).forEach((f) => { if (left <= 0) return; const t = Math.min(f.amount - f.paid, left); out.push({ f, take: t }); left -= t; }); return { out, extra: left }; }

function FeePaymentDialog({ mode, row, onClose, onSaved }) {
  const [v, setV] = React.useState({ owner: '', amount: '', source: '', dest: '', ref: '', reason: '', ok: false });
  const [step, setStep] = React.useState('form');
  const [tried, setTried] = React.useState(false);
  const [state, save] = useSave(onSaved);
  const set = (k) => (e) => setV((x) => ({ ...x, [k]: val(e), ...(k === 'owner' ? { source: '' } : {}) }));
  const amt = Number(v.amount) || 0, left = v.owner ? feeLeft(v.owner) : 0, al = allocateFees(v.owner, amt);
  if (mode === 'reverse') {
    const bad = v.reason.trim().length < 3 || !v.ok;
    return <Dialog title="عكس سداد الأتعاب" subtitle={oname(row.ownerId) + ' · ' + row.doc} width={520} onClose={onClose} busy={state === 'saving'}
      footer={<Foot state={state} onClose={onClose} onNext={() => { setTried(true); if (bad) return; save(() => { D.feePayments = D.feePayments.map((p) => p.id === row.id ? { ...p, status: 'REVERSED', reason: v.reason } : p); let back = row.amount; D.fees.filter((f) => f.ownerId === row.ownerId).reverse().forEach((f) => { const t = Math.min(f.paid, back); f.paid -= t; back -= t; }); }); }} label="عكس السداد" danger />}>
      <div style={{ display: 'grid', gap: 14 }}>
        <Alert tone="danger">يُعكس قيدا السداد وتعود الأتعاب إلى الرصيد المستحق على المالك. لا ينفذ ردًا بنكيًا.</Alert>
        <div className="kit-f-summary"><div><span>المبلغ</span><Money value={row.amount} size="md" /></div><div><span>التاريخ</span><b>{row.date}</b></div><div><span>المرجع</span><b>{row.ref}</b></div></div>
        <Field label="سبب التصحيح" required error={tried && v.reason.trim().length < 3 ? 'مطلوب' : undefined}><TextInput multiline rows={2} value={v.reason} onChange={set('reason')} /></Field>
        <Checkbox label="أعتمد عكس قيدي السداد وإعادة الأتعاب إلى الرصيد المستحق." checked={v.ok} onChange={set('ok')} />
      </div></Dialog>;
  }
  const errs = { owner: !v.owner, amount: !amt, source: !v.source, dest: !v.dest, ref: v.ref.trim().length < 2 };
  const bad = Object.values(errs).some(Boolean) || !v.ok;
  const next = () => { setTried(true); if (bad) return; if (step === 'form') return setStep('review'); save(() => { al.out.forEach((x) => { x.f.paid += x.take; }); D.feePayments = [{ id: 'fp' + Date.now(), ownerId: v.owner, date: D.today, amount: amt, ref: v.ref, status: 'PAID', doc: 'MF-0000' + (20 + D.feePayments.length) }, ...D.feePayments]; }); };
  return (
    <Dialog title={step === 'review' ? 'مراجعة سداد الأتعاب' : 'تسجيل سداد الأتعاب'} subtitle="مبلغ دفعه المالك للمكتب مباشرة" width={640} onClose={onClose} busy={state === 'saving'}
      footer={<Foot state={state} onClose={onClose} step={step} setStep={setStep} onNext={next} label={step === 'review' ? 'تسجيل السداد' : 'مراجعة'} />}>
      {step === 'review' ? <div style={{ display: 'grid', gap: 14 }}>
        <KeyValueList layout="rows" items={[{ label: 'المالك', value: oname(v.owner), strong: true }, { label: 'المبلغ', value: <Money value={amt} size="md" /> }, { label: 'من حساب المالك', value: v.source }, { label: 'إلى حساب المكتب', value: v.dest }, { label: 'المرجع', value: v.ref }, { label: 'التاريخ', value: D.today }]} />
        <DataTable caption="التوزيع على الأتعاب" rows={al.out.map((x) => ({ id: x.f.id, period: x.f.period, take: x.take, after: x.f.amount - x.f.paid - x.take }))} columns={[{ key: 'p', header: 'الفترة', render: (r) => r.period }, { key: 't', header: 'يُخصم', numeric: true, render: (r) => <Money value={r.take} /> }, { key: 'a', header: 'المتبقي بعده', numeric: true, render: (r) => <Money value={r.after} tone={r.after ? 'warning' : 'muted'} /> }]} />
        {al.extra > 0 && <Alert tone="warning">المبلغ يزيد عن الأتعاب المستحقة بـ {fmt(al.extra)} ر.س — راجع المبلغ قبل التسجيل.</Alert>}
        <Alert tone="neutral">لا يكرر إيراد الأتعاب ولا يغيّر مدفوعات المستأجرين. يصدر سند أتعاب إدارة.</Alert>
      </div> : <div style={{ display: 'grid', gap: 14 }}>
        <div className="kit-form">
          <Field label="المالك" required className="is-full" error={tried && errs.owner ? 'اختر المالك' : undefined}><Select value={v.owner} onChange={set('owner')} placeholder="اختر المالك" options={D.owners.map((o) => ({ value: o.id, label: o.name }))} /></Field>
          <Field label="المبلغ المستلم" required error={tried && errs.amount ? 'مطلوب' : undefined} hint={v.owner ? 'المستحق على المالك: ' + fmt(left) + ' ر.س · يوزع على الأقدم أولًا' : undefined}><TextInput ltr inputMode="decimal" value={v.amount} onChange={set('amount')} placeholder="0" /></Field>
          <Field label="مرجع إثبات السداد" required error={tried && errs.ref ? 'مطلوب' : undefined}><TextInput value={v.ref} onChange={set('ref')} /></Field>
          <Field label="حساب دفع المالك" required error={tried && errs.source ? 'اختر الحساب' : undefined}><Select value={v.source} onChange={set('source')} placeholder={v.owner ? 'اختر الحساب' : 'اختر المالك أولًا'} disabled={!v.owner} options={v.owner ? ownerAcc(v.owner).map((a) => ({ value: a.label, label: a.label })) : []} /></Field>
          <Field label="حساب استلام المكتب" required error={tried && errs.dest ? 'اختر الحساب' : undefined}><Select value={v.dest} onChange={set('dest')} placeholder="اختر الحساب" options={officeAcc} /></Field>
        </div>
        <Checkbox label="راجعت الحسابين وأؤكد استلام المبلغ بالفعل. التسجيل بتاريخ اليوم." checked={v.ok} onChange={set('ok')} />
        {tried && !v.ok && <span className="kit-f-missing">أكّد قبل المتابعة.</span>}
      </div>}
    </Dialog>
  );
}
function ManagementFees({ tab }) {
  const [dlg, setDlg] = React.useState(null);
  const [, tick] = React.useState(0);
  const owed = D.owners.map((o) => ({ id: o.id, name: o.name, total: D.fees.filter((f) => f.ownerId === o.id).reduce((s, f) => s + f.amount, 0), left: feeLeft(o.id), rows: D.fees.filter((f) => f.ownerId === o.id) })).filter((o) => o.total);
  return (
    <div style={{ display: 'grid', gap: 14 }}>
      <SummaryStrip items={[
        { label: 'أتعاب مستحقة غير مسددة', amount: owed.reduce((s, o) => s + o.left, 0), tone: 'warning', note: owed.filter((o) => o.left).length + ' ملاك' },
        { label: 'سُدد مباشرة — سبتمبر', amount: D.feePayments.filter((p) => p.status === 'PAID' && p.date.includes('/09/')).reduce((s, p) => s + p.amount, 0), tone: 'success', note: 'من حسابات الملاك' },
        { label: 'معكوس', amount: D.feePayments.filter((p) => p.status === 'REVERSED').reduce((s, p) => s + p.amount, 0), tone: 'neutral', note: 'محفوظ للأثر' }
      ]} />
      {tab === 'fees' ? <DataTable caption="الأتعاب حسب المالك" rows={owed} footer columns={[
        { key: 'o', header: 'المالك', render: (o) => <><span className="ap-cell-strong">{o.name}</span><small>{o.rows.map((f) => f.period.split(' ')[0] + (f.amount > f.paid ? (f.paid ? ' (جزئي)' : '') : ' ✓')).join(' · ')}</small></>, footer: 'الإجمالي' },
        { key: 't', header: 'الأتعاب المستحقة', numeric: true, render: (o) => <Money value={o.total} />, footer: <Money value={owed.reduce((s, o) => s + o.total, 0)} /> },
        { key: 'l', header: 'المتبقي', numeric: true, render: (o) => <Money value={o.left} tone={o.left ? 'danger' : 'muted'} />, footer: <Money value={owed.reduce((s, o) => s + o.left, 0)} tone="danger" /> },
        { key: 'a', header: <span className="ap-sr-only">إجراءات</span>, render: (o) => <div className="kit-acts">{o.left > 0 && <Button size="sm" variant="secondary" icon="Banknote" onClick={() => setDlg({ mode: 'record' })}>تسجيل سداد</Button>}</div> }
      ]} /> : <section className="kit-group" style={{ marginBottom: 0 }}>
        <header><h2>سداد المالك للأتعاب مباشرة<span className="kit-count">{D.feePayments.length}</span></h2><p>التصحيح بالعكس فقط؛ السند الأصلي يبقى.</p><Button size="sm" icon="Plus" onClick={() => setDlg({ mode: 'record' })}>تسجيل سداد الأتعاب</Button></header>
        <DataTable caption="سدادات الأتعاب" rows={D.feePayments} columns={[
          { key: 'o', header: 'المالك', render: (p) => oname(p.ownerId) },
          { key: 'd', header: 'التاريخ', render: (p) => <bdi className="ap-num">{p.date}</bdi> },
          { key: 'a', header: 'المبلغ', numeric: true, render: (p) => <Money value={p.amount} struck={p.status === 'REVERSED'} /> },
          { key: 'r', header: 'المرجع', render: (p) => <>{p.ref}{p.reason && <small>عُكس: {p.reason}</small>}</> },
          { key: 's', header: 'الحالة', render: (p) => <StatusBadge size="sm" status={p.status === 'PAID' ? 'paid' : 'reversed'} /> },
          { key: 'x', header: <span className="ap-sr-only">إجراءات</span>, render: (p) => <div className="kit-acts"><Button size="sm" variant="secondary" icon="Printer" onClick={() => window.open('../../print/documents.html#fee', '_blank')}>السند</Button>{p.status === 'PAID' && <Button size="sm" variant="ghost" onClick={() => setDlg({ mode: 'reverse', row: p })}>تصحيح بالعكس</Button>}</div> }
        ]} />
      </section>}
      {dlg && <FeePaymentDialog {...dlg} onClose={() => setDlg(null)} onSaved={() => { setDlg(null); tick((x) => x + 1); }} />}
    </div>
  );
}

// ---------- G8 · Collection posting rules ----------
D.books = D.books || [{ id: 'b0', name: 'دفتر المكتب', opening: true }, { id: 'b1', name: 'دفتر المالك — عبدالله السبيعي', opening: true }, { id: 'b2', name: 'دفتر المالك — هيا الدوسري', opening: false }];
D.ledgerAcc = { debit: ['1101 — حساب المكتب — الراجحي', '1102 — صندوق المكتب — نقد', '1201 — حساب المالك — السبيعي'], credit: ['1301 — ذمم المستأجرين', '2101 — مستحقات الملاك', '4101 — إيراد الإيجار', '2201 — إيجار مقبوض مقدمًا'] };
D.rules = D.rules || [
  { id: 'r1', book: 'b1', lease: 'l1', debit: '1201 — حساب المالك — السبيعي', credit: '1301 — ذمم المستأجرين', from: '01/01/2026', desc: 'تحصيل إيجار — عمارة الندى 3 / 204', enabled: true, versions: [{ v: 2, on: 'تفعيل', credit: '1301 — ذمم المستأجرين', at: '01/03/2026 · منيرة', desc: 'تغيير الحساب المقابل بعد تفعيل الاستحقاق' }, { v: 1, on: 'تفعيل', credit: '4101 — إيراد الإيجار', at: '05/01/2026 · منيرة', desc: 'الإصدار الأول' }] },
  { id: 'r2', book: 'b0', lease: 'l6', debit: '1102 — صندوق المكتب — نقد', credit: '2101 — مستحقات الملاك', from: '01/06/2026', desc: 'قبض نقدي لصالح المالك — الندى 3 / 201', enabled: false, versions: [{ v: 2, on: 'إيقاف', credit: '2101 — مستحقات الملاك', at: '15/09/2026 · أحمد', desc: 'إيقاف مؤقت حتى مطابقة العهدة' }, { v: 1, on: 'تفعيل', credit: '2101 — مستحقات الملاك', at: '01/06/2026 · أحمد', desc: 'الإصدار الأول' }] }
];
const leaseLabel = (id) => { const l = D.leases.find((x) => x.id === id); return l ? l.tenant + ' · ' + l.property + ' / ' + l.unit : id; };
function RuleDialog({ book, onClose, onSaved }) {
  const [v, setV] = React.useState({ lease: '', debit: '', credit: '', from: '2026-09-23', desc: '', enabled: true, ok: false });
  const [tried, setTried] = React.useState(false);
  const [state, save] = useSave(onSaved);
  const set = (k) => (e) => setV((x) => ({ ...x, [k]: val(e) }));
  const prev = D.rules.find((r) => r.book === book.id && r.lease === v.lease && r.debit === v.debit);
  const errs = { lease: !v.lease, debit: !v.debit, credit: !v.credit, desc: v.desc.trim().length < 5 };
  const next = () => { setTried(true); if (Object.values(errs).some(Boolean) || !v.ok) return; save(() => {
    const ver = { v: prev ? prev.versions[0].v + 1 : 1, on: v.enabled ? 'تفعيل' : 'إيقاف', credit: v.credit, at: D.today + ' · ' + D.user.name.split(' ')[0], desc: v.desc };
    if (prev) Object.assign(prev, { credit: v.credit, from: v.from.split('-').reverse().join('/'), desc: v.desc, enabled: v.enabled, versions: [ver, ...prev.versions] });
    else D.rules = [{ id: 'r' + Date.now(), book: book.id, lease: v.lease, debit: v.debit, credit: v.credit, from: v.from.split('-').reverse().join('/'), desc: v.desc, enabled: v.enabled, versions: [ver] }, ...D.rules]; }); };
  return (
    <Dialog title="إعداد قاعدة ترحيل أو إصدار جديد" subtitle={book.name} width={680} onClose={onClose} busy={state === 'saving'}
      footer={<Foot state={state} onClose={onClose} onNext={next} label="اعتماد الإصدار" />}>
      <div style={{ display: 'grid', gap: 14 }}>
        <div className="kit-form">
          <Field label="العقد" required className="is-full" error={tried && errs.lease ? 'اختر العقد' : undefined}><Select value={v.lease} onChange={set('lease')} placeholder="اختر العقد" options={D.leases.filter((l) => l.status === 'active').map((l) => ({ value: l.id, label: leaseLabel(l.id) }))} /></Field>
          <Field label="حساب الاستلام — مدين" required error={tried && errs.debit ? 'اختر الحساب' : undefined}><Select value={v.debit} onChange={set('debit')} placeholder="اختر الحساب" options={D.ledgerAcc.debit} /></Field>
          <Field label="الحساب المقابل — دائن" required error={tried && errs.credit ? 'اختر الحساب' : undefined} hint="حسب سياستك المحاسبية — النظام لا يقرر بدلًا منك."><Select value={v.credit} onChange={set('credit')} placeholder="اختر الحساب" options={D.ledgerAcc.credit} /></Field>
          <Field label="أقدم تاريخ دفع تقبله القاعدة" required><TextInput type="date" value={v.from} max="2026-09-23" onChange={set('from')} /></Field>
          <Field label="بيان القيد" required error={tried && errs.desc ? '5 أحرف على الأقل' : undefined}><TextInput value={v.desc} onChange={set('desc')} placeholder="تحصيل إيجار — العقار / الوحدة" /></Field>
        </div>
        <div className="kit-f-summary"><div><span>معاينة لكل 1,000 ر.س — مدين</span><b>{v.debit || 'حساب الاستلام'} · 1,000</b></div><div><span>دائن</span><b>{v.credit || 'الحساب المقابل'} · 1,000</b></div></div>
        <Alert tone={prev ? 'info' : 'neutral'}>{prev ? 'يوجد إصدار ' + prev.versions[0].v + ' لهذا العقد والحساب؛ الحفظ ينشئ الإصدار ' + (prev.versions[0].v + 1) + ' ويحفظ تاريخ القديم.' : 'سيُنشأ الإصدار الأول لهذا العقد والحساب.'} يسري على الدفعات الجديدة بعد الاعتماد فقط.</Alert>
        <Checkbox label="تفعيل الترحيل التلقائي" hint="إلغاء الاختيار يحفظ إصدارًا يوقف الأتمتة." checked={v.enabled} onChange={set('enabled')} />
        <Checkbox label="راجعت جهة الدفتر والعقد والحساب المقابل وأعتمد تطبيق هذا الإصدار على الدفعات الجديدة." checked={v.ok} onChange={set('ok')} />
        {tried && !v.ok && <span className="kit-f-missing">الاعتماد مطلوب.</span>}
      </div>
    </Dialog>
  );
}
function CollectionRulesScreen() {
  const [bookId, setBook] = React.useState('b1');
  const [open, setOpen] = React.useState(false);
  const [exp, setExp] = React.useState('');
  const [, tick] = React.useState(0);
  const book = D.books.find((b) => b.id === bookId);
  const rows = D.rules.filter((r) => r.book === bookId);
  return (
    <>
      <PageHeader title="قواعد ترحيل التحصيل" description="قاعدة لكل عقد وحساب استلام. عند تأكيد دفعة مطابقة: المبلغ كاملًا مدين لحساب الاستلام ودائن للحساب المقابل."
        actions={<Button icon="Plus" disabled={!book.opening} onClick={() => setOpen(true)}>قاعدة أو إصدار جديد</Button>} />
      <div className="kit-toolbar"><Field label="الدفتر" style={{ minWidth: 280 }}><Select value={bookId} onChange={(e) => setBook(val(e))} options={D.books.map((b) => ({ value: b.id, label: b.name }))} /></Field></div>
      {!book.opening ? <StateView boxed kind="empty" icon="BookOpen" title="اعتمد الافتتاحية أولًا" text="القواعد تُعد بعد اعتماد أرصدة افتتاح هذا الدفتر." actions={<Button variant="secondary" onClick={() => go('books')}>فتح الدفاتر</Button>} />
        : !rows.length ? <StateView boxed kind="empty" icon="Settings2" title="لا قواعد معتمدة" text="التحصيلات تُجهَّز كمسودات قيود للمراجعة حتى تُعد قاعدة." />
        : <DataTable caption="القواعد" rows={rows} columns={[
          { key: 'l', header: 'العقد', render: (r) => <><span className="ap-cell-strong">{leaseLabel(r.lease)}</span><small>{r.desc}</small></> },
          { key: 'd', header: 'مدين ← دائن', render: (r) => <>{r.debit}<small>← {r.credit}</small></> },
          { key: 'f', header: 'من تاريخ دفع', render: (r) => <bdi className="ap-num">{r.from}</bdi> },
          { key: 'v', header: 'الإصدار', render: (r) => <button type="button" className="kit-src" onClick={() => setExp(exp === r.id ? '' : r.id)}>الإصدار {r.versions[0].v} · السجل</button> },
          { key: 's', header: 'الحالة', render: (r) => <StatusBadge size="sm" tone={r.enabled ? 'success' : 'neutral'} label={r.enabled ? 'مفعّل' : 'متوقف'} /> }
        ]} />}
      {rows.filter((r) => r.id === exp).map((r) => <div key={r.id} className="kit-panel" style={{ marginTop: 12 }}><h3 className="kit-h2" style={{ marginTop: 0 }}>سجل إصدارات — {leaseLabel(r.lease)}</h3><NS.Timeline events={r.versions.map((x) => ({ title: 'إصدار ' + x.v + ' — ' + x.on, date: x.at, icon: 'Settings2', tone: x.on === 'إيقاف' ? 'warning' : 'success', body: 'دائن: ' + x.credit + ' · ' + x.desc }))} /></div>)}
      <p className="kit-scope">القاعدة لا تحسب عمولات أو ضرائب. الفترات المقفلة والدفعات السابقة للاعتماد تبقى للمراجعة اليدوية.</p>
      {open && <RuleDialog book={book} onClose={() => setOpen(false)} onSaved={() => { setOpen(false); tick((x) => x + 1); }} />}
    </>
  );
}

// ---------- G9 · Operational report results ----------
const P = D.properties.map((p) => p.name);
const OPS = {
  aging: { title: 'أعمار الديون (المتأخرات)', icon: 'Clock', desc: 'المتأخر على المستأجرين حسب عمر الدين.', asOf: true, cols: [{ l: 'المستأجر' }, { l: 'العقار / الوحدة', g: 1 }, { l: '0–30', n: 1 }, { l: '31–60', n: 1 }, { l: '61–90', n: 1 }, { l: '+90', n: 1 }, { l: 'الإجمالي', n: 1, t: 1 }],
    rows: [['خالد العتيبي', 'عمارة الندى 3 / 204', 3000, 3000, 0, 0, 6000, 'l1'], ['مؤسسة ركن البناء', 'مجمع الربيع التجاري / محل 3', 0, 0, 13500, 0, 13500, 'l2'], ['سلطان الزهراني', 'عمارة السلي 2 / 305', 0, 2200, 0, 0, 2200, 'l4'], ['سعد الحارثي', 'عمارة الندى 3 / 201', 2000, 0, 0, 0, 2000, 'l6']],
    sums: (r) => [{ label: 'إجمالي المتأخر', amount: r.reduce((s, x) => s + x[6], 0), tone: 'danger' }, { label: 'أكثر من 60 يومًا', amount: r.reduce((s, x) => s + x[4] + x[5], 0), tone: 'warning', note: 'يحتاج إجراءً' }, { label: 'مستأجرون', value: r.length, tone: 'neutral' }] },
  collections: { title: 'التحصيل حسب الفترة', icon: 'ReceiptText', desc: 'الدفعات المؤكدة خلال الفترة، والمعلقة منفصلة.', cols: [{ l: 'التاريخ' }, { l: 'المستأجر' }, { l: 'العقار', g: 1 }, { l: 'الطريقة والجهة' }, { l: 'السند' }, { l: 'المبلغ', n: 1, t: 1 }],
    rows: [['04/09/2026', 'فيصل الشمري', 'عمارة الندى 3', 'تحويل · حساب المكتب', 'RC-000131', 3000], ['05/09/2026', 'عمر باسل', 'عمارة الندى 3', 'نقد · عهدة سارة', 'RC-000127', 2500], ['10/09/2026', 'ياسر المالكي', 'عمارة الندى 3', 'تحويل للمالك', 'RC-000133', 3333.33], ['16/09/2026', 'سعد الحارثي', 'عمارة الندى 3', 'نقد · عهدة سارة', 'RC-000135', 1500], ['18/09/2026', 'مؤسسة ركن البناء', 'مجمع الربيع التجاري', 'شيك · حساب المكتب', 'RC-000138', 13500]],
    sums: (r) => [{ label: 'مؤكد في الفترة', amount: r.reduce((s, x) => s + x[5], 0), tone: 'success', note: r.length + ' سندات' }, { label: 'بانتظار التحقق', amount: 5700, tone: 'neutral', note: 'لا يدخل في المؤكد' }, { label: 'مباشرة للمالك', amount: 3333.33, tone: 'info', note: 'ليست بحوزة المكتب' }] },
  occupancy: { title: 'الإشغال والشواغر', icon: 'DoorOpen', desc: 'الوحدات المؤجرة والشاغرة لكل عقار حتى اليوم.', asOf: true, cols: [{ l: 'العقار', g: 1 }, { l: 'الوحدات', n: 1, c: 1, t: 1 }, { l: 'مؤجرة', n: 1, c: 1, t: 1 }, { l: 'شاغرة', n: 1, c: 1, t: 1 }, { l: 'نسبة الإشغال', n: 1 }, { l: 'أقدم شاغر' }],
    rows: D.properties.map((p, i) => [p.name, p.units, p.occupied, p.units - p.occupied, Math.round(p.occupied / p.units * 100) + '%', p.units - p.occupied ? ['15/08/2026', '01/09/2026', '—', '20/07/2026', '01/09/2026', '—'][i] : '—']),
    sums: (r) => { const u = r.reduce((s, x) => s + x[1], 0), o = r.reduce((s, x) => s + x[2], 0); return [{ label: 'نسبة الإشغال', value: Math.round(o / u * 100) + '%', tone: 'brand', note: o + ' من ' + u }, { label: 'وحدات شاغرة', value: u - o, tone: 'warning' }, { label: 'عقارات', value: r.length, tone: 'neutral' }]; } },
  leases: { title: 'العقود المنتهية والمتجددة', icon: 'FileText', desc: 'ما انتهى أو جُدد أو ينتهي خلال الفترة.', cols: [{ l: 'المستأجر' }, { l: 'العقار / الوحدة', g: 1 }, { l: 'الانتهاء' }, { l: 'الحالة', s: 1 }, { l: 'الإيجار السنوي', n: 1, t: 1 }],
    rows: [['سلطان الزهراني', 'عمارة السلي 2 / 305', '31/08/2026', ['ended', 'انتهى — رصيد قائم'], 26400, 'l4'], ['ناصر القحطاني', 'عمارة الياسمين 7 / 102', '30/09/2026', ['due', 'ينتهي خلال 7 أيام'], 36000, 'l3'], ['ريم الشهري', 'عمارة الملقا 12 / 301', '31/10/2026', ['due', 'ينتهي خلال 38 يومًا'], 30000, 'l7'], ['فيصل الشمري', 'عمارة الندى 3 / 101', '31/08/2026', ['active', 'جُدد حتى 31/08/2027'], 36000]],
    sums: (r) => [{ label: 'انتهت', value: r.filter((x) => x[3][0] === 'ended').length, tone: 'neutral' }, { label: 'جُددت', value: r.filter((x) => x[3][0] === 'active').length, tone: 'success' }, { label: 'تنتهي قريبًا', value: r.filter((x) => x[3][0] === 'due').length, tone: 'warning', note: 'راجع إيجار قبل الانتهاء' }] },
  expenses: { title: 'المصروفات حسب العقار', icon: 'Wallet', desc: 'المصروفات المدفوعة والمعتمدة وجهة تمويلها.', cols: [{ l: 'التاريخ' }, { l: 'العقار', g: 1 }, { l: 'البند' }, { l: 'التمويل' }, { l: 'المبلغ', n: 1, t: 1 }],
    rows: [['03/09/2026', 'عمارة الندى 3', 'صيانة مكيف — 201', 'من رصيد المالك', 450], ['08/09/2026', 'عمارة الندى 3', 'فاتورة كهرباء المرافق', 'من رصيد المالك', 1320], ['12/09/2026', 'عمارة الياسمين 7', 'تنظيف الخزانات', 'تمويل مقدم من المكتب', 800], ['19/09/2026', 'مجمع الربيع التجاري', 'إصلاح باب المحل 3', 'دفع مباشر من المالك', 1200]],
    sums: (r) => [{ label: 'إجمالي المصروفات', amount: r.reduce((s, x) => s + x[4], 0), tone: 'brand' }, { label: 'من رصيد المالك', amount: r.filter((x) => x[3] === 'من رصيد المالك').reduce((s, x) => s + x[4], 0), tone: 'neutral', note: 'مخصوم في التصفية' }, { label: 'تمويل من المكتب', amount: r.filter((x) => x[3].includes('المكتب')).reduce((s, x) => s + x[4], 0), tone: 'warning', note: 'يُسترد لاحقًا' }] }
};
function OperationalReportScreen({ kind }) {
  const R = OPS[kind] || OPS.aging;
  const [f, setF] = React.useState({ from: '2026-09-01', to: '2026-09-23', prop: '', owner: '', group: 'property' });
  const [note, setNote] = React.useState('');
  const set = (k) => (e) => setF((x) => ({ ...x, [k]: val(e) }));
  const gi = R.cols.findIndex((c) => c.g);
  const ownerProps = f.owner ? D.properties.filter((p) => p.ownerId === f.owner).map((p) => p.name) : null;
  const rows = R.rows.filter((r) => (!f.prop || String(r[gi]).startsWith(f.prop)) && (!ownerProps || ownerProps.some((n) => String(r[gi]).startsWith(n))));
  const invalid = f.from > f.to;
  const cell = (c, x) => c.s ? <StatusBadge size="sm" status={x[0]} label={x[1]} /> : c.n && typeof x === 'number' ? (c.c ? fmt(x) : <Money value={x} tone={x ? undefined : 'muted'} />) : x;
  const groups = f.group === 'none' ? [['', rows]] : Object.entries(rows.reduce((m, r) => { const k = f.group === 'owner' ? (oname((D.properties.find((p) => String(r[gi]).startsWith(p.name)) || {}).ownerId) || '—') : String(r[gi]).split(' / ')[0]; (m[k] = m[k] || []).push(r); return m; }, {}));
  const tIdx = R.cols.map((c, i) => c.t ? i : -1).filter((i) => i >= 0);
  const tot = (rs, i) => rs.reduce((s, r) => s + (Number(r[i]) || 0), 0);
  const cols = (rs) => R.cols.map((c, i) => ({ key: 'c' + i, header: c.l, numeric: !!c.n, render: (r) => i === 0 && r[R.cols.length] ? <><span className="ap-cell-strong">{r[0]}</span><small><button type="button" className="kit-src" onClick={() => go('lease', { id: r[R.cols.length] })}>فتح العقد</button></small></> : cell(c, r[i]), footer: i === 0 ? 'الإجمالي' : tIdx.includes(i) ? (c.c ? fmt(tot(rs, i)) : <Money value={tot(rs, i)} />) : undefined }));
  return (
    <>
      <PageHeader title={R.title} description={R.desc} actions={<><Button variant="secondary" icon="Download" disabled={invalid || !rows.length} onClick={() => setNote('نُزّل الملف ' + kind + '-2026-09.csv بترميز UTF-8.')}>CSV</Button><Button icon="Printer" disabled={invalid || !rows.length} onClick={() => window.open('../../print/documents.html#report', '_blank')}>طباعة</Button></>} />
      <div className="kit-toolbar">
        {R.asOf ? <Field label="حتى تاريخ"><TextInput type="date" value={f.to} max="2026-09-23" onChange={set('to')} /></Field> : <><Field label="من"><TextInput type="date" value={f.from} max={f.to} onChange={set('from')} /></Field><Field label="إلى" error={invalid ? 'قبل تاريخ البداية' : undefined}><TextInput type="date" value={f.to} max="2026-09-23" onChange={set('to')} /></Field></>}
        <Field label="العقار"><Select value={f.prop} onChange={set('prop')} placeholder="كل العقارات" options={P} /></Field>
        <Field label="المالك"><Select value={f.owner} onChange={set('owner')} placeholder="كل الملاك" options={D.owners.map((o) => ({ value: o.id, label: o.name }))} /></Field>
        <SegmentedControl label="التجميع" value={f.group} onChange={set('group')} options={[{ value: 'property', label: 'حسب العقار' }, { value: 'owner', label: 'حسب المالك' }, { value: 'none', label: 'بدون' }]} />
      </div>
      {note && <Alert tone="success" onDismiss={() => setNote('')} style={{ marginBottom: 12 }}>{note}</Alert>}
      {invalid ? <StateView boxed kind="error" title="راجع الفترة" text="تاريخ النهاية قبل البداية. تقارير الأرصدة حتى اليوم فقط." />
        : !rows.length ? <StateView boxed kind="empty" icon="SearchX" title="لا نتائج لهذه المرشحات" text="غيّر العقار أو المالك أو الفترة." actions={<Button variant="secondary" onClick={() => setF((x) => ({ ...x, prop: '', owner: '' }))}>مسح المرشحات</Button>} />
        : <>
          <SummaryStrip items={R.sums(rows)} />
          <p className="kit-scope">{D.org} · {R.asOf ? 'حتى ' + f.to.split('-').reverse().join('/') : 'من ' + f.from.split('-').reverse().join('/') + ' إلى ' + f.to.split('-').reverse().join('/')} · {rows.length} صفوف</p>
          {groups.map(([g, rs]) => <section key={g || 'all'} className="kit-group">{g && <header><h2>{g}<span className="kit-count">{rs.length}</span></h2></header>}<DataTable caption={R.title + (g ? ' — ' + g : '')} rows={rs.map((r, i) => ({ ...r, id: g + i }))} footer={tIdx.length > 0} columns={cols(rs)} /></section>)}
        </>}
    </>
  );
}
function OperationalReportCards() {
  return <><h2 className="kit-h2">التقارير التشغيلية</h2><div className="kit-cards">{Object.entries(OPS).map(([k, r]) => <article key={k} className="kit-card">
    <div style={{ display: 'flex', gap: 12, alignItems: 'flex-start' }}><span className="kit-card__icon"><Icon name={r.icon} size={20} /></span><div><h3>{r.title}</h3><p style={{ display: 'block' }}>{r.desc}</p></div></div>
    <div><Button size="sm" variant="secondary" icon="Eye" onClick={() => go('opreport', { id: k })}>عرض التقرير</Button></div></article>)}</div><h2 className="kit-h2">التقارير المحاسبية</h2></>;
}

Object.assign(window, { SettlementBatchDialog, ManagementFees, CollectionRulesScreen, OperationalReportScreen, OperationalReportCards, OPS_REPORTS: OPS });
})();
