// app.jsx — main app shell: state, mode toggle (Admin desktop / Tenant mobile)

const { useState: _, useEffect: __, useMemo: ___, useCallback: ____, useRef: _____ } = React;

// ═════════════════════════════════════════════════════════════
// Tweaks defaults
// ═════════════════════════════════════════════════════════════
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "primary": "#C2563A",
  "density": "regular",
  "lang": "ro",
  "dark": false,
  "aptView": "card",
  "fontScale": "normal"
}/*EDITMODE-END*/;

// Palette presets — keyed by hex so TweakColor matching works
const PALETTES = {
  '#C2563A': { primary: '#C2563A', primaryHover: '#A8482F', primaryLight: '#F8E7DE', accent: '#7A8B5F' }, // terracotta
  '#5C8B68': { primary: '#5C8B68', primaryHover: '#4A7355', primaryLight: '#E5EFE3', accent: '#C2563A' }, // sage
  '#C68A2E': { primary: '#C68A2E', primaryHover: '#A87422', primaryLight: '#F8EAC5', accent: '#5C8B68' }, // ochre
  '#5B5DD3': { primary: '#5B5DD3', primaryHover: '#4A4BBD', primaryLight: '#E7E7FA', accent: '#C2563A' }, // indigo
};

// Font scale for accessibility (esp. 60+ users)
const FONT_SCALES = {
  small:  { base: 13, label_ro: 'Mic' },
  normal: { base: 14, label_ro: 'Normal' },
  large:  { base: 16, label_ro: 'Mare' },
  xlarge: { base: 19, label_ro: 'Foarte mare' },
};

const DENSITIES = {
  compact:  { padCard: 18, gap: 10, navItem: 38, rowH: 44 },
  regular:  { padCard: 24, gap: 14, navItem: 44, rowH: 52 },
  comfy:    { padCard: 30, gap: 18, navItem: 50, rowH: 60 },
};

// ═════════════════════════════════════════════════════════════
// App state — apartments, expenses, charges, payments
// ═════════════════════════════════════════════════════════════
function useAppState() {
  const [apartments, setApartments] = React.useState(window.APARTMENTS);
  const [expenses, setExpenses]     = React.useState(window.EXPENSES_NOV);
  const [readings, setReadings]     = React.useState(window.METER_READINGS);
  const [listStatus, setListStatus] = React.useState('draft'); // draft | calculating | published
  const [charges, setCharges]       = React.useState({});      // computed on demand
  const [payments, setPayments]     = React.useState(window.INITIAL_PAYMENTS);
  const [notifSent, setNotifSent]   = React.useState(false);
  const [issues, setIssues]         = React.useState(window.ISSUES);
  const [proposals, setProposals]   = React.useState(window.AGA_PROPOSALS);
  const [announcements, setAnnouncements] = React.useState(window.ANNOUNCEMENTS);
  const [emergencies, setEmergencies] = React.useState(window.EMERGENCIES);
  const [activeEmergency, setActiveEmergency] = React.useState(null);
  const [vault, setVault] = React.useState(window.VAULT);
  const [vaultTx, setVaultTx] = React.useState(window.VAULT_TRANSACTIONS);
  // Current user signer (for tenant viewing as committee member, etc.)
  const [currentSigner, setCurrentSigner] = React.useState('s1'); // default: admin

  // compute charges = per-apartment amount due, with breakdown by category
  // Each breakdown entry includes the formula explanation for transparency
  const calcCharges = React.useCallback((opts = {}) => {
    const out = {};
    const apts = apartments.filter(a => a.is_active);

    for (const a of apts) {
      out[a.id] = { breakdown: {}, total: 0, _apt: a, excluded: {} };
    }

    for (const e of expenses) {
      const cat = window.CATEGORIES.find(c => c.id === e.category_id);
      if (!cat) continue;

      // Filter to only apartments that participate in this category
      const participating = apts.filter(a => window.aptParticipates(a, cat).participates);
      const totalSqm = participating.reduce((s, a) => s + (a.surface_mp || 0), 0);
      const totalPersons = participating.reduce((s, a) => s + (a.persons_count || 1), 0);

      // Track exclusions for transparency
      for (const a of apts) {
        const part = window.aptParticipates(a, cat);
        if (!part.participates) {
          out[a.id].excluded[cat.id] = part.reason;
        }
      }

      const dist = e.distribution || cat.distribution;
      const amt = parseFloat(e.amount);

      if (dist === 'per_apartment') {
        const share = amt / participating.length;
        const formula = `${window.fmtRONshort(amt)} ÷ ${participating.length} apt = ${share.toFixed(2)}`;
        participating.forEach(a => {
          const prev = out[a.id].breakdown[cat.id];
          out[a.id].breakdown[cat.id] = {
            amount: (prev?.amount || 0) + share,
            formula,
            category: cat,
          };
        });
      } else if (dist === 'per_person') {
        participating.forEach(a => {
          const share = (a.persons_count / totalPersons) * amt;
          const formula = `${a.persons_count} pers. × (${window.fmtRONshort(amt)} ÷ ${totalPersons} pers.) = ${share.toFixed(2)}`;
          const prev = out[a.id].breakdown[cat.id];
          out[a.id].breakdown[cat.id] = {
            amount: (prev?.amount || 0) + share,
            formula,
            category: cat,
          };
        });
      } else if (dist === 'per_sqm') {
        participating.forEach(a => {
          const share = (a.surface_mp / totalSqm) * amt;
          const formula = `${a.surface_mp} m² ÷ ${totalSqm} m² × ${window.fmtRONshort(amt)} = ${share.toFixed(2)}`;
          const prev = out[a.id].breakdown[cat.id];
          out[a.id].breakdown[cat.id] = {
            amount: (prev?.amount || 0) + share,
            formula,
            category: cat,
          };
        });
      } else if (dist === 'per_consumption') {
        participating.forEach(a => {
          const r = readings[a.id];
          if (!r) return;
          const cold = r.cold_curr - r.cold_prev;
          const hot = r.hot_curr - r.hot_prev;
          let share = 0, formula = '';
          if (cat.id === 'c1') {
            share = cold * window.UTIL_COST.cold;
            formula = `${cold.toFixed(3)} m³ × ${window.UTIL_COST.cold.toFixed(2)} RON/m³ = ${share.toFixed(2)}`;
          }
          if (cat.id === 'c2') {
            share = hot * window.UTIL_COST.hot;
            formula = `${hot.toFixed(3)} m³ × ${window.UTIL_COST.hot.toFixed(2)} RON/m³ = ${share.toFixed(2)}`;
          }
          const prev = out[a.id].breakdown[cat.id];
          out[a.id].breakdown[cat.id] = {
            amount: (prev?.amount || 0) + share,
            formula,
            category: cat,
          };
        });
      }
    }

    for (const id of Object.keys(out)) {
      out[id].total = Object.values(out[id].breakdown).reduce((s, v) => s + (v.amount || 0), 0);
    }
    return out;
  }, [apartments, expenses, readings]);

  // initial compute on mount
  React.useEffect(() => {
    setCharges(calcCharges());
  }, []);

  const totals = React.useMemo(() => {
    const totalExpense = expenses.reduce((s, e) => s + parseFloat(e.amount), 0);
    const totalDue = Object.values(charges).reduce((s, c) => s + (c.total || 0), 0);
    const totalPaid = payments.reduce((s, p) => s + (p.amount_paid || 0), 0);
    return { totalExpense, totalDue, totalPaid };
  }, [expenses, charges, payments]);

  // apartment status
  const aptStatus = React.useCallback((aptId) => {
    const due = charges[aptId]?.total || 0;
    const paid = payments.filter(p => p.apt === aptId).reduce((s, p) => s + p.amount_paid, 0);
    if (paid <= 0) return { status: 'unpaid', due, paid, balance: due };
    if (paid >= due - 0.5) return { status: 'paid', due, paid, balance: 0 };
    return { status: 'partial', due, paid, balance: due - paid };
  }, [charges, payments]);

  return {
    apartments, setApartments,
    expenses, setExpenses,
    readings, setReadings,
    listStatus, setListStatus,
    charges, setCharges, calcCharges,
    payments, setPayments,
    notifSent, setNotifSent,
    totals,
    aptStatus,
    // sesizări + AGA + announcements
    issues, setIssues,
    proposals, setProposals,
    announcements, setAnnouncements,
    emergencies, setEmergencies,
    activeEmergency, setActiveEmergency,
    vault, setVault,
    vaultTx, setVaultTx,
    currentSigner, setCurrentSigner,
  };
}

// ═════════════════════════════════════════════════════════════
// Mode toggle (Admin / Locatar)
// ═════════════════════════════════════════════════════════════
function ModeToggle({ mode, setMode, lang }) {
  const T = window.I18N[lang];
  return (
    <div style={{
      position: 'fixed', top: 20, left: '50%', transform: 'translateX(-50%)',
      zIndex: 70,
      display: 'inline-flex', padding: 4, gap: 2,
      background: 'rgba(255,255,255,0.85)',
      backdropFilter: 'blur(20px) saturate(180%)',
      border: '1px solid rgba(28, 22, 12, 0.08)',
      borderRadius: 999,
      boxShadow: '0 4px 16px rgba(28, 22, 12, 0.12), 0 1px 0 rgba(255,255,255,0.7) inset',
    }}>
      {[
        { id: 'admin', label: T['mode.admin'], icon: 'sliders' },
        { id: 'tenant', label: T['mode.tenant'], icon: 'user' },
      ].map(opt => {
        const active = mode === opt.id;
        return (
          <button key={opt.id} onClick={() => setMode(opt.id)} style={{
            padding: '8px 18px', borderRadius: 999, border: 0,
            background: active ? 'var(--primary)' : 'transparent',
            color: active ? '#fff' : '#3a2f1e',
            fontFamily: 'inherit', fontSize: 13.5, fontWeight: 600,
            cursor: 'pointer', display: 'inline-flex', alignItems: 'center', gap: 7,
            transition: 'background 200ms ease, color 200ms ease',
          }}>
            <Icon name={opt.icon} size={15} />
            {opt.label}
          </button>
        );
      })}
    </div>
  );
}

// ═════════════════════════════════════════════════════════════
// Main App
// ═════════════════════════════════════════════════════════════
function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const initialMode = (window.CURRENT_USER && window.CURRENT_USER.role === 'locatar') ? 'tenant' : 'admin';
  const [mode, setMode] = React.useState(initialMode);
  React.useEffect(() => { window.__BLOCAPP_MOUNTED = true; }, []);
  const lang = t.lang;
  const tr = React.useCallback((key) => window.I18N[lang][key] || key, [lang]);

  const state = useAppState();

  // CSS variables — apply theme based on tweaks
  React.useEffect(() => {
    const palette = PALETTES[t.primary] || PALETTES['#C2563A'];
    const density = DENSITIES[t.density] || DENSITIES.regular;
    const root = document.documentElement;
    const dark = t.dark;

    root.style.setProperty('--primary', palette.primary);
    root.style.setProperty('--primary-hover', palette.primaryHover);
    root.style.setProperty('--primary-light', palette.primaryLight);
    root.style.setProperty('--accent', palette.accent);

    if (dark) {
      root.style.setProperty('--bg',        '#1a1612');
      root.style.setProperty('--surface',   '#241f18');
      root.style.setProperty('--surface-2', '#2c2620');
      root.style.setProperty('--ink',       '#f5efe4');
      root.style.setProperty('--ink-2',     '#d4c9b8');
      root.style.setProperty('--muted',     '#8a7d6c');
      root.style.setProperty('--border',    'rgba(245, 239, 228, 0.08)');
      root.style.setProperty('--neutral-bg','#2c2620');
      root.style.setProperty('--neutral-fg','#d4c9b8');
      root.style.setProperty('--success-bg','#1f3328');
      root.style.setProperty('--success-fg','#7ed09a');
      root.style.setProperty('--warning-bg','#3a2e15');
      root.style.setProperty('--warning-fg','#f0c870');
      root.style.setProperty('--danger-bg', '#3a1f1a');
      root.style.setProperty('--danger-fg', '#f08a78');
    } else {
      root.style.setProperty('--bg',        '#FAF6F0');
      root.style.setProperty('--surface',   '#FFFFFF');
      root.style.setProperty('--surface-2', '#F5EFE5');
      root.style.setProperty('--ink',       '#1f1a12');
      root.style.setProperty('--ink-2',     '#3a3327');
      root.style.setProperty('--muted',     '#8a7d6c');
      root.style.setProperty('--border',    'rgba(28, 22, 12, 0.08)');
      root.style.setProperty('--neutral-bg','#F0EADB');
      root.style.setProperty('--neutral-fg','#5a4f3d');
      root.style.setProperty('--success-bg','#DDF0E4');
      root.style.setProperty('--success-fg','#1f6b3e');
      root.style.setProperty('--warning-bg','#FAEBC8');
      root.style.setProperty('--warning-fg','#8a5a13');
      root.style.setProperty('--danger-bg', '#FADEDB');
      root.style.setProperty('--danger-fg', '#a8341e');
    }
    root.style.setProperty('--success', '#3a8b5b');
    root.style.setProperty('--warning', '#c68a2e');
    root.style.setProperty('--danger',  '#c2563a');

    root.style.setProperty('--pad-card', density.padCard + 'px');
    root.style.setProperty('--gap', density.gap + 'px');
    root.style.setProperty('--nav-item-h', density.navItem + 'px');
    root.style.setProperty('--row-h', density.rowH + 'px');

    const fontScale = FONT_SCALES[t.fontScale] || FONT_SCALES.normal;
    root.style.setProperty('--font-base', fontScale.base + 'px');
    document.body.style.fontSize = fontScale.base + 'px';

    document.body.style.background = 'var(--bg)';
    document.body.style.color = 'var(--ink)';
  }, [t]);

  return (
    <ToastProvider>
      <div style={{ minHeight: '100vh', background: 'var(--bg)', position: 'relative' }}>
        <ModeToggle mode={mode} setMode={setMode} lang={lang} />

        {mode === 'admin' ? (
          <AdminApp state={state} tr={tr} t={t} setTweak={setTweak} lang={lang} />
        ) : (
          <TenantApp state={state} tr={tr} t={t} setTweak={setTweak} lang={lang} />
        )}

        <TweaksPanel>
          <TweakSection label={lang === 'ro' ? 'Aspect' : 'Appearance'} />
          <TweakRadio label={lang === 'ro' ? 'Limba' : 'Language'} value={t.lang}
                      options={['ro', 'en']}
                      onChange={(v) => setTweak('lang', v)} />
          <TweakToggle label={lang === 'ro' ? 'Mod întunecat' : 'Dark mode'} value={t.dark}
                       onChange={(v) => setTweak('dark', v)} />
          <TweakSection label={lang === 'ro' ? 'Culoare primară' : 'Primary color'} />
          <TweakColor label={lang === 'ro' ? 'Paletă' : 'Palette'} value={t.primary}
                      options={['#C2563A', '#5C8B68', '#C68A2E', '#5B5DD3']}
                      onChange={(c) => setTweak('primary', c)} />
          <TweakSection label={lang === 'ro' ? 'Densitate' : 'Density'} />
          <TweakRadio label={lang === 'ro' ? 'Spațiere' : 'Spacing'} value={t.density}
                      options={['compact', 'regular', 'comfy']}
                      onChange={(v) => setTweak('density', v)} />
          <TweakSection label={lang === 'ro' ? 'Accesibilitate' : 'Accessibility'} />
          <TweakSelect label={lang === 'ro' ? 'Mărime text' : 'Text size'} value={t.fontScale}
                       options={[
                         { value: 'small',  label: lang === 'ro' ? 'Mic (13px)' : 'Small (13px)' },
                         { value: 'normal', label: lang === 'ro' ? 'Normal (14px)' : 'Normal (14px)' },
                         { value: 'large',  label: lang === 'ro' ? 'Mare (16px)' : 'Large (16px)' },
                         { value: 'xlarge', label: lang === 'ro' ? 'Foarte mare (19px)' : 'Extra large (19px)' },
                       ]}
                       onChange={(v) => setTweak('fontScale', v)} />
          <TweakSection label={lang === 'ro' ? 'Apartamente' : 'Apartments'} />
          <TweakRadio label={lang === 'ro' ? 'Vizualizare' : 'View'} value={t.aptView}
                      options={['card', 'tabel']}
                      onChange={(v) => setTweak('aptView', v)} />
        </TweaksPanel>
      </div>
    </ToastProvider>
  );
}

window.App = App;
