// Vyuu admin console — MCP Catalog v2 (import + registry), Device detail drawer, Relation graph
const { Upload: UploadIcon, Plus: PlusIcon, Search: Search2, Copy: CopyIcon,
  Github: Gh2, FileText: Ft2, Database: Db2, Mail: Ml2, Terminal: Tm2, Box: Bx2,
  Slack: Sl2, Cloud: Cl2, Calendar, Briefcase, Bot: Bot2,
  Wifi: WifiIcon, Battery: BattIcon, MapPin: PinIcon, ShieldCheck,
  HardDrive: HDIcon2, Cpu: CpuIcon2, Clock: ClockIcon2,
  Plug: Plug2, ExternalLink, CheckCircle2: Check2, AlertTriangle: Alert3,
  X: XIcon2, MoreHorizontal: MH3 } = window.LucideReact;

// ─────────────────────────────────────────────────────────────────
// MCP Catalog v2 — Our catalog + Registry (searchable) + Import
// ─────────────────────────────────────────────────────────────────
const OUR_CATALOG = [
  { n:'filesystem', icon:Ft2, v:'0.6.2', pub:'Anthropic (official)', tools:6, status:'approved', scope:'Workspace roots only', users:34 },
  { n:'github', icon:Gh2, v:'1.1.0', pub:'GitHub', tools:18, status:'approved', scope:'Read-only + issues', users:41 },
  { n:'postgres', icon:Db2, v:'0.4.1', pub:'Community', tools:9, status:'review', scope:'Read replica only', users:12 },
  { n:'gmail', icon:Ml2, v:'0.2.8', pub:'Google Workspace', tools:11, status:'approved', scope:'Personal inbox', users:28 },
  { n:'shell-exec', icon:Tm2, v:'0.3.0', pub:'Community', tools:2, status:'blocked', scope:'—', users:0 },
  { n:'jira', icon:Bx2, v:'1.0.4', pub:'Atlassian', tools:14, status:'approved', scope:'All projects', users:19 },
];

// Vyuu's inbuilt registry — what admins can browse & promote to their catalog
const REGISTRY = [
  { n:'slack', icon:Sl2, v:'1.2.0', pub:'Slack (official)', tools:21, installs:'12.3k', risk:'low', desc:'Read & post to channels; manage threads, files, reminders.', tags:['chat','messaging'] },
  { n:'google-drive', icon:Cl2, v:'0.9.4', pub:'Google (official)', tools:15, installs:'28.7k', risk:'medium', desc:'List, read, write, and share Drive files and folders.', tags:['storage','files'] },
  { n:'salesforce', icon:Cl2, v:'2.1.0', pub:'Salesforce', tools:34, installs:'4.2k', risk:'medium', desc:'SOQL queries, bulk APIs, metadata & tooling access.', tags:['crm','sales'] },
  { n:'google-calendar', icon:Calendar, v:'0.5.1', pub:'Google (official)', tools:9, installs:'18.1k', risk:'low', desc:'Create, list, update events across user calendars.', tags:['calendar','productivity'] },
  { n:'stripe', icon:Bx2, v:'1.4.2', pub:'Stripe', tools:26, installs:'9.8k', risk:'medium', desc:'Query charges, customers, subscriptions; issue refunds (write-gated).', tags:['payments','finance'] },
  { n:'notion', icon:Ft2, v:'0.8.0', pub:'Notion', tools:12, installs:'15.6k', risk:'medium', desc:'Read & write pages, databases, blocks.', tags:['docs','knowledge'] },
  { n:'linear', icon:Briefcase, v:'1.1.3', pub:'Linear', tools:17, installs:'7.2k', risk:'low', desc:'Issue and project management; cycle & triage workflows.', tags:['issues','eng'] },
  { n:'shopify', icon:Bx2, v:'0.7.0', pub:'Shopify', tools:22, installs:'3.4k', risk:'medium', desc:'Orders, products, customers, fulfillment across stores.', tags:['ecom','retail'] },
  { n:'snowflake', icon:Db2, v:'0.6.8', pub:'Snowflake', tools:11, installs:'5.9k', risk:'medium', desc:'Read warehouse, schemas, run queries; write gated by role.', tags:['data','warehouse'] },
  { n:'datadog', icon:Bot2, v:'1.0.1', pub:'Datadog', tools:19, installs:'2.8k', risk:'low', desc:'Metrics, logs, monitors, incidents.', tags:['observability','ops'] },
  { n:'hubspot', icon:Cl2, v:'0.9.0', pub:'HubSpot', tools:28, installs:'6.1k', risk:'medium', desc:'Contacts, deals, companies, marketing workflows.', tags:['crm','marketing'] },
  { n:'1password', icon:ShieldCheck, v:'0.3.2', pub:'1Password', tools:6, installs:'1.2k', risk:'high', desc:'Read vault items (admin-scoped). ⚠ High risk — requires manual approval.', tags:['secrets','security'] },
];

const MCPCatalogV2 = () => {
  const [tab, setTab] = React.useState('ours'); // ours | registry
  const [query, setQuery] = React.useState('');
  const [statusFilter, setStatusFilter] = React.useState('all');
  const [importOpen, setImportOpen] = React.useState(false);
  const [catalog, setCatalog] = React.useState(OUR_CATALOG);

  const filteredOurs = catalog.filter(s =>
    (statusFilter==='all' || s.status===statusFilter) &&
    (s.n.toLowerCase().includes(query.toLowerCase()) || s.pub.toLowerCase().includes(query.toLowerCase()))
  );
  const filteredRegistry = REGISTRY.filter(s =>
    s.n.toLowerCase().includes(query.toLowerCase()) ||
    s.pub.toLowerCase().includes(query.toLowerCase()) ||
    s.tags.some(t => t.toLowerCase().includes(query.toLowerCase())) ||
    s.desc.toLowerCase().includes(query.toLowerCase())
  );

  const promoteFromRegistry = (r) => {
    setCatalog(c => [{ n:r.n, icon:r.icon, v:r.v, pub:r.pub, tools:r.tools, status:'review', scope:'pending config', users:0 }, ...c]);
    setTab('ours');
  };

  return (
    <div>
      <SectionTitle eyebrow="MCP Security · Catalog" title="Approved servers & the registry you can draw from"
        actions={<>
          <Button small icon={UploadIcon} onClick={()=>setImportOpen(true)}>Import catalog</Button>
          <Button primary small icon={PlusIcon} onClick={()=>setImportOpen(true)}>Add server</Button>
        </>}/>

      <div style={{display:'grid', gridTemplateColumns:'repeat(3,1fr)', gap:14, marginBottom:20}}>
        <KPI label="In your catalog" value={String(catalog.length)} delta={`${catalog.filter(c=>c.status==='approved').length} approved · ${catalog.filter(c=>c.status==='review').length} under review`} tone="orange"/>
        <KPI label="Registry" value="184" delta="Built-in · curated weekly" tone="ocean"/>
        <KPI label="Pending requests" value="5" delta="From users asking for new servers" tone="amber"/>
      </div>

      {/* Tab bar + controls */}
      <div style={{display:'flex', alignItems:'center', justifyContent:'space-between', gap:16, marginBottom:18, flexWrap:'wrap'}}>
        <div style={{display:'flex', gap:4, padding:4, background:theme.lineSoft, borderRadius:10}}>
          {[{k:'ours', l:'Your catalog', n:catalog.length}, {k:'registry', l:'Browse registry', n:REGISTRY.length}].map(t => (
            <button key={t.k} onClick={()=>setTab(t.k)} style={{
              padding:'7px 14px', borderRadius:7, border:'none', cursor:'pointer',
              background: tab===t.k?theme.panel:'transparent',
              color: tab===t.k?theme.ink:theme.muted,
              fontSize:13, fontWeight:600, fontFamily:theme.sans,
              boxShadow: tab===t.k ? '0 1px 3px rgba(31,42,46,.06)' : 'none',
              display:'flex', alignItems:'center', gap:6,
            }}>
              {t.l}
              <span style={{fontSize:10.5, fontFamily:theme.mono, color:theme.muted, padding:'1px 6px', background:theme.lineSoft, borderRadius:999}}>{t.n}</span>
            </button>
          ))}
        </div>

        <div style={{display:'flex', gap:10, alignItems:'center', flex:1, maxWidth:520}}>
          <div style={{position:'relative', flex:1}}>
            <Search2 size={14} color={theme.muted} style={{position:'absolute', left:12, top:10}}/>
            <input value={query} onChange={e=>setQuery(e.target.value)}
              placeholder={tab==='ours' ? 'Search your catalog…' : 'Search 184 MCP servers by name, publisher, or tag…'}
              style={{
                width:'100%', padding:'8px 12px 8px 34px', border:`1px solid ${theme.line}`, borderRadius:8,
                fontFamily:theme.sans, fontSize:13, color:theme.ink, background:theme.panel, outline:'none',
              }}/>
          </div>
          {tab==='ours' && (
            <select value={statusFilter} onChange={e=>setStatusFilter(e.target.value)} style={{
              padding:'8px 12px', border:`1px solid ${theme.line}`, borderRadius:8,
              fontFamily:theme.sans, fontSize:12.5, color:theme.ink, background:theme.panel, outline:'none', cursor:'pointer',
            }}>
              <option value="all">All statuses</option>
              <option value="approved">Approved</option>
              <option value="review">Under review</option>
              <option value="blocked">Blocked</option>
            </select>
          )}
        </div>
      </div>

      {/* Cards */}
      {tab==='ours' && (
        <div style={{display:'grid', gridTemplateColumns:'repeat(3,1fr)', gap:14}}>
          {filteredOurs.map(s => {
            const Icon = s.icon;
            const tone = s.status==='approved' ? 'orange' : s.status==='review' ? 'amber' : 'terracotta';
            return (
              <Card key={s.n}>
                <div style={{display:'flex', justifyContent:'space-between', alignItems:'flex-start', marginBottom:12}}>
                  <div style={{display:'flex', gap:12, alignItems:'center'}}>
                    <div style={{width:38, height:38, borderRadius:9, background:theme.oceanSoft, display:'flex', alignItems:'center', justifyContent:'center'}}>
                      <Icon size={18} color={theme.oceanInk} strokeWidth={1.8}/>
                    </div>
                    <div>
                      <div style={{fontFamily:theme.mono, fontSize:14, color:theme.ink, fontWeight:600}}>{s.n}</div>
                      <div style={{fontSize:11, color:theme.muted}}>v{s.v} · {s.pub}</div>
                    </div>
                  </div>
                  <Pill tone={tone}>{s.status==='review'?'UNDER REVIEW':s.status.toUpperCase()}</Pill>
                </div>
                <div style={{display:'flex', gap:16, fontSize:11.5, color:theme.muted, marginBottom:12}}>
                  <span><strong style={{color:theme.ink, fontFamily:theme.mono}}>{s.tools}</strong> tools</span>
                  <span><strong style={{color:theme.ink, fontFamily:theme.mono}}>{s.users}</strong> users</span>
                </div>
                <div style={{fontSize:12, color:theme.muted, paddingTop:12, borderTop:`1px solid ${theme.lineSoft}`, fontStyle:'italic'}}>{s.scope}</div>
              </Card>
            );
          })}
          {filteredOurs.length===0 && <EmptyState msg={query?`No servers match "${query}" in your catalog.`:'No servers yet. Browse the registry or import.'} cta="Browse registry" onClick={()=>setTab('registry')}/>}
        </div>
      )}

      {tab==='registry' && (
        <div style={{display:'grid', gridTemplateColumns:'repeat(3,1fr)', gap:14}}>
          {filteredRegistry.map(s => {
            const Icon = s.icon;
            const alreadyInCatalog = catalog.some(c => c.n===s.n);
            return (
              <Card key={s.n}>
                <div style={{display:'flex', justifyContent:'space-between', alignItems:'flex-start', marginBottom:10}}>
                  <div style={{display:'flex', gap:12, alignItems:'center'}}>
                    <div style={{width:38, height:38, borderRadius:9, background:theme.orangeSoft, display:'flex', alignItems:'center', justifyContent:'center'}}>
                      <Icon size={18} color={theme.orangeDeep} strokeWidth={1.8}/>
                    </div>
                    <div>
                      <div style={{fontFamily:theme.mono, fontSize:14, color:theme.ink, fontWeight:600}}>{s.n}</div>
                      <div style={{fontSize:11, color:theme.muted}}>v{s.v} · {s.pub}</div>
                    </div>
                  </div>
                  <RiskPill level={s.risk}/>
                </div>
                <p style={{fontSize:12, color:theme.muted, margin:'6px 0 12px', lineHeight:1.5, minHeight:32}}>{s.desc}</p>
                <div style={{display:'flex', gap:5, flexWrap:'wrap', marginBottom:14}}>
                  {s.tags.map(t => <span key={t} style={{fontSize:10.5, color:theme.muted, padding:'2px 8px', border:`1px solid ${theme.line}`, borderRadius:999, fontFamily:theme.sans}}>{t}</span>)}
                </div>
                <div style={{display:'flex', justifyContent:'space-between', alignItems:'center', paddingTop:12, borderTop:`1px solid ${theme.lineSoft}`, fontSize:11.5}}>
                  <span style={{color:theme.muted}}><strong style={{color:theme.ink, fontFamily:theme.mono}}>{s.tools}</strong> tools · {s.installs} installs</span>
                  {alreadyInCatalog
                    ? <Pill tone="orange">In catalog</Pill>
                    : <Button small primary icon={PlusIcon} onClick={()=>promoteFromRegistry(s)}>Add</Button>}
                </div>
              </Card>
            );
          })}
          {filteredRegistry.length===0 && <EmptyState msg={`No servers match "${query}" in the registry.`}/>}
        </div>
      )}

      <ImportCatalogDrawer open={importOpen} onClose={()=>setImportOpen(false)} onImported={(items)=>{
        setCatalog(c => [...items, ...c]);
        setImportOpen(false);
      }}/>
    </div>
  );
};

const EmptyState = ({msg, cta, onClick}) => (
  <div style={{gridColumn:'1 / -1', padding:'48px 24px', textAlign:'center', background:theme.panel, border:`1px dashed ${theme.line}`, borderRadius:12}}>
    <div style={{fontSize:13, color:theme.muted, marginBottom:cta?14:0}}>{msg}</div>
    {cta && <Button small primary onClick={onClick}>{cta}</Button>}
  </div>
);

// ─────────────────────────────────────────────────────────────────
// Import catalog drawer
// ─────────────────────────────────────────────────────────────────
const SAMPLE_JSON = `{
  "servers": [
    {
      "name": "internal-metabase",
      "publisher": "LLP Platform Team",
      "version": "0.1.0",
      "endpoint": "https://mcp.llp.internal/metabase",
      "tools": ["run_query", "list_dashboards"],
      "scope": "read-only"
    }
  ]
}`;

const ImportCatalogDrawer = ({open, onClose, onImported}) => {
  const [source, setSource] = React.useState('json'); // json | git | manual
  const [jsonText, setJsonText] = React.useState(SAMPLE_JSON);
  const [gitUrl, setGitUrl] = React.useState('');
  const [manualName, setManualName] = React.useState('');
  const [manualEndpoint, setManualEndpoint] = React.useState('');

  const doImport = () => {
    if (source==='manual' && manualName) {
      onImported([{ n:manualName, icon:Bx2, v:'0.1.0', pub:'Custom', tools:0, status:'review', scope:manualEndpoint||'—', users:0 }]);
    } else if (source==='json') {
      try {
        const parsed = JSON.parse(jsonText);
        const items = (parsed.servers||[]).map(s => ({ n:s.name, icon:Bx2, v:s.version||'0.1.0', pub:s.publisher||'Custom', tools:(s.tools||[]).length, status:'review', scope:s.scope||'pending', users:0 }));
        onImported(items);
      } catch { onImported([]); }
    } else {
      onImported([{ n:'imported-git-server', icon:Bx2, v:'0.1.0', pub:gitUrl||'git import', tools:0, status:'review', scope:'pending config', users:0 }]);
    }
  };

  return (
    <Drawer open={open} onClose={onClose} width={620}>
      <DrawerHeader onClose={onClose} eyebrow="MCP Security · Import" title="Bring your own MCP catalog"/>
      <div style={{flex:1, overflow:'auto', padding:24}}>
        <p style={{fontSize:13, color:theme.muted, marginTop:0, lineHeight:1.55, maxWidth:520}}>
          Add internal MCP servers built by your platform team, or ingest a catalog file your security team maintains. Every imported server starts in <strong>Under review</strong> and is not exposed to users until you approve.
        </p>

        <div style={{display:'grid', gap:8, marginTop:20}}>
          {[
            {k:'json', t:'Paste a catalog JSON', d:'Same format as `mcp-catalog.json` — 1 file, N servers.'},
            {k:'git', t:'Connect a Git source', d:'Poll a repo for `mcp-catalog.json`. Refresh hourly.'},
            {k:'manual', t:'Add a single server manually', d:'Quick when you have one endpoint to register.'},
          ].map(o => {
            const on = source===o.k;
            return (
              <button key={o.k} onClick={()=>setSource(o.k)} style={{
                textAlign:'left', padding:14, borderRadius:10, cursor:'pointer',
                border:`1px solid ${on?theme.orangeDeep:theme.line}`,
                background: on?theme.panel:theme.panel,
                boxShadow: on ? `0 0 0 3px ${theme.orangeSoft}` : 'none',
              }}>
                <div style={{display:'flex', justifyContent:'space-between', alignItems:'center', marginBottom:3}}>
                  <span style={{fontSize:13.5, color:theme.ink, fontWeight:600}}>{o.t}</span>
                  {on && <Check2 size={16} color={theme.orangeDeep}/>}
                </div>
                <div style={{fontSize:12, color:theme.muted}}>{o.d}</div>
              </button>
            );
          })}
        </div>

        <div style={{marginTop:22}}>
          {source==='json' && (
            <>
              <div style={{fontSize:12, color:theme.muted, marginBottom:6, fontWeight:600}}>Catalog JSON</div>
              <textarea value={jsonText} onChange={e=>setJsonText(e.target.value)} rows={11} style={{
                width:'100%', padding:12, border:`1px solid ${theme.line}`, borderRadius:8,
                fontFamily:theme.mono, fontSize:12, color:theme.ink, background:'#FBF8F1', outline:'none', resize:'vertical',
              }}/>
              <div style={{fontSize:11, color:theme.muted, marginTop:6}}>Drop a file or paste above. Schema: <code style={{fontFamily:theme.mono, color:theme.ink}}>{`{servers:[{name, publisher, version, endpoint, tools, scope}]}`}</code></div>
            </>
          )}
          {source==='git' && (
            <>
              <div style={{fontSize:12, color:theme.muted, marginBottom:6, fontWeight:600}}>Git repository URL</div>
              <input value={gitUrl} onChange={e=>setGitUrl(e.target.value)} placeholder="https://github.com/llp-platform/mcp-catalog" style={{
                width:'100%', padding:'10px 14px', border:`1px solid ${theme.line}`, borderRadius:8,
                fontFamily:theme.mono, fontSize:13, color:theme.ink, background:theme.panel, outline:'none',
              }}/>
              <div style={{fontSize:11, color:theme.muted, marginTop:6}}>Vyuu will look for <code style={{fontFamily:theme.mono}}>mcp-catalog.json</code> at the repo root and poll hourly.</div>
            </>
          )}
          {source==='manual' && (
            <div style={{display:'grid', gap:12}}>
              <div>
                <div style={{fontSize:12, color:theme.muted, marginBottom:6, fontWeight:600}}>Server name</div>
                <input value={manualName} onChange={e=>setManualName(e.target.value)} placeholder="internal-metabase" style={{
                  width:'100%', padding:'10px 14px', border:`1px solid ${theme.line}`, borderRadius:8,
                  fontFamily:theme.mono, fontSize:13, color:theme.ink, background:theme.panel, outline:'none',
                }}/>
              </div>
              <div>
                <div style={{fontSize:12, color:theme.muted, marginBottom:6, fontWeight:600}}>Endpoint</div>
                <input value={manualEndpoint} onChange={e=>setManualEndpoint(e.target.value)} placeholder="stdio://… or https://mcp.internal/…" style={{
                  width:'100%', padding:'10px 14px', border:`1px solid ${theme.line}`, borderRadius:8,
                  fontFamily:theme.mono, fontSize:13, color:theme.ink, background:theme.panel, outline:'none',
                }}/>
              </div>
            </div>
          )}
        </div>
      </div>
      <div style={{padding:'14px 24px', borderTop:`1px solid ${theme.line}`, background:theme.panel, display:'flex', justifyContent:'flex-end', gap:8}}>
        <Button small onClick={onClose}>Cancel</Button>
        <Button small primary icon={UploadIcon} onClick={doImport}>Import to catalog</Button>
      </div>
    </Drawer>
  );
};

Object.assign(window, {MCPCatalogV2, ImportCatalogDrawer, EmptyState});
