// tilgang-bruker-visning.jsx — Brukersentrert tilgangsvisning + Se som-logg
// To nye faner i Tilganger: per-bruker tilganger (sorter/filtrer) og audit av "Se som"

// ══════════════════════════════════════════════════════════════
// BRUKERSENTRERT TILGANGSVISNING
// ══════════════════════════════════════════════════════════════
// Viser for hver bruker hvilke moduler de har tilgang til (utledet
// fra rolle + overstyringer + admin-nivå). Kan sorteres og filtreres
// både på bruker og på modul — komplement til matrisen.

async function TBV_hentAlt() {
  const [profiler, matrise, overstyringer, moduler] = await Promise.all([
    window._sb.from('profiles')
      .select('id,navn,epost,admin_nivaa,kan_se_som,rolle_id,roller(nokkel,navn,farge),enhet_id,enheter(navn)')
      .order('navn'),
    window._sb.from('roller_tilgang').select('niva, roller(nokkel), moduler(nokkel,navn,gruppe,sortering)'),
    window._sb.from('bruker_overstyringer').select('bruker_id, niva, moduler(nokkel)').then(r => r).catch(() => ({ data: [] })),
    window._sb.from('moduler').select('nokkel,navn,gruppe,sortering').order('sortering'),
  ]);

  // Bygg rolle→modul→nivå-oppslag
  const rolleTilgang = {};
  (matrise.data || []).forEach(rad => {
    const rn = rad.roller?.nokkel, mn = rad.moduler?.nokkel;
    if (!rn || !mn) return;
    if (!rolleTilgang[rn]) rolleTilgang[rn] = {};
    rolleTilgang[rn][mn] = rad.niva;
  });

  // Overstyringer per bruker
  const overMap = {};
  (overstyringer.data || []).forEach(o => {
    if (!o.bruker_id || !o.moduler?.nokkel) return;
    if (!overMap[o.bruker_id]) overMap[o.bruker_id] = {};
    overMap[o.bruker_id][o.moduler.nokkel] = o.niva;
  });

  return {
    profiler: profiler.data || [],
    moduler: moduler.data || [],
    rolleTilgang,
    overMap,
  };
}

// Beregn effektiv tilgang for én bruker på én modul
function TBV_effektivTilgang(bruker, modulNokkel, rolleTilgang, overMap) {
  // Admin/superbruker overstyrer alt
  if (bruker.admin_nivaa === 'superbruker') return 'A';
  if (bruker.admin_nivaa === 'administrator') return 'A';
  // Eksplisitt overstyring
  const over = overMap[bruker.id]?.[modulNokkel];
  if (over && over !== '·') return over;
  // Fra rolle
  const rolleN = bruker.roller?.nokkel;
  if (rolleN && rolleTilgang[rolleN]?.[modulNokkel]) return rolleTilgang[rolleN][modulNokkel];
  return '·';
}

function FaneBrukerTilgang() {
  const [data,      setData]      = React.useState(null);
  const [laster,    setLaster]    = React.useState(true);
  const [sok,       setSok]       = React.useState('');
  const [modulFilt, setModulFilt] = React.useState('alle');
  const [nivaFilt,  setNivaFilt]  = React.useState('alle');
  const [sortK,     setSortK]     = React.useState('navn');
  const [sortDir,   setSortDir]   = React.useState('asc');
  const [valgtBruker, setValgtBruker] = React.useState(null);

  React.useEffect(() => { TBV_hentAlt().then(setData).finally(() => setLaster(false)); }, []);

  if (laster) return <div style={{ padding:32, textAlign:'center', color:SK.soft, fontSize:13 }}>Laster tilganger…</div>;
  if (!data) return null;

  const { profiler, moduler, rolleTilgang, overMap } = data;
  const AKS = window.AKS_KODER || {};

  // Filtrer brukere
  let rader = profiler.slice();
  if (sok) {
    const q = sok.toLowerCase();
    rader = rader.filter(b => (b.navn||'').toLowerCase().includes(q) || (b.epost||'').toLowerCase().includes(q));
  }
  // Filtrer på at brukeren har et visst nivå på valgt modul
  if (modulFilt !== 'alle') {
    rader = rader.filter(b => {
      const niv = TBV_effektivTilgang(b, modulFilt, rolleTilgang, overMap);
      if (nivaFilt === 'alle') return niv !== '·';
      return niv === nivaFilt;
    });
  } else if (nivaFilt !== 'alle') {
    // Filtrer på at brukeren har dette nivået på MINST én modul
    rader = rader.filter(b => moduler.some(m => TBV_effektivTilgang(b, m.nokkel, rolleTilgang, overMap) === nivaFilt));
  }

  // Sorter
  rader.sort((a,b) => {
    let va, vb;
    if (sortK === 'navn') { va = (a.navn||a.epost||'').toLowerCase(); vb = (b.navn||b.epost||'').toLowerCase(); }
    else if (sortK === 'rolle') { va = a.roller?.navn||''; vb = b.roller?.navn||''; }
    else if (sortK === 'admin') { va = a.admin_nivaa||'ingen'; vb = b.admin_nivaa||'ingen'; }
    else if (sortK === 'antall') {
      va = moduler.filter(m => TBV_effektivTilgang(a, m.nokkel, rolleTilgang, overMap) !== '·').length;
      vb = moduler.filter(m => TBV_effektivTilgang(b, m.nokkel, rolleTilgang, overMap) !== '·').length;
    }
    if (va < vb) return sortDir==='asc'?-1:1;
    if (va > vb) return sortDir==='asc'?1:-1;
    return 0;
  });

  const toggleSort = k => { if (sortK===k) setSortDir(d=>d==='asc'?'desc':'asc'); else { setSortK(k); setSortDir('asc'); } };
  const SH = ({ k, children, style }) => (
    <th onClick={()=>toggleSort(k)} style={{ cursor:'pointer', userSelect:'none', ...style }}>
      {children}{sortK===k ? (sortDir==='asc'?' ↑':' ↓') : ''}
    </th>
  );

  // Detalj for én bruker: alle moduler med nivå
  if (valgtBruker) {
    const b = valgtBruker;
    const gruppert = {};
    moduler.forEach(m => { (gruppert[m.gruppe] = gruppert[m.gruppe] || []).push(m); });
    return (
      <div style={{ marginTop:16 }}>
        <button onClick={()=>setValgtBruker(null)} style={{ background:'none', border:'none', cursor:'pointer', color:SK.soft, fontSize:12, fontFamily:'inherit', padding:0, marginBottom:12 }}>← Alle brukere</button>
        <Card padded>
          <div style={{ display:'flex', alignItems:'center', gap:12, marginBottom:16 }}>
            <div style={{ width:42, height:42, borderRadius:'50%', background:b.roller?.farge||'#9aa3b8', color:'#fff',
              display:'flex', alignItems:'center', justifyContent:'center', fontSize:14, fontWeight:700 }}>
              {(b.navn||b.epost||'?').split(' ').map(n=>n[0]).slice(0,2).join('').toUpperCase()}
            </div>
            <div style={{ flex:1 }}>
              <div style={{ fontSize:15, fontWeight:600 }}>{b.navn||b.epost}</div>
              <div style={{ fontSize:12, color:SK.soft, display:'flex', gap:8, alignItems:'center', marginTop:2 }}>
                {b.roller?.navn || 'Ingen rolle'}{b.enheter?.navn && ` · ${b.enheter.navn}`}
                {window.AdminBadge && <window.AdminBadge nivaa={b.admin_nivaa} />}
              </div>
            </div>
          </div>
          {Object.entries(gruppert).map(([gruppe, mods]) => (
            <div key={gruppe} style={{ marginBottom:14 }}>
              <div style={{ fontSize:10.5, fontWeight:700, letterSpacing:0.06, textTransform:'uppercase', color:SK.soft, marginBottom:6 }}>{gruppe}</div>
              <div style={{ display:'flex', flexDirection:'column', gap:2 }}>
                {mods.map(m => {
                  const niv = TBV_effektivTilgang(b, m.nokkel, rolleTilgang, overMap);
                  const k = AKS[niv] || AKS['·'] || {};
                  const fraOver = overMap[b.id]?.[m.nokkel] && overMap[b.id][m.nokkel] !== '·';
                  const fraAdmin = b.admin_nivaa === 'administrator' || b.admin_nivaa === 'superbruker';
                  return (
                    <div key={m.nokkel} style={{ display:'flex', alignItems:'center', gap:10, padding:'6px 10px', borderRadius:6,
                      background: niv==='·' ? 'transparent' : SK.iceBlueLight+'66' }}>
                      <span style={{ flex:1, fontSize:12.5, color: niv==='·'?SK.soft:SK.ink }}>{m.navn}</span>
                      {fraAdmin && niv!=='·' && <span style={{ fontSize:10, color:'#a01a25' }}>via admin</span>}
                      {fraOver && <span style={{ fontSize:10, color:'#8e5a05' }}>overstyrt</span>}
                      <span style={{ fontSize:11, fontWeight:700, minWidth:60, textAlign:'right', color:k.fg||SK.soft }}>
                        {k.label || 'Ingen'}
                      </span>
                    </div>
                  );
                })}
              </div>
            </div>
          ))}
        </Card>
      </div>
    );
  }

  return (
    <div style={{ marginTop:16 }}>
      <div style={{ fontSize:12.5, color:SK.soft, lineHeight:1.5, marginBottom:14,
        padding:'10px 14px', background:SK.iceBlueLight, borderRadius:10 }}>
        Brukersentrert visning av effektiv tilgang (rolle + overstyringer + admin-nivå). Filtrer på modul og nivå
        for å se hvem som har en gitt tilgang, eller klikk en bruker for full oversikt. Komplement til matrisen.
      </div>

      <div style={{ display:'flex', gap:10, marginBottom:14, flexWrap:'wrap', alignItems:'center' }}>
        <input className="ok-input ok-input--search" placeholder="Søk bruker…" value={sok} onChange={e=>setSok(e.target.value)}
          style={{ maxWidth:220, padding:'7px 12px 7px 32px' }} />
        <select className="ok-input" value={modulFilt} onChange={e=>setModulFilt(e.target.value)} style={{ padding:'7px 10px', fontSize:13, maxWidth:200 }}>
          <option value="alle">Alle moduler</option>
          {moduler.map(m => <option key={m.nokkel} value={m.nokkel}>{m.navn}</option>)}
        </select>
        <select className="ok-input" value={nivaFilt} onChange={e=>setNivaFilt(e.target.value)} style={{ padding:'7px 10px', fontSize:13, maxWidth:160 }}>
          <option value="alle">Alle nivåer</option>
          {['L','R','A','S'].map(k => <option key={k} value={k}>{(AKS[k]||{}).label||k}</option>)}
        </select>
        <span style={{ fontSize:12, color:SK.soft, marginLeft:'auto' }}>{rader.length} brukere</span>
      </div>

      <Card padded={false}>
        <table className="ok-table">
          <thead><tr>
            <SH k="navn" style={{ paddingLeft:18 }}>Bruker</SH>
            <SH k="rolle">Rolle</SH>
            <SH k="admin">Admin-nivå</SH>
            <SH k="antall">Moduler m/tilgang</SH>
            {modulFilt !== 'alle' && <th>Nivå på valgt modul</th>}
          </tr></thead>
          <tbody>
            {rader.map(b => {
              const antall = moduler.filter(m => TBV_effektivTilgang(b, m.nokkel, rolleTilgang, overMap) !== '·').length;
              const valgtNiv = modulFilt !== 'alle' ? TBV_effektivTilgang(b, modulFilt, rolleTilgang, overMap) : null;
              const k = valgtNiv ? (AKS[valgtNiv]||{}) : null;
              return (
                <tr key={b.id} onClick={()=>setValgtBruker(b)} style={{ cursor:'pointer' }}>
                  <td style={{ paddingLeft:18 }}>
                    <div style={{ display:'flex', alignItems:'center', gap:8 }}>
                      <div style={{ width:26, height:26, borderRadius:'50%', background:b.roller?.farge||'#9aa3b8', color:'#fff',
                        display:'flex', alignItems:'center', justifyContent:'center', fontSize:9, fontWeight:700 }}>
                        {(b.navn||b.epost||'?').split(' ').map(n=>n[0]).slice(0,2).join('').toUpperCase()}
                      </div>
                      <div>
                        <div style={{ fontSize:12.5, fontWeight:600 }}>{b.navn||b.epost}</div>
                        {b.kan_se_som && <div style={{ fontSize:10, color:'#8e5a05' }}>kan «Se som»</div>}
                      </div>
                    </div>
                  </td>
                  <td style={{ fontSize:12 }}>
                    {b.roller?.navn ? (
                      <span style={{ display:'inline-flex', alignItems:'center', gap:6 }}>
                        <span style={{ width:8, height:8, borderRadius:'50%', background:b.roller.farge }} />{b.roller.navn}
                      </span>
                    ) : <span style={{ color:SK.coral, fontStyle:'italic' }}>Ingen</span>}
                  </td>
                  <td>{window.AdminBadge ? <window.AdminBadge nivaa={b.admin_nivaa} /> : (b.admin_nivaa||'—')}</td>
                  <td style={{ fontSize:12.5, fontWeight:600 }}>{antall} <span style={{ color:SK.soft, fontWeight:400 }}>av {moduler.length}</span></td>
                  {modulFilt !== 'alle' && (
                    <td>
                      <span style={{ fontSize:11, fontWeight:700, padding:'2px 8px', borderRadius:99,
                        background:k?.bg||'transparent', color:k?.fg||SK.soft }}>{k?.label||'Ingen'}</span>
                    </td>
                  )}
                </tr>
              );
            })}
          </tbody>
        </table>
      </Card>
    </div>
  );
}

// ══════════════════════════════════════════════════════════════
// "SE SOM"-LOGG (audit)
// ══════════════════════════════════════════════════════════════

function FaneSeSomLogg() {
  const [logg,   setLogg]   = React.useState([]);
  const [laster, setLaster] = React.useState(true);
  const [feil,   setFeil]   = React.useState(null);

  React.useEffect(() => {
    window._sb.from('sesom_logg').select('*').order('created_at', { ascending: false }).limit(100)
      .then(({ data, error }) => { if (error) setFeil(error.message); else setLogg(data||[]); })
      .finally(() => setLaster(false));
  }, []);

  const fmtVarighet = (sek) => {
    if (!sek) return '';
    if (sek < 60) return `${sek}s`;
    if (sek < 3600) return `${Math.round(sek/60)} min`;
    return `${Math.round(sek/3600)} t`;
  };

  // Aktive økter akkurat nå (aktivert uten matchende deaktivering)
  const aktiveNa = (() => {
    const sisteHandling = {};
    [...logg].reverse().forEach(l => { sisteHandling[l.bruker_id] = l; });
    return Object.values(sisteHandling).filter(l => l.handling === 'aktivert');
  })();

  return (
    <div style={{ marginTop:16 }}>
      <div style={{ fontSize:12.5, color:SK.soft, lineHeight:1.5, marginBottom:14,
        padding:'10px 14px', background:SK.iceBlueLight, borderRadius:10 }}>
        Revisjonsspor for «Se som bruker». Viser hvem som har aktivert funksjonen, hvem de så systemet som, og hvor lenge.
      </div>

      {aktiveNa.length > 0 && (
        <div style={{ background:'#fcddde', border:'1.5px solid #f2545c', borderRadius:10, padding:'12px 16px', marginBottom:16 }}>
          <div style={{ fontSize:12.5, fontWeight:600, color:'#8a1620', marginBottom:6 }}>
            {aktiveNa.length} aktiv{aktiveNa.length>1?'e':''} «Se som»-økt{aktiveNa.length>1?'er':''} akkurat nå
          </div>
          {aktiveNa.map(l => (
            <div key={l.id} style={{ fontSize:12, color:'#8a1620' }}>
              {l.bruker_navn} ser som {l.sett_som_navn} (siden {new Date(l.created_at).toLocaleTimeString('nb-NO',{hour:'2-digit',minute:'2-digit'})})
            </div>
          ))}
        </div>
      )}

      {feil && <div style={{ background:'#fcddde', borderRadius:8, padding:'9px 13px', fontSize:13, color:'#8a1620', marginBottom:12 }}>{feil}</div>}

      {laster ? (
        <div style={{ padding:32, textAlign:'center', color:SK.soft, fontSize:13 }}>Laster logg…</div>
      ) : logg.length === 0 ? (
        <div style={{ padding:32, textAlign:'center', color:SK.soft, fontSize:13 }}>Ingen «Se som»-aktivitet registrert ennå.</div>
      ) : (
        <Card padded={false}>
          <table className="ok-table">
            <thead><tr>
              <th style={{ paddingLeft:18 }}>Bruker</th>
              <th>Så som</th>
              <th>Handling</th>
              <th>Varighet</th>
              <th>Tidspunkt</th>
            </tr></thead>
            <tbody>
              {logg.map(l => (
                <tr key={l.id}>
                  <td style={{ paddingLeft:18, fontSize:12.5, fontWeight:600 }}>{l.bruker_navn||'—'}</td>
                  <td style={{ fontSize:12.5 }}>{l.sett_som_navn||'—'}</td>
                  <td>
                    <span style={{ fontSize:11, fontWeight:600, padding:'2px 8px', borderRadius:99,
                      background: l.handling==='aktivert'?'#fdeac8':'#e9eef7',
                      color: l.handling==='aktivert'?'#8e5a05':'#3c4a6b' }}>
                      {l.handling==='aktivert'?'Aktiverte':'Avsluttet'}
                    </span>
                  </td>
                  <td style={{ fontSize:12, color:SK.soft }}>{fmtVarighet(l.varighet_sek)}</td>
                  <td style={{ fontSize:12, color:SK.soft }}>
                    {new Date(l.created_at).toLocaleString('nb-NO',{day:'numeric',month:'short',hour:'2-digit',minute:'2-digit'})}
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </Card>
      )}
    </div>
  );
}

Object.assign(window, { FaneBrukerTilgang, FaneSeSomLogg });
