// App shell — sidebar nav, view routing, Supabase data + auth
const { useState: useStateA, useEffect: useEffectA, useMemo: useMemoA } = React;

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "theme": "light",
  "accent": "green"
}/*EDITMODE-END*/;

const ACCENTS = {
  green:  { accent: '#2f5d3a', accent2: '#c7823a' },
  indigo: { accent: '#3b4b8a', accent2: '#c7823a' },
  slate:  { accent: '#3a4654', accent2: '#b88118' },
  plum:   { accent: '#6b3a5a', accent2: '#c7823a' },
};

// Converts snake_case Supabase row → camelCase used throughout the UI
function rowToClient(r) {
  return {
    id:                 r.id,
    rowNum:             r.row_num,
    client:             r.client,
    address:            r.address,
    postClosingAddress: r.post_closing_address,
    type:               r.type,
    agent:              r.agent,
    partner:            r.partner,
    source:             r.source,
    status:             r.status,
    stage:              r.stage,
    contractDate:       r.contract_date,
    closingDate:        r.closing_date,
    salesPrice:         r.sales_price,
    grossCommission:    r.gross_commission,
    agentSplit:         r.agent_split,
    teamSplit:          r.team_split,
    partnerSplit:       r.partner_split,
    referralSplit:      r.referral_split,
    invoice:            r.invoice,
    lender:             r.lender,
    titleCompany:       r.title_company,
    gifts:              r.gifts,
    notes:              r.notes,
    comments:           r.comments,
    createdAt:          r.created_at,
    _editKey:           r.id,    // use Supabase UUID as the stable key
  };
}

// Converts camelCase form payload → snake_case for Supabase insert/update
function clientToRow(c) {
  return {
    client:               c.client,
    address:              c.address,
    post_closing_address: c.postClosingAddress || c.post_closing_address || null,
    type:                 c.type,
    agent:                c.agent,
    partner:              c.partner || null,
    source:               c.source,
    status:               c.status || 'ACTIVE',
    stage:                c.stage || null,
    contract_date:        c.contractDate || null,
    closing_date:         c.closingDate || null,
    sales_price:          c.salesPrice || null,
    gross_commission:     c.grossCommission || null,
    agent_split:          c.agentSplit || null,
    team_split:           c.teamSplit || null,
    partner_split:        c.partnerSplit || null,
    referral_split:       c.referralSplit || null,
    invoice:              c.invoice || null,
    lender:               c.lender || null,
    title_company:        c.titleCompany || c.title || null,
    gifts:                c.gifts || null,
    notes:                c.notes || null,
    comments:             c.comments || null,
  };
}

function App() {
  const [clients, setClients] = useStateA([]);
  const [clientsLoading, setClientsLoading] = useStateA(true);
  const [view, setView] = useStateA(() => location.hash.replace('#', '') || 'dashboard');
  const [authedUser, setAuthedUser] = useStateA(null); // { name, email, is_admin }
  const [agent, setAgent] = useStateA('Hilary');
  const [tweaks, setTweaks] = useStateA(TWEAK_DEFAULTS);
  const [tweaksVisible, setTweaksVisible] = useStateA(false);
  const [toast, setToast] = useStateA(null);

  const db = window._supabase;

  // ── Auth: restore session on mount, listen for changes ──────────────────
  useEffectA(() => {
    db.auth.getSession().then(({ data: { session } }) => {
      if (session?.user) {
        loadUserProfile(session.user);
      }
    });

    const { data: { subscription } } = db.auth.onAuthStateChange((_event, session) => {
      if (session?.user) {
        loadUserProfile(session.user);
      } else {
        setAuthedUser(null);
        setClients([]);
      }
    });
    return () => subscription.unsubscribe();
  }, []);

  async function loadUserProfile(authUser) {
    // The Edge Function puts name + is_admin in user_metadata
    const meta = authUser.user_metadata || {};
    setAuthedUser({
      name:     meta.name     || authUser.email?.split('@')[0] || 'Agent',
      email:    authUser.email,
      is_admin: meta.is_admin || false,
    });
  }

  // Set agent context from authed user
  useEffectA(() => {
    if (authedUser) setAgent(authedUser.name);
  }, [authedUser]);

  // ── Load clients from Supabase ──────────────────────────────────────────
  useEffectA(() => {
    if (!authedUser) return;
    loadClients();

    // Realtime subscription: any change to clients table refreshes the list
    const channel = db
      .channel('clients-changes')
      .on('postgres_changes', { event: '*', schema: 'public', table: 'clients' }, () => {
        loadClients();
      })
      .subscribe();

    return () => db.removeChannel(channel);
  }, [authedUser]);

  async function loadClients() {
    setClientsLoading(true);
    const { data, error } = await db
      .from('clients')
      .select('*')
      .order('created_at', { ascending: false });
    if (!error && data) setClients(data.map(rowToClient));
    setClientsLoading(false);
  }

  // ── Theme / accent ───────────────────────────────────────────────────────
  useEffectA(() => {
    document.documentElement.classList.toggle('dark', tweaks.theme === 'dark');
    const a = ACCENTS[tweaks.accent] || ACCENTS.green;
    document.documentElement.style.setProperty('--accent', a.accent);
    document.documentElement.style.setProperty('--accent-2', a.accent2);
  }, [tweaks]);

  // ── Hash routing ─────────────────────────────────────────────────────────
  useEffectA(() => {
    const onHash = () => setView(location.hash.replace('#', '') || 'dashboard');
    window.addEventListener('hashchange', onHash);
    return () => window.removeEventListener('hashchange', onHash);
  }, []);

  // ── Edit-mode postMessage (for the tweaks panel) ─────────────────────────
  useEffectA(() => {
    const handler = (e) => {
      const d = e.data || {};
      if (d.type === '__activate_edit_mode') setTweaksVisible(true);
      if (d.type === '__deactivate_edit_mode') setTweaksVisible(false);
    };
    window.addEventListener('message', handler);
    window.parent.postMessage({ type: '__edit_mode_available' }, '*');
    return () => window.removeEventListener('message', handler);
  }, []);

  function saveTweak(k, v) {
    const next = { ...tweaks, [k]: v };
    setTweaks(next);
    window.parent.postMessage({ type: '__edit_mode_set_keys', edits: { [k]: v } }, '*');
  }

  function showToast(msg) {
    setToast(msg);
    setTimeout(() => setToast(null), 2800);
  }

  // ── Sign in / out ────────────────────────────────────────────────────────
  function handleSignIn(user) {
    setAuthedUser(user);
    setAgent(user.name);
  }

  async function handleSignOut() {
    await db.auth.signOut();
    setAuthedUser(null);
    setClients([]);
  }

  // ── Form submit → Supabase insert ────────────────────────────────────────
  async function handleSubmit(record) {
    const row = clientToRow(record);
    const { data, error } = await db.from('clients').insert(row).select().single();
    if (error) {
      showToast('Error saving client');
      console.error(error);
      return;
    }
    showToast(`Added ${record.client}`);
    // Realtime will refresh the list automatically
  }

  // ── Admin: apply fix to a client ─────────────────────────────────────────
  async function applyEdit(id, patch) {
    const row = {};
    if (patch.status      !== undefined) row.status           = patch.status;
    if (patch.salesPrice  !== undefined) row.sales_price      = patch.salesPrice;
    if (patch.grossCommission !== undefined) row.gross_commission = patch.grossCommission;
    if (patch.agentSplit  !== undefined) row.agent_split      = patch.agentSplit;
    if (patch.teamSplit   !== undefined) row.team_split       = patch.teamSplit;
    if (patch.partnerSplit!== undefined) row.partner_split    = patch.partnerSplit;
    if (patch.contractDate!== undefined) row.contract_date    = patch.contractDate;
    if (patch.closingDate !== undefined) row.closing_date     = patch.closingDate;
    if (patch.partner     !== undefined) row.partner          = patch.partner;
    if (patch.invoice     !== undefined) row.invoice          = patch.invoice;

    const { error } = await db.from('clients').update(row).eq('id', id);
    if (error) { showToast('Error saving fix'); return; }
    showToast('Saved');
  }

  // ── Inline extras (post-closing address, comments) ───────────────────────
  async function updateExtra(id, patch) {
    const row = {};
    if (patch.postAddress !== undefined) row.post_closing_address = patch.postAddress;
    if (patch.comments    !== undefined) row.comments             = patch.comments;
    if (Object.keys(row).length === 0) return;
    await db.from('clients').update(row).eq('id', id);
  }

  const nav = [
    { id: 'form',      label: 'Intake Form',    className: 'nav-intake' },
    { id: 'dashboard', label: 'Dashboard',       className: 'nav-dashboard' },
    { id: 'agent',     label: 'My stats',        className: 'nav-mystats' },
    { id: 'admin',     label: 'Administration' },
  ];

  if (!authedUser) {
    return <LockScreen onSignIn={handleSignIn} />;
  }

  return (
    <div className="app" data-screen-label={view}>
      <aside className="sidebar">
        <div className="brand">
          <img src="assets/locals-logo.png" alt="Locals Realty Group" className="brand-logo" />
        </div>
        <nav className="nav-section">
          {nav.slice(0, 3).map(n => (
            <button
              key={n.id}
              className={'nav-item ' + (n.className || '') + (view === n.id ? ' active' : '')}
              onClick={() => { location.hash = n.id; }}>
              <span className="dot"></span>{n.label}
            </button>
          ))}
        </nav>
        <div className="signed-in">
          <div className="signed-in-label">Signed in as</div>
          <div className="signed-in-row">
            <div className="signed-in-avatar">{authedUser.name.slice(0, 1).toUpperCase()}</div>
            <div style={{ minWidth: 0, flex: 1 }}>
              <div className="signed-in-name">{authedUser.name}</div>
              <div className="signed-in-meta">
                {clientsLoading ? 'Loading…' : `${clients.length} clients · Live`}
              </div>
            </div>
          </div>
          <button className="signout-btn" onClick={handleSignOut} title="Sign out">
            <svg width="13" height="13" viewBox="0 0 16 16" fill="none" aria-hidden="true">
              <path d="M10 11l3-3-3-3M13 8H6M9 13H4a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h5"
                stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round" />
            </svg>
            Sign out
          </button>
          {authedUser.is_admin && (
            <div className="agent-picker-admin">
              <span className="agent-picker-admin-label">Administration</span>
              <button
                className={'agent-picker-admin-btn' + (view === 'admin' ? ' active' : '')}
                onClick={() => { location.hash = 'admin'; }}
                title="Open the Administration panel">
                Open
              </button>
            </div>
          )}
        </div>
      </aside>

      <main className="main">
        {view === 'dashboard' && <Dashboard clients={clients} agents={window.AGENTS} />}
        {view === 'form'      && <FormView  onSubmit={handleSubmit} agents={window.AGENTS} sources={window.SOURCES} />}
        {view === 'agent'     && <AgentView clients={clients} agent={agent} allAgents={window.AGENTS} />}
        {view === 'clients'   && (
          <ClientsTable
            clients={clients}
            onExtra={updateExtra}
          />
        )}
        {view === 'admin' && authedUser.is_admin && (
          <AdminView
            clients={clients}
            authedUser={authedUser}
            onApplyEdit={applyEdit}
          />
        )}
        {view === 'admin' && !authedUser.is_admin && (
          <div className="main" style={{padding:'60px 40px'}}>
            <h2 style={{fontFamily:'var(--font-serif)', fontSize:28}}>Admin access only</h2>
            <p style={{color:'var(--ink-3)'}}>Ask Hilary to grant you admin access.</p>
          </div>
        )}
      </main>

      {tweaksVisible && (
        <div className="tweaks-panel">
          <h4>Tweaks</h4>
          <div className="tweak-row">
            <label>Theme</label>
            <div className="seg">
              <button className={tweaks.theme === 'light' ? 'on' : ''} onClick={() => saveTweak('theme', 'light')}>Light</button>
              <button className={tweaks.theme === 'dark'  ? 'on' : ''} onClick={() => saveTweak('theme', 'dark')}>Dark</button>
            </div>
          </div>
          <div className="tweak-row">
            <label>Accent</label>
            <div className="seg">
              {Object.keys(ACCENTS).map(k => (
                <button key={k} className={tweaks.accent === k ? 'on' : ''} onClick={() => saveTweak('accent', k)}>
                  <span style={{ display: 'inline-block', width: 10, height: 10, borderRadius: '50%', background: ACCENTS[k].accent, marginRight: 5, verticalAlign: 'middle' }}></span>
                  {k}
                </button>
              ))}
            </div>
          </div>
        </div>
      )}

      {toast && <div className="toast">✓ {toast}</div>}
    </div>
  );
}

// ── Clients table (uses Supabase IDs for row keys) ─────────────────────────
function ClientsTable({ clients, onExtra }) {
  const [q, setQ] = useStateA('');
  const [statusFilter, setStatusFilter] = useStateA('ALL');
  const [openRow, setOpenRow] = useStateA(null);

  const filtered = clients.filter(c => {
    if (statusFilter !== 'ALL' && (c.status || '').toUpperCase() !== statusFilter) return false;
    if (q && !(`${c.client} ${c.address} ${c.agent}`.toLowerCase()).includes(q.toLowerCase())) return false;
    return true;
  });

  function exportCsv() {
    const header = ['Client','Address','Post-Closing Address','Type','Agent','Partner','Source','Status','Contract','Closing','Sales Price','Gross Commission','Agent Split','Team Split','Partner Split','Referral','Invoice','Comments'];
    const rows = filtered.map(c => [
      c.client, c.address, c.postClosingAddress || '', c.type, c.agent, c.partner, c.source, c.status,
      c.contractDate || '', c.closingDate || '', c.salesPrice || '', c.grossCommission || '',
      c.agentSplit || '', c.teamSplit || '', c.partnerSplit || '', c.referralSplit || '',
      c.invoice || '', (c.comments || '').replace(/\n/g, ' ')
    ]);
    const csv = [header, ...rows].map(r => r.map(v => {
      const s = String(v ?? '');
      return /[",\n]/.test(s) ? '"' + s.replace(/"/g, '""') + '"' : s;
    }).join(',')).join('\n');
    const blob = new Blob([csv], { type: 'text/csv' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url; a.download = 'client-tracker-' + new Date().toISOString().slice(0, 10) + '.csv';
    a.click();
    setTimeout(() => URL.revokeObjectURL(url), 1000);
  }

  return (
    <div>
      <div className="page-head">
        <div>
          <h1 className="page-title">All clients</h1>
          <p className="page-sub">
            {filtered.length} of {clients.length} records
            <span className="sheet-badge" title="Live data from Supabase">
              <span className="sheet-dot"></span>
              Live · Supabase
            </span>
          </p>
        </div>
        <div style={{ display: 'flex', gap: 8 }}>
          <input placeholder="Search name, address, agent…" value={q} onChange={e => setQ(e.target.value)}
            style={{ padding: '8px 12px', border: '1px solid var(--rule)', borderRadius: 6, background: 'var(--panel)', color: 'var(--ink)', width: 260 }} />
          <select value={statusFilter} onChange={e => setStatusFilter(e.target.value)}
            style={{ padding: '8px 12px', border: '1px solid var(--rule)', borderRadius: 6, background: 'var(--panel)', color: 'var(--ink)' }}>
            <option value="ALL">All statuses</option>
            <option>ACTIVE</option><option>PENDING</option><option>CLOSED</option><option>DFT</option>
          </select>
          <button className="btn" onClick={exportCsv}>Export CSV</button>
        </div>
      </div>
      <div className="card" style={{ padding: 0, overflow: 'hidden' }}>
        <div style={{ maxHeight: '72vh', overflow: 'auto' }}>
          <table className="table clients-table">
            <thead>
              <tr>
                <th style={{ width: 28 }}></th>
                <th>Client</th><th>Type</th><th>Agent</th><th>Partner</th><th>Source</th>
                <th>Status</th><th>Closing</th>
                <th className="num">Price</th><th className="num">Gross comm.</th>
                <th className="num">Agent</th><th className="num">Team</th>
                <th className="num">Partner</th><th className="num">Referral</th><th className="num">Invoice</th>
                <th>Post-closing address</th><th>Comments</th>
              </tr>
            </thead>
            <tbody>
              {filtered.map(c => {
                const k = c.id;
                const isOpen = openRow === k;
                return (
                  <React.Fragment key={k}>
                    <tr className={isOpen ? 'row-open' : ''}>
                      <td><button className="row-toggle" onClick={() => setOpenRow(isOpen ? null : k)} title="Edit post-closing address & comments">{isOpen ? '▾' : '▸'}</button></td>
                      <td>{c.client}<div className="muted" style={{ fontSize: 11 }}>{c.address}</div></td>
                      <td><span className="chip">{c.type}</span></td>
                      <td>{c.agent}</td>
                      <td className="muted">{c.partner || '—'}</td>
                      <td className="muted">{c.source}</td>
                      <td><span className={'pill ' + (c.status || '')}><span className="dot"></span>{c.status}</span></td>
                      <td className="muted">{c.closingDate || '—'}</td>
                      <td className="num">{fmtMoney(c.salesPrice)}</td>
                      <td className="num">{fmtMoney(c.grossCommission)}</td>
                      <td className="num">{fmtMoney(c.agentSplit)}</td>
                      <td className="num">{fmtMoney(c.teamSplit)}</td>
                      <td className="num">{fmtMoney(c.partnerSplit)}</td>
                      <td className="num">{fmtMoney(c.referralSplit)}</td>
                      <td className="num">{fmtMoney(c.invoice)}</td>
                      <td className="muted truncate" style={{ maxWidth: 180 }}>{c.postClosingAddress || <span style={{ color: 'var(--ink-3)', fontStyle: 'italic' }}>—</span>}</td>
                      <td className="muted truncate" style={{ maxWidth: 200 }}>{c.comments || <span style={{ color: 'var(--ink-3)', fontStyle: 'italic' }}>—</span>}</td>
                    </tr>
                    {isOpen && (
                      <tr className="row-edit">
                        <td></td>
                        <td colSpan="16">
                          <div className="edit-grid">
                            <div className="field" style={{ marginBottom: 0 }}>
                              <label>Post-closing address</label>
                              <input type="text" defaultValue={c.postClosingAddress || ''}
                                onBlur={e => onExtra(k, { postAddress: e.target.value })}
                                placeholder="Where the client relocated after closing" />
                            </div>
                            <div className="field" style={{ marginBottom: 0 }}>
                              <label>Comments</label>
                              <textarea rows="2" defaultValue={c.comments || ''}
                                onBlur={e => onExtra(k, { comments: e.target.value })}
                                placeholder="Gift sent, referral potential, follow-up reminders…" />
                            </div>
                          </div>
                        </td>
                      </tr>
                    )}
                  </React.Fragment>
                );
              })}
            </tbody>
          </table>
        </div>
      </div>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
