// Audit Log Viewer — immutable record of all sensitive actions
// Admin-only · reads from audit_log via StagevoData.getAuditLog()

const ACTION_META = {
  create:       { label:'Created',      color:'var(--won)',  bg:'var(--won-soft)',  icon:'✚' },
  update:       { label:'Updated',      color:'var(--info)', bg:'var(--info-soft)', icon:'✎' },
  delete:       { label:'Deleted',      color:'var(--lost)', bg:'var(--lost-soft)', icon:'✕' },
  stage_change: { label:'Stage change', color:'var(--warn)', bg:'var(--warn-soft)', icon:'⇄' },
  reassign:     { label:'Reassigned',   color:'#7C3AED',     bg:'#F3EEFF',          icon:'↪' },
  login:        { label:'Login',        color:'var(--won)',  bg:'var(--won-soft)',  icon:'→' },
  logout:       { label:'Logout',       color:'var(--ink-3)',bg:'var(--surface-2)', icon:'←' },
  invite:       { label:'Invited',      color:'var(--info)', bg:'var(--info-soft)', icon:'✉' },
  mfa_enrolled: { label:'MFA enrolled', color:'#7C3AED',     bg:'#F3EEFF',          icon:'🔐' },
};

const ENTITY_ICONS = { deals:'📋', contacts:'👤', profiles:'👥', settings:'⚙️', quotes:'📄', portal_links:'🔗', showrooms:'🏠' };
const DEMO_LOG = [
  { id:1, user_name:'Charith Kapurubandara', action:'stage_change', entity_type:'deals', entity_id:'CHE 51891', before_state:{stage:'possible'}, after_state:{stage:'in_progress'}, created_at: new Date(Date.now()-2*60000).toISOString(), ip_address:'101.100.x.x' },
  { id:2, user_name:'Alex Kim', action:'update', entity_type:'deals', entity_id:'BAY 51234', before_state:{value:62000}, after_state:{value:74000}, created_at: new Date(Date.now()-18*60000).toISOString(), ip_address:'103.12.x.x' },
  { id:3, user_name:'Admin', action:'invite', entity_type:'profiles', entity_id:'new-user@example.com', before_state:null, after_state:{role:'sales_designer',email:'new-user@example.com'}, created_at: new Date(Date.now()-65*60000).toISOString(), ip_address:'101.100.x.x' },
  { id:4, user_name:'Jordan Lee', action:'create', entity_type:'contacts', entity_id:'CON-2291', before_state:null, after_state:{name:'Tom Bradley', phone:'+61 412 xxx xxx'}, created_at: new Date(Date.now()-110*60000).toISOString(), ip_address:'220.233.x.x' },
  { id:5, user_name:'Casey Wong', action:'delete', entity_type:'deals', entity_id:'PAK 50234', before_state:{customer:'Old Lead',stage:'possible',value:28000}, after_state:null, created_at: new Date(Date.now()-3*3600000).toISOString(), ip_address:'115.64.x.x' },
  { id:6, user_name:'Charith Kapurubandara', action:'mfa_enrolled', entity_type:'profiles', entity_id:'charith@stagevo.io', before_state:{mfa:false}, after_state:{mfa:true}, created_at: new Date(Date.now()-4*3600000).toISOString(), ip_address:'101.100.x.x' },
  { id:7, user_name:'Alex Kim', action:'login', entity_type:'profiles', entity_id:'alex@stagevo.io', before_state:null, after_state:{method:'email+password'}, created_at: new Date(Date.now()-5*3600000).toISOString(), ip_address:'103.12.x.x' },
  { id:8, user_name:'Admin', action:'update', entity_type:'settings', entity_id:'org-config', before_state:{mfa_required:false}, after_state:{mfa_required:true}, created_at: new Date(Date.now()-6*3600000).toISOString(), ip_address:'101.100.x.x' },
  { id:9, user_name:'Jordan Lee', action:'reassign', entity_type:'deals', entity_id:'BAY 52100', before_state:{rep:'Casey Wong'}, after_state:{rep:'Jordan Lee'}, created_at: new Date(Date.now()-24*3600000).toISOString(), ip_address:'220.233.x.x' },
  { id:10, user_name:'Casey Wong', action:'stage_change', entity_type:'deals', entity_id:'CHE 51788', before_state:{stage:'in_progress'}, after_state:{stage:'sold'}, created_at: new Date(Date.now()-25*3600000).toISOString(), ip_address:'115.64.x.x' },
  { id:11, user_name:'Admin', action:'create', entity_type:'quotes', entity_id:'QT-00029', before_state:null, after_state:{total:88400,customer:'Priya Nair'}, created_at: new Date(Date.now()-26*3600000).toISOString(), ip_address:'101.100.x.x' },
  { id:12, user_name:'Alex Kim', action:'update', entity_type:'contacts', entity_id:'CON-0188', before_state:{phone:'+61 412 xxx'}, after_state:{phone:'+61 412 334 501'}, created_at: new Date(Date.now()-48*3600000).toISOString(), ip_address:'103.12.x.x' },
];

function relTime(iso) {
  const d = Math.floor((Date.now() - new Date(iso)) / 1000);
  if (d < 60) return d + 's ago';
  if (d < 3600) return Math.floor(d/60) + 'm ago';
  if (d < 86400) return Math.floor(d/3600) + 'h ago';
  return Math.floor(d/86400) + 'd ago';
}

function fmtDateTime(iso) {
  return new Date(iso).toLocaleString('en-AU', { day:'numeric', month:'short', year:'numeric', hour:'2-digit', minute:'2-digit', second:'2-digit' });
}

function DiffView({ before, after }) {
  if (!before && !after) return <span style={{ color:'var(--ink-4)', fontSize:12 }}>—</span>;
  const allKeys = [...new Set([...Object.keys(before||{}), ...Object.keys(after||{})])];
  const changes = allKeys.filter(k => JSON.stringify((before||{})[k]) !== JSON.stringify((after||{})[k]));
  if (!changes.length) return <span style={{ color:'var(--ink-4)', fontSize:12 }}>No field changes</span>;
  return (
    <div style={{ display:'flex', flexDirection:'column', gap:4 }}>
      {changes.map(k => (
        <div key={k} style={{ display:'flex', alignItems:'flex-start', gap:8, fontSize:12 }}>
          <span style={{ fontWeight:600, color:'var(--ink-2)', minWidth:80 }}>{k}</span>
          {before && before[k] != null && (
            <span style={{ background:'#FEE2E2', color:'#991B1B', borderRadius:4, padding:'1px 6px', fontFamily:'var(--mono)' }}>
              {String(before[k])}
            </span>
          )}
          {before && before[k] != null && after && after[k] != null && <span style={{ color:'var(--ink-4)' }}>→</span>}
          {after && after[k] != null && (
            <span style={{ background:'#DCFCE7', color:'#15803D', borderRadius:4, padding:'1px 6px', fontFamily:'var(--mono)' }}>
              {String(after[k])}
            </span>
          )}
        </div>
      ))}
    </div>
  );
}

function AuditLog({ currentUser, showToast }) {
  const toast = showToast || (() => {});
  const LIVE = !!window.STAGEVO_AUTHED && !!window.StagevoData;
  const [rows, setRows] = React.useState([]);
  const [loading, setLoading] = React.useState(LIVE);
  const [filterAction, setFilterAction] = React.useState('all');
  const [filterEntity, setFilterEntity] = React.useState('all');
  const [filterUser, setFilterUser] = React.useState('');
  const [expandedId, setExpandedId] = React.useState(null);
  const [page, setPage] = React.useState(0);
  const PAGE_SIZE = 15;

  React.useEffect(() => {
    if (!LIVE) { setRows(DEMO_LOG); return; }
    setLoading(true);
    window.StagevoData.getAuditLog().then(({ data }) => {
      setRows(data || []); setLoading(false);
    }).catch(() => { setRows(DEMO_LOG); setLoading(false); });
  }, [LIVE]);

  function exportCSV() {
    const header = ['Time','User','Action','Entity Type','Entity ID','IP','Before','After'];
    const csvRows = filtered.map(r => [
      fmtDateTime(r.created_at), r.user_name || '', r.action, r.entity_type, r.entity_id || '',
      r.ip_address || '',
      r.before_state ? JSON.stringify(r.before_state).replace(/"/g,'""') : '',
      r.after_state  ? JSON.stringify(r.after_state).replace(/"/g,'""') : '',
    ].map(v => '"'+v+'"').join(','));
    const blob = new Blob([[header.join(','), ...csvRows].join('\n')], { type:'text/csv' });
    const a = document.createElement('a'); a.href = URL.createObjectURL(blob);
    a.download = 'stagevo-audit-log-' + new Date().toISOString().slice(0,10) + '.csv';
    a.click(); toast('Audit log exported to CSV');
  }

  const actions = ['all', ...Object.keys(ACTION_META)];
  const entities = ['all', 'deals', 'contacts', 'profiles', 'settings', 'quotes', 'portal_links', 'showrooms'];
  const filtered = rows.filter(r => {
    if (filterAction !== 'all' && r.action !== filterAction) return false;
    if (filterEntity !== 'all' && r.entity_type !== filterEntity) return false;
    if (filterUser && !(r.user_name||'').toLowerCase().includes(filterUser.toLowerCase())) return false;
    return true;
  });
  const paged = filtered.slice(page * PAGE_SIZE, (page+1) * PAGE_SIZE);
  const totalPages = Math.ceil(filtered.length / PAGE_SIZE);

  return (
    <div>
      {/* Stats bar */}
      <div style={{ display:'grid', gridTemplateColumns:'repeat(5,1fr)', gap:12, marginBottom:18 }}>
        {[
          { label:'Total events', value: rows.length, color:'var(--ink)' },
          { label:'Today', value: rows.filter(r => new Date(r.created_at) > new Date(Date.now()-86400000)).length, color:'var(--accent)' },
          { label:'Stage changes', value: rows.filter(r=>r.action==='stage_change').length, color:'var(--warn)' },
          { label:'Deletions', value: rows.filter(r=>r.action==='delete').length, color:'var(--lost)' },
          { label:'User events', value: rows.filter(r=>['login','logout','invite','mfa_enrolled'].includes(r.action)).length, color:'#7C3AED' },
        ].map(s => (
          <div key={s.label} className="kpi">
            <div className="kpi-label">{s.label}</div>
            <div className="kpi-value" style={{ fontSize:26, color:s.color }}>{s.value}</div>
          </div>
        ))}
      </div>

      <div className="card">
        {/* Toolbar */}
        <div className="card-hd" style={{ flexWrap:'wrap', gap:10 }}>
          <div className="card-title">Audit Trail</div>
          <div style={{ display:'flex', gap:8, alignItems:'center', marginLeft:'auto', flexWrap:'wrap' }}>
            <input value={filterUser} onChange={e => { setFilterUser(e.target.value); setPage(0); }}
              placeholder="Filter by user…" style={{ border:'1px solid var(--border)', borderRadius:6, padding:'5px 10px', fontSize:12.5, outline:'none', background:'var(--surface-2)', width:160 }} />
            <select value={filterAction} onChange={e => { setFilterAction(e.target.value); setPage(0); }}
              style={{ border:'1px solid var(--border)', borderRadius:6, padding:'5px 10px', fontSize:12.5, background:'var(--surface-2)', outline:'none' }}>
              {actions.map(a => <option key={a} value={a}>{a==='all'?'All actions':ACTION_META[a]?.label||a}</option>)}
            </select>
            <select value={filterEntity} onChange={e => { setFilterEntity(e.target.value); setPage(0); }}
              style={{ border:'1px solid var(--border)', borderRadius:6, padding:'5px 10px', fontSize:12.5, background:'var(--surface-2)', outline:'none' }}>
              {entities.map(e => <option key={e} value={e}>{e==='all'?'All entities':e}</option>)}
            </select>
            <button className="btn sm" onClick={exportCSV}>Export CSV ↓</button>
          </div>
        </div>

        {/* Table */}
        {loading ? (
          <div style={{ padding:'40px', textAlign:'center', color:'var(--ink-3)' }}>
            <div className="auth-spinner" style={{ margin:'0 auto 12px' }}></div> Loading audit log…
          </div>
        ) : (
          <>
            <div className="tbl-wrap">
              <table className="tbl">
                <thead>
                  <tr>
                    <th style={{ width:140 }}>Time</th>
                    <th>User</th>
                    <th style={{ width:110 }}>Action</th>
                    <th>Entity</th>
                    <th>Changes</th>
                    <th style={{ width:110 }}>IP Address</th>
                  </tr>
                </thead>
                <tbody>
                  {paged.length === 0 && (
                    <tr><td colSpan={6} style={{ textAlign:'center', color:'var(--ink-3)', padding:'32px', fontSize:13 }}>No events match the current filters.</td></tr>
                  )}
                  {paged.map(row => {
                    const meta = ACTION_META[row.action] || { label:row.action, color:'var(--ink-3)', bg:'var(--surface-2)', icon:'·' };
                    const eIcon = ENTITY_ICONS[row.entity_type] || '📁';
                    const isExpanded = expandedId === row.id;
                    return (
                      <React.Fragment key={row.id}>
                        <tr onClick={() => setExpandedId(isExpanded ? null : row.id)} style={{ cursor:'pointer' }}>
                          <td>
                            <div style={{ fontSize:12, fontFamily:'var(--mono)', color:'var(--ink-2)' }}>{relTime(row.created_at)}</div>
                            <div style={{ fontSize:10.5, color:'var(--ink-4)' }}>{fmtDateTime(row.created_at).split(',')[0]}</div>
                          </td>
                          <td>
                            <div style={{ fontSize:13, fontWeight:600, color:'var(--ink)' }}>{row.user_name || 'Unknown'}</div>
                          </td>
                          <td>
                            <span style={{ display:'inline-flex', alignItems:'center', gap:5, fontSize:11.5, fontWeight:600,
                              color:meta.color, background:meta.bg, borderRadius:99, padding:'3px 8px' }}>
                              <span>{meta.icon}</span>{meta.label}
                            </span>
                          </td>
                          <td>
                            <div style={{ display:'flex', alignItems:'center', gap:6 }}>
                              <span style={{ fontSize:14 }}>{eIcon}</span>
                              <div>
                                <div style={{ fontSize:12, fontWeight:600, color:'var(--ink)' }}>{row.entity_type}</div>
                                {row.entity_id && <div style={{ fontSize:11, color:'var(--ink-3)', fontFamily:'var(--mono)' }}>{row.entity_id}</div>}
                              </div>
                            </div>
                          </td>
                          <td style={{ maxWidth:260 }}>
                            <DiffView before={row.before_state} after={row.after_state} />
                          </td>
                          <td style={{ fontSize:11.5, color:'var(--ink-3)', fontFamily:'var(--mono)' }}>{row.ip_address || '—'}</td>
                        </tr>
                        {isExpanded && (
                          <tr style={{ background:'var(--surface-2)' }}>
                            <td colSpan={6} style={{ padding:'14px 20px' }}>
                              <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:24 }}>
                                <div>
                                  <div style={{ fontSize:11, fontWeight:700, textTransform:'uppercase', letterSpacing:'0.07em', color:'var(--ink-3)', marginBottom:8 }}>Before</div>
                                  <pre style={{ margin:0, fontSize:11.5, fontFamily:'var(--mono)', color:'var(--ink-2)', background:'#FEE2E2', padding:'10px 12px', borderRadius:6, overflowX:'auto', maxHeight:140, overflowY:'auto', whiteSpace:'pre-wrap' }}>
                                    {row.before_state ? JSON.stringify(row.before_state, null, 2) : 'null'}
                                  </pre>
                                </div>
                                <div>
                                  <div style={{ fontSize:11, fontWeight:700, textTransform:'uppercase', letterSpacing:'0.07em', color:'var(--ink-3)', marginBottom:8 }}>After</div>
                                  <pre style={{ margin:0, fontSize:11.5, fontFamily:'var(--mono)', color:'var(--ink-2)', background:'#DCFCE7', padding:'10px 12px', borderRadius:6, overflowX:'auto', maxHeight:140, overflowY:'auto', whiteSpace:'pre-wrap' }}>
                                    {row.after_state ? JSON.stringify(row.after_state, null, 2) : 'null'}
                                  </pre>
                                </div>
                              </div>
                              <div style={{ marginTop:10, fontSize:11.5, color:'var(--ink-3)' }}>
                                Full timestamp: {fmtDateTime(row.created_at)} · Event ID: {row.id}
                              </div>
                            </td>
                          </tr>
                        )}
                      </React.Fragment>
                    );
                  })}
                </tbody>
              </table>
            </div>

            {/* Pagination */}
            {totalPages > 1 && (
              <div style={{ padding:'10px 20px', borderTop:'1px solid var(--border)', display:'flex', alignItems:'center', gap:12 }}>
                <span style={{ fontSize:12, color:'var(--ink-3)' }}>{filtered.length} events · page {page+1}/{totalPages}</span>
                <div style={{ marginLeft:'auto', display:'flex', gap:6 }}>
                  <button className="btn sm" disabled={page===0} onClick={() => setPage(p=>p-1)}>← Prev</button>
                  <button className="btn sm" disabled={page>=totalPages-1} onClick={() => setPage(p=>p+1)}>Next →</button>
                </div>
              </div>
            )}

            <div style={{ padding:'10px 20px', borderTop:'1px solid var(--border)', display:'flex', alignItems:'center', gap:8 }}>
              <span style={{ fontSize:12, color:'var(--ink-3)' }}>🔒 This log is immutable — entries cannot be edited or deleted by anyone, including admins.</span>
            </div>
          </>
        )}
      </div>
    </div>
  );
}

window.AuditLog = AuditLog;
