// SCREEN: Identity Graph
const IdentityScreen = () => {
  const [selected, setSelected] = React.useState('act_7d1e8');
  const [actorIdInput, setActorIdInput] = React.useState('act_7d1e8');
  const [actorData, setActorData] = React.useState(null); // null = fall back to local actors array
  const [searching, setSearching] = React.useState(false);
  const [demoToast, setDemoToast] = React.useState(null);
  // FIX: ref to cancel in-flight lookup when a newer one starts (async race)
  const lookupAbortRef = React.useRef(null);

  const lookupActor = (id) => {
    if (!id || !id.trim()) return;
    // Cancel any previous in-flight request
    if (lookupAbortRef.current) { lookupAbortRef.current.abort(); }
    const ac = new AbortController();
    lookupAbortRef.current = ac;
    setSearching(true);
    arFetch('/v1/identities/actor/' + encodeURIComponent(id.trim()), { signal: ac.signal })
      .then(data => {
        if (ac.signal.aborted) return; // superseded by a newer click — discard
        setActorData({
          id: data.actor_id || id,
          type: data.actor_type || 'user',
          keys: (data.identity_keys || []).length,
          conf: typeof data.confidence === 'number' ? data.confidence : 0.9,
          firstSeen: data.first_seen ? new Date(data.first_seen).toLocaleDateString() : '—',
          lastSeen: data.last_seen ? new Date(data.last_seen).toLocaleString() : 'now',
        });
        setSelected(id.trim());
        setDemoToast('Actor data loaded');  setTimeout(() => setDemoToast(null), 2000);
        if (data.identity_keys && data.identity_keys.length > 0) {
          setDisplayKeys(data.identity_keys.slice(0, 5).map((k, i) => ({
            type: k.key_type || 'unknown',
            label: k.hashed_value ? k.hashed_value.slice(-6) : '...',
            src: k.source || 'api',
            angle: [-90, -30, 40, 100, 170][i] || 0,
            dist: [90, 95, 90, 85, 90][i] || 90,
          })));
        } else {
          setDisplayKeys(keys);
        }
      })
      .catch(err => {
        if (err && err.name === 'AbortError') return; // superseded — ignore
        setActorData(null); setDemoToast('Demo mode — showing sample actor data'); setTimeout(() => setDemoToast(null), 3000);
      }) // fall back to local actors array
      .finally(() => { if (!ac.signal.aborted) setSearching(false); });
  };

  React.useEffect(() => { lookupActor('act_7d1e8'); }, []);

  // Central + satellite layout
  const W = 900, H = 460;
  const cx = W / 2, cy = H / 2;

  // Actor clusters
  const actors = [
    { id: 'act_7d1e8', x: cx,        y: cy,        type: 'user',   keys: 5, conf: 0.96, label: 'Known user' },
    { id: 'act_91ae3', x: cx - 260,  y: cy - 110,  type: 'user',   keys: 4, conf: 0.92, label: 'Known user' },
    { id: 'act_4b02a', x: cx + 240,  y: cy - 130,  type: 'device', keys: 2, conf: 0.78, label: 'Device' },
    { id: 'act_2c938', x: cx + 250,  y: cy + 120,  type: 'anonymous', keys: 1, conf: 0.42, label: 'Anonymous' },
    { id: 'act_b19c2', x: cx - 240,  y: cy + 130,  type: 'device', keys: 2, conf: 0.71, label: 'Device' },
  ];

  // Identity keys (satellites) around selected
  const keys = [
    { type: 'email_hash',  label: '...9d4a', src: 'form_submit', angle: -90, dist: 90 },
    { type: 'device_id',   label: 'ios_fb2c', src: 'sdk',        angle: -30, dist: 95 },
    { type: 'cookie_id',   label: 'gcl_3f8b', src: 'web',        angle: 40,  dist: 90 },
    { type: 'phone_hash',  label: '...71ce', src: 'checkout',    angle: 100, dist: 85 },
    { type: 'customer_id', label: 'cu_4928', src: 'crm_sync',    angle: 170, dist: 90 },
  ];
  const [displayKeys, setDisplayKeys] = React.useState(keys);

  const selActor = actors.find(a => a.id === selected) || actors[0];

  const typeFill = { user: '#8B5CF6', device: '#22D3EE', anonymous: '#6B7489' };
  const typeStroke = { user: '#c4b5fd', device: '#67e8f9', anonymous: '#A8B0C2' };

  return (
    <React.Fragment>
    <div style={{display: 'flex', gap: 14, height: '100%'}}>
      <div style={{flex: 1, minWidth: 0}}>
        <div style={{display: 'flex', gap: 10, marginBottom: 14, alignItems: 'center'}}>
          <div style={{flex: 1, position: 'relative', maxWidth: 440, display: 'flex', gap: 8}}>
            <div style={{flex: 1, position: 'relative'}}>
              <Icon name="search" size={14} style={{position: 'absolute', left: 10, top: 9, color: 'var(--text-3)'}} />
              <input
                placeholder="Actor ID, e.g. act_7d1e8 or UUID"
                value={actorIdInput}
                onChange={e => setActorIdInput(e.target.value)}
                onKeyDown={e => { if (e.key === 'Enter') lookupActor(actorIdInput); }}
                style={{width: '100%', padding: '8px 12px 8px 32px', background: 'var(--bg-2)', border: '1px solid var(--border)', borderRadius: 8, color: 'var(--text-1)', fontSize: 12, outline: 'none'}}
              />
            </div>
            <button className="btn primary" onClick={() => lookupActor(actorIdInput)} disabled={searching} style={{flexShrink: 0}}>
              {searching ? 'Looking up…' : 'Look up'}
            </button>
          </div>
          <span className="mono" style={{fontSize: 11, color: 'var(--text-3)'}}>
            84,210 actors · 312K keys · 67% resolution rate · avg conf 0.81
          </span>
        </div>

        <div className="card" style={{padding: 0, overflow: 'hidden'}}>
          <svg viewBox={`0 0 ${W} ${H}`} width="100%" height={H} style={{display: 'block', background: 'radial-gradient(ellipse at center, #11172a 0%, #0B0F1A 100%)'}}>
            {/* Concentric rings around selected */}
            {[60, 95, 130].map((r, i) => (
              <circle key={i} cx={selActor.x} cy={selActor.y} r={r} fill="none" stroke="#1f2738" strokeDasharray="2 4" />
            ))}

            {/* Lines between actors (cross-device links) */}
            {[
              [actors[0], actors[1]],
              [actors[0], actors[2]],
              [actors[0], actors[4]],
              [actors[1], actors[4]],
              [actors[2], actors[3]],
            ].map(([a, b], i) => (
              <line key={i} x1={a.x} y1={a.y} x2={b.x} y2={b.y} stroke="#2E3649" strokeWidth="1" strokeDasharray="3 4" opacity="0.6" />
            ))}

            {/* Satellite keys around selected */}
            {displayKeys.map((k, i) => {
              const ang = (k.angle * Math.PI) / 180;
              const kx = selActor.x + Math.cos(ang) * k.dist;
              const ky = selActor.y + Math.sin(ang) * k.dist;
              return (
                <g key={i}>
                  <line x1={selActor.x} y1={selActor.y} x2={kx} y2={ky} stroke="#8B5CF6" strokeWidth="1" opacity="0.5" />
                  <circle cx={kx} cy={ky} r="8" fill="#1A2030" stroke="#8B5CF6" strokeWidth="1.5" />
                  <text x={kx} y={ky + 20} textAnchor="middle" fontSize="9" fill="#A8B0C2" fontFamily="var(--mono)">{k.type}</text>
                  <text x={kx} y={ky + 32} textAnchor="middle" fontSize="9" fill="#6B7489" fontFamily="var(--mono)">{k.label}</text>
                </g>
              );
            })}

            {/* Actors */}
            {actors.map(a => {
              const sel = a.id === selected;
              const r = a.id === selected ? 22 : 16;
              return (
                <g key={a.id} onClick={() => { setSelected(a.id); setActorIdInput(a.id); lookupActor(a.id); }} style={{cursor: 'pointer'}}>
                  {sel && <circle cx={a.x} cy={a.y} r={r + 4} fill="none" stroke="#8B5CF6" opacity="0.4"><animate attributeName="r" from={r+2} to={r+10} dur="1.6s" repeatCount="indefinite" /><animate attributeName="opacity" from="0.5" to="0" dur="1.6s" repeatCount="indefinite" /></circle>}
                  <circle cx={a.x} cy={a.y} r={r} fill={typeFill[a.type]} stroke={typeStroke[a.type]} strokeWidth={sel ? 2 : 1} opacity={sel ? 1 : 0.8} />
                  <text x={a.x} y={a.y + 4} textAnchor="middle" fontSize="10" fill="white" fontFamily="var(--mono)" fontWeight="600">{a.keys}</text>
                  <text x={a.x} y={a.y + r + 14} textAnchor="middle" fontSize="10" fill="#F4F6FB" fontFamily="var(--mono)">{a.id}</text>
                  <text x={a.x} y={a.y + r + 26} textAnchor="middle" fontSize="9" fill="#6B7489">{a.label} · conf {a.conf}</text>
                </g>
              );
            })}

            {/* Legend */}
            <g transform="translate(20, 20)">
              <rect width="200" height="78" rx="6" fill="rgba(11,15,26,0.8)" stroke="#232A3B" />
              <text x="12" y="18" fontSize="10" fill="#6B7489" fontFamily="var(--mono)" style={{textTransform: 'uppercase', letterSpacing: '0.05em'}}>Actor types</text>
              <circle cx="22" cy="36" r="5" fill="#8B5CF6" /><text x="34" y="40" fontSize="10" fill="#F4F6FB">Known user</text>
              <circle cx="22" cy="54" r="5" fill="#22D3EE" /><text x="34" y="58" fontSize="10" fill="#F4F6FB">Device</text>
              <circle cx="22" cy="72" r="5" fill="#6B7489" /><text x="34" y="76" fontSize="10" fill="#F4F6FB">Anonymous</text>
            </g>
          </svg>
        </div>
      </div>

      <div style={{width: 320, flexShrink: 0, display: 'flex', flexDirection: 'column', gap: 14}}>
        {(() => {
          const d = actorData || selActor;
          return (
        <div className="card">
          <div style={{display: 'flex', gap: 8, alignItems: 'center', marginBottom: 8}}>
            <span className="badge violet">{(d.type || 'user').toUpperCase()}</span>
            <span className="mono" style={{fontSize: 11, color: 'var(--text-3)'}}>conf {d.conf}</span>
          </div>
          <div className="mono" style={{fontSize: 14, color: 'var(--text-1)', marginBottom: 4}}>{d.id}</div>
          <div style={{fontSize: 11, color: 'var(--text-3)'}}>
            First seen {d.firstSeen || '2025-11-03'} · Last seen {d.lastSeen || '2m ago'}
          </div>
        </div>
          );
        })()}

        <div className="card">
          <div className="card-title" style={{marginBottom: 10}}>Identity keys ({displayKeys.length})</div>
          <div style={{display: 'flex', flexDirection: 'column', gap: 6}}>
            {displayKeys.map((k, i) => (
              <div key={i} style={{display: 'flex', gap: 8, alignItems: 'center', padding: '6px 8px', background: 'var(--bg-3)', borderRadius: 6}}>
                <span className="mono" style={{fontSize: 10, color: 'var(--text-2)', flex: 1}}>{k.type}</span>
                <span className="mono" style={{fontSize: 10, color: 'var(--text-3)'}}>{k.label}</span>
                <span className="badge">{k.src}</span>
              </div>
            ))}
          </div>
        </div>

        <div className="card">
          <div className="card-title" style={{marginBottom: 10}}>Consent</div>
          <div style={{display: 'flex', flexDirection: 'column', gap: 6, fontSize: 11}}>
            <div style={{display: 'flex', justifyContent: 'space-between'}}><span style={{color: 'var(--text-2)'}}>Analytics</span><span className="badge green">granted</span></div>
            <div style={{display: 'flex', justifyContent: 'space-between'}}><span style={{color: 'var(--text-2)'}}>Marketing</span><span className="badge green">granted</span></div>
            <div style={{display: 'flex', justifyContent: 'space-between'}}><span style={{color: 'var(--text-2)'}}>Personalization</span><span className="badge amber">pending</span></div>
          </div>
        </div>

        <button className="btn primary" style={{justifyContent: 'center'}}
          onClick={() => { if (window.AR_NAVIGATE) window.AR_NAVIGATE('journey'); }}>
          View journey for this actor <Icon name="arrow-right" size={12} />
        </button>
      </div>
    </div>
    {demoToast && (
      <div style={{position:'fixed',bottom:24,right:24,zIndex:2000,padding:'10px 18px',background:'var(--bg-3)',border:'1px solid var(--border)',color:'var(--text-2)',borderRadius:8,fontSize:12,boxShadow:'0 4px 20px rgba(0,0,0,0.4)'}}>
        ℹ {demoToast}
      </div>
    )}
    </React.Fragment>
  );
};

window.IdentityScreen = IdentityScreen;
