/**
 * @license
 * SPDX-License-Identifier: Apache-2.0
 */

import React, { useState, useMemo, useRef } from 'react';
import { parseSocialData, ParseResult, getCoreMembers, MemberMetrics, findShortestPath, UserNode, detectClusters, ClusterInfo } from './lib/parser';
import NetworkGraph from './components/NetworkGraph';

type Tab = 'analysis' | 'clusters' | 'filters' | 'logs';

export default function App() {
  const [rawData, setRawData] = useState('');
  const [analysis, setAnalysis] = useState<ParseResult | null>(null);
  const [selectedUser, setSelectedUser] = useState<MemberMetrics | null>(null);
  const [searchQuery, setSearchQuery] = useState('');
  const [minDegree, setMinDegree] = useState(2);
  const [pathTargetQuery, setPathTargetQuery] = useState('');
  const [highlightedPath, setHighlightedPath] = useState<string[] | null>(null);
  const [ignoredUsers, setIgnoredUsers] = useState<string[]>(['carterpcs', 'clavicular']);
  const [newIgnoreUser, setNewIgnoreUser] = useState('');
  const [linkFilter, setLinkFilter] = useState<'all' | 'following' | 'follower'>('all');
  const [activeTab, setActiveTab] = useState<Tab>('analysis');

  const fileInputRef = useRef<HTMLInputElement>(null);

  const handleAnalyze = () => {
    const data = parseSocialData(rawData);
    setAnalysis(data);
    setSelectedUser(null);
    setHighlightedPath(null);
  };

  const handleImport = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file) return;

    const reader = new FileReader();
    reader.onload = (event) => {
      const content = event.target?.result as string;
      if (file.name.endsWith('.json')) {
        try {
          const data = JSON.parse(content);
          // Simple validation and reconstruction of Map objects
          if (data.nodes && data.relationships) {
             const allUsers = new Map<string, UserNode>();
             data.nodes.forEach((n: any) => allUsers.set(n.username, n));
             
             const relationships = new Map<string, { following: UserNode[], followers: UserNode[] }>();
             Object.entries(data.relationships).forEach(([key, val]: [string, any]) => {
                relationships.set(key, {
                  following: val.following.map((u: string) => allUsers.get(u) || { username: u, displayName: u }),
                  followers: val.followers.map((u: string) => allUsers.get(u) || { username: u, displayName: u })
                });
             });
             setAnalysis({ allUsers, relationships, logs: [`Imported graph from ${file.name}`] });
          }
        } catch (err) {
          alert("Failed to parse JSON import.");
        }
      } else {
        setRawData(content);
        handleAnalyze();
      }
    };
    reader.readAsText(file);
  };

  const exportJSON = () => {
    if (!analysis) return;
    const exportData = {
      nodes: Array.from(analysis.allUsers.values()),
      relationships: Object.fromEntries(
        Array.from(analysis.relationships.entries()).map(([k, v]) => [
          k, 
          { following: v.following.map(x => x.username), followers: v.followers.map(x => x.username) }
        ])
      )
    };
    const blob = new Blob([JSON.stringify(exportData, null, 2)], { type: 'application/json' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = 'network_graph.json';
    a.click();
    URL.revokeObjectURL(url);
  };

  const exportCSV = () => {
    if (!analysis) return;
    let csv = "source,target,type\n";
    analysis.relationships.forEach((rels, subject) => {
        rels.following.forEach(u => csv += `${subject},${u.username},following\n`);
        rels.followers.forEach(u => csv += `${u.username},${subject},follower\n`);
    });
    const blob = new Blob([csv], { type: 'text/csv' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = 'network_edges.csv';
    a.click();
    URL.revokeObjectURL(url);
  };

  const handleFindPath = (target: string) => {
    if (!analysis || !selectedUser) return;
    const path = findShortestPath(analysis, selectedUser.username, target);
    if (path) {
      setHighlightedPath(path);
      setPathTargetQuery('');
    } else {
      alert("No path found between these nodes.");
    }
  };

  const filteredAnalysis = useMemo(() => {
    if (!analysis) return null;
    
    const ignoredSet = new Set(ignoredUsers.map(u => u.toLowerCase()));
    
    // Deep clone basic structure
    const newAllUsers = new Map<string, UserNode>();
    analysis.allUsers.forEach((node, username) => {
      if (!ignoredSet.has(username.toLowerCase())) {
        newAllUsers.set(username, node);
      }
    });

    const newRelationships = new Map<string, { following: UserNode[]; followers: UserNode[] }>();
    
    analysis.relationships.forEach((rels, subject) => {
      if (ignoredSet.has(subject.toLowerCase())) return;
      
      const filteredFollowing = rels.following.filter(u => !ignoredSet.has(u.username.toLowerCase()));
      const filteredFollowers = rels.followers.filter(u => !ignoredSet.has(u.username.toLowerCase()));
      
      newRelationships.set(subject, {
        following: filteredFollowing,
        followers: filteredFollowers
      });
    });

    return {
      allUsers: newAllUsers,
      relationships: newRelationships,
      logs: analysis.logs
    };
  }, [analysis, ignoredUsers]);

  const allMembers = useMemo(() => filteredAnalysis ? getCoreMembers(filteredAnalysis) : [], [filteredAnalysis]);
  const metricsMap = useMemo(() => new Map(allMembers.map(m => [m.username, m])), [allMembers]);
  const clusters = useMemo(() => filteredAnalysis ? detectClusters(filteredAnalysis, allMembers) : [], [filteredAnalysis, allMembers]);
  const coreMembers = useMemo(() => allMembers.slice(0, 10), [allMembers]);
  const altCandidates = useMemo(() => allMembers.filter(m => m.isAltCandidate), [allMembers]);
  
  const displayedMembers = useMemo(() => {
    if (!filteredAnalysis) return [];
    if (searchQuery.trim() === '') return coreMembers;
    const lowerQ = searchQuery.toLowerCase();
    return allMembers.filter(m => m.username.toLowerCase().includes(lowerQ)).slice(0, 20);
  }, [allMembers, coreMembers, searchQuery, filteredAnalysis]);

  const handleNodeClick = (username: string) => {
    if (!filteredAnalysis) return;
    const member = allMembers.find(m => m.username === username);
    if (member) {
      setSelectedUser(member);
      setHighlightedPath(null); // Reset path when a new base user is selected
    }
  };

  const addIgnoredUser = (username: string) => {
    const trimmed = username.trim().replace(/^@/, '');
    if (trimmed && !ignoredUsers.includes(trimmed)) {
      setIgnoredUsers([...ignoredUsers, trimmed]);
    }
    setNewIgnoreUser('');
  };

  const removeIgnoredUser = (username: string) => {
    setIgnoredUsers(ignoredUsers.filter(u => u !== username));
  };

  return (
    <div className="flex flex-col h-screen w-full bg-slate-50 font-sans text-slate-900 overflow-hidden">
      {/* Header Navigation */}
      <nav className="h-16 bg-white border-b border-slate-200 px-6 flex items-center justify-between shrink-0">
        <div className="flex items-center gap-3">
          <div className="w-8 h-8 bg-indigo-600 rounded-lg flex items-center justify-center">
            <svg className="w-5 h-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M13 10V3L4 14h7v7l9-11h-7z" />
            </svg>
          </div>
          <span className="text-xl font-bold tracking-tight text-slate-800 uppercase">
            Relationship <span className="text-indigo-600">Analyzer</span>
          </span>
        </div>
        <div className="flex items-center gap-4">
          <label className="flex items-center gap-2 cursor-pointer">
            <input 
               type="checkbox" 
               checked={minDegree > 1} 
               onChange={e => setMinDegree(e.target.checked ? 2 : 1)} 
               className="w-4 h-4 text-indigo-600 border-slate-300 rounded focus:ring-indigo-500 cursor-pointer" 
            />
            <span className="text-xs font-semibold text-slate-600">Hide 1-edge nodes</span>
          </label>
          <div className="px-3 py-1 bg-slate-100 rounded-full text-xs font-semibold text-slate-500">
            {filteredAnalysis ? `${filteredAnalysis.allUsers.size} nodes` : "Ready"}
          </div>
          <div className="flex bg-slate-100 rounded-lg p-1 border border-slate-200 shadow-inner">
            <button 
              onClick={() => setLinkFilter('all')} 
              className={`px-3 py-1 text-[10px] font-bold rounded-md transition-all ${linkFilter === 'all' ? 'bg-white text-indigo-600 shadow-sm' : 'text-slate-400 hover:text-slate-600'}`}
            >
              ALL
            </button>
            <button 
              onClick={() => setLinkFilter('following')} 
              className={`px-3 py-1 text-[10px] font-bold rounded-md transition-all ${linkFilter === 'following' ? 'bg-white text-blue-600 shadow-sm' : 'text-slate-400 hover:text-slate-600'}`}
            >
              OUT
            </button>
            <button 
              onClick={() => setLinkFilter('follower')} 
              className={`px-3 py-1 text-[10px] font-bold rounded-md transition-all ${linkFilter === 'follower' ? 'bg-white text-green-600 shadow-sm' : 'text-slate-400 hover:text-slate-600'}`}
            >
              IN
            </button>
          </div>
          <div className="flex bg-indigo-600 rounded-lg overflow-hidden shadow-sm transition hover:bg-indigo-700">
            <button onClick={() => fileInputRef.current?.click()} className="px-4 py-2 text-white text-sm font-medium border-r border-indigo-500 hover:bg-indigo-500" title="Import JSON or paste text">
              Import
            </button>
            <input type="file" ref={fileInputRef} onChange={handleImport} accept=".json,.csv,.txt" className="hidden" />
            <button onClick={exportJSON} className="px-4 py-2 text-white text-sm font-medium border-r border-indigo-500 hover:bg-indigo-500">
              Exp JSON
            </button>
            <button onClick={exportCSV} className="px-4 py-2 text-white text-sm font-medium hover:bg-indigo-500">
              Exp CSV
            </button>
          </div>
        </div>
      </nav>

      <div className="flex flex-1 overflow-hidden">
        {/* Sidebar: Parsing & Data Source */}
        <aside className="w-72 bg-white border-r border-slate-200 flex flex-col p-5 shrink-0 overflow-y-auto">
          <div className="mb-6">
            <h3 className="text-xs font-bold text-slate-400 uppercase tracking-widest mb-3">Input Source</h3>
            <textarea
              className="w-full h-48 p-3 border border-slate-200 bg-slate-50 rounded-lg mb-4 font-mono text-[11px] leading-relaxed resize-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 outline-none text-slate-600"
              placeholder="Paste raw relationship data here..."
              value={rawData}
              onChange={(e) => setRawData(e.target.value)}
            />
            <button
              onClick={handleAnalyze}
              className="w-full bg-slate-900 text-white px-4 py-3 rounded-lg text-sm font-bold shadow-sm hover:bg-slate-800 transition"
            >
              Analyze Data
            </button>
          </div>

          <div className="mb-6 h-48 overflow-y-auto">
            <h3 className="text-xs font-bold text-slate-400 uppercase tracking-widest mb-3">Ignore List (OSINT Filter)</h3>
            <div className="mb-3 flex gap-2">
               <input 
                 type="text" 
                 placeholder="Add user to ignore..." 
                 className="flex-1 text-[10px] p-2 border border-slate-200 rounded bg-slate-50 outline-none focus:ring-1 focus:ring-indigo-500"
                 value={newIgnoreUser}
                 onChange={e => setNewIgnoreUser(e.target.value)}
                 onKeyDown={e => e.key === 'Enter' && addIgnoredUser(newIgnoreUser)}
               />
               <button onClick={() => addIgnoredUser(newIgnoreUser)} className="px-2 py-1 bg-slate-200 rounded text-[10px] font-bold text-slate-600 hover:bg-slate-300 transition shrink-0">Add</button>
            </div>
            <div className="flex flex-wrap gap-1.5">
               {ignoredUsers.map(u => (
                 <div key={u} className="flex items-center gap-1 px-2 py-1 bg-slate-100 border border-slate-200 rounded text-[10px] font-medium text-slate-600 animate-in fade-in zoom-in duration-200">
                   {u}
                   <button onClick={() => removeIgnoredUser(u)} className="ml-1 text-slate-400 hover:text-red-500">
                     <svg className="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M6 18L18 6M6 6l12 12" /></svg>
                   </button>
                 </div>
               ))}
               {ignoredUsers.length === 0 && <div className="text-[10px] text-slate-400 italic">No users ignored</div>}
            </div>
          </div>

          <div className="mb-6 h-48 overflow-y-auto">
            <h3 className="text-xs font-bold text-slate-400 uppercase tracking-widest mb-3">Analysis Status</h3>
            <div className="flex flex-col gap-2">
              {analysis ? (
                <>
                  <div className="text-[11px] font-mono p-2 border-l-2 border-green-500 bg-green-50 text-green-700 tracking-tight">
                    [OK] Extracted {analysis.allUsers.size} users
                  </div>
                  <div className="text-[11px] font-mono p-2 border-l-2 border-indigo-500 bg-indigo-50 text-indigo-700 tracking-tight">
                    [OK] Identified {analysis.relationships.size} subjects
                  </div>
                  {analysis.logs.map((log, idx) => (
                    <div key={idx} className="text-[10px] font-mono p-2 border-l-2 border-slate-200 text-slate-500 tracking-tight">
                      {log}
                    </div>
                  ))}
                </>
              ) : (
                <div className="text-[11px] font-mono p-2 border-l-2 border-slate-200 text-slate-400 tracking-tight">
                  Awaiting input...
                </div>
              )}
            </div>
          </div>

          {analysis && (
            <div className="mt-auto p-4 bg-slate-900 rounded-xl text-white">
              <div className="text-xs font-medium text-slate-400 mb-1">Total Unique Nodes</div>
              <div className="text-2xl font-bold">{analysis.allUsers.size}</div>
            </div>
          )}
        </aside>

        {/* Main Visualization View */}
        <main className="flex-1 relative bg-slate-100 flex items-center justify-center p-8 overflow-hidden">
          <div className="absolute inset-0 opacity-20" style={{ backgroundImage: 'radial-gradient(#cbd5e1 1px, transparent 1px)', backgroundSize: '24px 24px' }}></div>
          
          <div className="relative w-full h-full border border-slate-200 bg-white rounded-3xl shadow-inner flex flex-col items-center justify-center z-10 p-6 overflow-hidden">
            {!filteredAnalysis || filteredAnalysis.allUsers.size === 0 ? (
              <div className="text-slate-400 font-medium tracking-wide flex flex-col items-center">
                <svg className="w-12 h-12 text-slate-200 mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="1.5" d="M13 10V3L4 14h7v7l9-11h-7z" /></svg>
                Paste data to generate visualization
              </div>
            ) : (
              <div className="w-full h-full relative">
                 <NetworkGraph 
                   data={filteredAnalysis} 
                   minDegree={minDegree} 
                   onNodeClick={handleNodeClick} 
                   highlightedNode={selectedUser ? selectedUser.username : null} 
                   metrics={metricsMap} 
                   path={highlightedPath || undefined} 
                   filter={linkFilter}
                 />
                 
                 <div className="absolute top-2 left-6 p-4 bg-white/90 backdrop-blur border border-slate-200 rounded-2xl shadow-xl w-64 z-20 pointer-events-none">
                   <div className="text-[10px] font-bold text-indigo-600 mb-1 tracking-wider uppercase">Network Summary</div>
                   <div className="text-xl font-bold mb-1 tracking-tight text-slate-800">
                     {filteredAnalysis.relationships.size} Centers
                   </div>
                   <div className="text-sm text-slate-500 mb-4 whitespace-nowrap truncate">
                     Mapped from raw data
                   </div>
                   <div className="grid grid-cols-2 gap-2 text-[10px] font-bold uppercase text-slate-600">
                     <div className="p-3 bg-slate-50 rounded-lg border border-slate-100">
                       <span className="block text-slate-400 mb-1">Nodes</span>
                       <span className="text-indigo-600 text-lg">{filteredAnalysis.allUsers.size}</span>
                     </div>
                     <div className="p-3 bg-slate-50 rounded-lg border border-slate-100">
                       <span className="block text-slate-400 mb-1">Cores</span>
                       <span className="text-indigo-600 text-lg">{coreMembers.length}</span>
                     </div>
                   </div>
                   <div className="mt-4 pt-3 border-t border-slate-100 flex flex-col gap-2">
                     <div className="flex items-center gap-2">
                       <div className="w-4 h-0.5 bg-blue-500 rounded-full"></div>
                       <span className="text-[9px] font-bold text-slate-500 uppercase tracking-tight">Outgoing / Following</span>
                     </div>
                     <div className="flex items-center gap-2">
                       <div className="w-4 h-0.5 bg-green-500 rounded-full"></div>
                       <span className="text-[9px] font-bold text-slate-500 uppercase tracking-tight">Incoming / Follower</span>
                     </div>
                   </div>
                 </div>

                 {selectedUser && (
                   <div className="absolute bottom-2 right-6 p-4 bg-indigo-50/90 backdrop-blur border border-indigo-200 rounded-2xl shadow-xl w-64 z-20">
                     <div className="flex justify-between items-start mb-1">
                       <div className="text-[10px] font-bold text-indigo-800 tracking-wider uppercase">Selected Node</div>
                       <button onClick={() => { setSelectedUser(null); setHighlightedPath(null); }} className="text-indigo-400 hover:text-indigo-700">
                         <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M6 18L18 6M6 6l12 12" /></svg>
                       </button>
                     </div>
                     <div className="text-lg font-bold mb-1 text-slate-900 truncate flex items-center justify-between" title={selectedUser.username}>
                        <span>{selectedUser.username}</span>
                        <div className="flex gap-1">
                           <a href={`https://twitter.com/${selectedUser.username}`} target="_blank" rel="noreferrer" className="p-1 bg-white rounded-md border border-indigo-100 hover:bg-indigo-50 transition" title="Search Twitter">
                             <span className="text-[10px]">𝕏</span>
                           </a>
                           <a href={`https://www.tiktok.com/@${selectedUser.username}`} target="_blank" rel="noreferrer" className="p-1 bg-white rounded-md border border-indigo-100 hover:bg-indigo-50 transition" title="Search TikTok">
                             <span className="text-[10px]">TT</span>
                           </a>
                           <a href={`https://www.google.com/search?q=%22${selectedUser.username}%22+social+media`} target="_blank" rel="noreferrer" className="p-1 bg-white rounded-md border border-indigo-100 hover:bg-indigo-50 transition" title="Google Search">
                             <span className="text-[10px]">G</span>
                           </a>
                        </div>
                      </div>
                     
                     {highlightedPath ? (
                        <div className="mt-3 p-3 bg-white rounded-lg border border-indigo-100 max-h-32 overflow-y-auto">
                           <div className="text-[10px] font-bold uppercase text-slate-400 mb-2">Shortest Path</div>
                           <div className="flex flex-col gap-1 text-xs">
                             {highlightedPath.map((u, i) => (
                               <div key={u} className="flex items-center gap-2">
                                  <div className="w-4 h-4 rounded-full bg-amber-500 text-white flex items-center justify-center text-[8px] font-bold">{i + 1}</div>
                                  <span className="font-semibold text-slate-800 truncate" title={u}>{u}</span>
                               </div>
                             ))}
                           </div>
                           <button onClick={() => setHighlightedPath(null)} className="mt-3 w-full py-1.5 text-[10px] font-bold text-slate-500 bg-slate-50 rounded hover:bg-slate-100 transition">
                             Clear Path
                           </button>
                        </div>
                     ) : (
                       <>
                         <div className="grid grid-cols-3 gap-2 mt-3 text-[10px] font-bold uppercase text-slate-600">
                            <div className="p-2 bg-white rounded-lg border border-indigo-100 flex flex-col items-center">
                               <span className="block text-slate-400 mb-1">In</span>
                               <span className="text-indigo-600 text-base">{selectedUser.inDegree}</span>
                            </div>
                            <div className="p-2 bg-white rounded-lg border border-indigo-100 flex flex-col items-center">
                               <span className="block text-slate-400 mb-1">Out</span>
                               <span className="text-indigo-600 text-base">{selectedUser.outDegree}</span>
                            </div>
                            <div className="p-2 bg-white rounded-lg border border-indigo-100 flex flex-col items-center">
                               <span className="block text-slate-400 mb-1">Mut</span>
                               <span className="text-indigo-600 text-base">{selectedUser.mutuals}</span>
                            </div>
                         </div>
                         <div className="mt-2 p-2 bg-white rounded-lg border border-indigo-100 flex justify-between items-center text-[10px] font-bold uppercase text-slate-600">
                               <span className="text-slate-400">Hub Score</span>
                               <span className="text-indigo-600 text-base">{selectedUser.score}</span>
                         </div>
                         {selectedUser.isAltCandidate && (
                           <div className="mt-3 bg-amber-100 border border-amber-200 text-amber-800 p-2 rounded-lg text-xs font-semibold flex items-center justify-between">
                              <span>Alt Candidate</span>
                              <span className="text-[10px] truncate max-w-[80px]" title={selectedUser.altOf}>Of @{selectedUser.altOf}</span>
                           </div>
                         )}
                         <div className="mt-3 pt-3 border-t border-indigo-100">
                            <div className="text-[10px] font-bold text-indigo-800 mb-2 uppercase">Relation Viewer</div>
                            <div className="flex gap-2">
                               <input 
                                 type="text" 
                                 placeholder="Find path to..." 
                                 value={pathTargetQuery}
                                 onChange={e => setPathTargetQuery(e.target.value)}
                                 className="flex-1 text-xs border border-indigo-100 rounded p-1.5 outline-none focus:ring-1 focus:ring-indigo-500"
                                 onKeyDown={e => {
                                   if (e.key === 'Enter' && pathTargetQuery.trim()) {
                                      handleFindPath(pathTargetQuery.trim());
                                   }
                                 }}
                               />
                               <button 
                                 onClick={() => pathTargetQuery.trim() && handleFindPath(pathTargetQuery.trim())}
                                 className="bg-indigo-600 text-white rounded px-2 py-1 text-xs font-bold hover:bg-indigo-700 transition"
                               >
                                 Go
                               </button>
                            </div>
                         </div>
                       </>
                     )}
                   </div>
                 )}
              </div>
            )}
          </div>
        </main>

        {/* Right Panel: Insights */}
        <section className="w-80 bg-white border-l border-slate-200 flex flex-col shrink-0 overflow-hidden">
          <div className="flex border-b border-slate-100 bg-slate-50/50 p-1">
            {(['analysis', 'clusters', 'filters', 'logs'] as Tab[]).map(t => (
              <button
                key={t}
                onClick={() => setActiveTab(t)}
                className={`flex-1 py-2 text-[10px] font-bold uppercase tracking-wider rounded-md transition-all ${activeTab === t ? 'bg-white text-indigo-600 shadow-sm border border-slate-200' : 'text-slate-400 hover:text-slate-600 hover:bg-slate-100/50'}`}
              >
                {t}
              </button>
            ))}
          </div>

          <div className="p-5 flex-1 overflow-y-auto">
            {activeTab === 'analysis' && (
              <>
                <h3 className="text-xs font-bold text-slate-400 uppercase tracking-widest mb-4">Core Network Members</h3>
                <div className="mb-4">
                    <input 
                      type="text" 
                      placeholder="Search members..." 
                      className="w-full text-xs p-2 border border-slate-200 rounded-lg outline-none focus:ring-2 focus:ring-indigo-500 bg-slate-50"
                      value={searchQuery}
                      onChange={e => setSearchQuery(e.target.value)}
                    />
                </div>
                
                {filteredAnalysis && displayedMembers.length > 0 ? (
                  <ul className="space-y-3">
                    {displayedMembers.map((m, i) => {
                       const isHub = i === 0 && searchQuery === '';
                       const isBridge = i > 0 && i < 4 && searchQuery === '';
                       const role = isHub ? 'HUB' : (isBridge ? 'BRIDGE' : 'NODE');
                       
                       return (
                          <li key={m.username} onClick={() => handleNodeClick(m.username)} className={`flex items-center gap-3 group cursor-pointer p-1 -mx-1 rounded-lg hover:bg-slate-50 transition ${selectedUser?.username === m.username ? 'bg-indigo-50/50 ring-1 ring-indigo-100' : ''}`}>
                            <div className={`w-7 h-7 rounded-sm flex items-center justify-center text-[10px] font-bold shrink-0 transition-colors
                              ${selectedUser?.username === m.username ? 'bg-indigo-600 text-white shadow-md' : 'bg-slate-100 text-slate-500 group-hover:bg-slate-200'}`}>
                              {(i + 1).toString().padStart(2, '0')}
                            </div>
                            <div className="min-w-0 flex-1">
                              <div className="text-xs font-semibold text-slate-800 truncate flex items-center gap-1" title={m.username}>
                                {m.username}
                                {m.isAltCandidate && <span className="text-[10px]" title="Alt Account">⚠️</span>}
                              </div>
                              <div className="flex items-center">
                                <span className="text-[10px] text-slate-400">{m.inDegree + m.outDegree} edges</span>
                              </div>
                            </div>
                            {searchQuery === '' && (
                                <span className={`text-[9px] font-mono font-bold px-1.5 py-0.5 rounded
                                  ${isHub ? 'bg-indigo-100 text-indigo-700' : 
                                    isBridge ? 'bg-slate-100 text-slate-600' : 'bg-transparent text-slate-400 border border-slate-200'}`}
                                >
                                  {role}
                                </span>
                            )}
                          </li>
                       );
                    })}
                  </ul>
                ) : (
                  <div className="w-full h-32 border-2 border-dashed border-slate-100 rounded-xl flex items-center justify-center">
                    <span className="text-xs font-medium text-slate-400">No members analyzed</span>
                  </div>
                )}

                {altCandidates.length > 0 && searchQuery === '' && (
                   <div className="mt-8 mb-4">
                     <h3 className="text-xs font-bold text-slate-400 uppercase tracking-widest mb-4">Alt / Dup Suspects</h3>
                     <div className="space-y-3">
                       {altCandidates.slice(0, 8).map(m => (
                           <div key={m.username} onClick={() => handleNodeClick(m.username)} className="p-3 bg-amber-50 rounded-xl border border-amber-100 cursor-pointer hover:bg-amber-100 transition">
                             <div className="flex justify-between items-start mb-2">
                               <div className="min-w-0 flex-1">
                                 <div className="text-xs font-bold text-slate-800 truncate" title={m.username}>{m.username}</div>
                               </div>
                               <div className="bg-amber-100 text-amber-700 text-[9px] font-bold px-1.5 py-0.5 rounded ml-2 shrink-0">
                                 Likely Alt
                               </div>
                             </div>
                             <div className="text-[10px] text-slate-500 mt-2 border-t border-amber-100 pt-2">
                                Similar to <span className="font-bold text-slate-800">@{m.altOf}</span>
                             </div>
                           </div>
                       ))}
                     </div>
                   </div>
                )}
              </>
            )}

            {activeTab === 'clusters' && (
              <>
                <h3 className="text-xs font-bold text-slate-400 uppercase tracking-widest mb-4">Network Clusters</h3>
                <div className="space-y-4">
                  {clusters.length > 0 ? clusters.map(c => (
                    <div key={c.center} className="p-3 bg-white border border-slate-200 rounded-xl shadow-sm hover:shadow-md transition">
                       <div className="flex items-center justify-between mb-2">
                          <div className="flex items-center gap-2">
                            <div className="w-3 h-3 rounded-full" style={{ backgroundColor: c.color }}></div>
                            <span className="text-xs font-bold text-slate-800 truncate">{c.center}'s Orbit</span>
                          </div>
                          <span className="text-[10px] font-bold text-slate-400 uppercase tracking-wider">{c.members.length} members</span>
                       </div>
                       <div className="flex flex-wrap gap-1 max-h-24 overflow-y-auto">
                          {c.members.slice(0, 15).map(m => (
                            <span 
                              key={m} 
                              onClick={() => handleNodeClick(m)}
                              className="text-[9px] px-1.5 py-0.5 bg-slate-100 text-slate-600 rounded-md border border-slate-200 hover:bg-indigo-50 hover:text-indigo-600 cursor-pointer transition"
                            >
                              {m}
                            </span>
                          ))}
                          {c.members.length > 15 && <span className="text-[9px] text-slate-400">+{c.members.length - 15} more</span>}
                       </div>
                    </div>
                  )) : (
                    <div className="text-center py-8 text-slate-400 italic text-xs">
                      No significant clusters detected. Try analyzing more subjects.
                    </div>
                  )}
                </div>
              </>
            )}

            {activeTab === 'filters' && (
               <>
                 <h3 className="text-xs font-bold text-slate-400 uppercase tracking-widest mb-3">Ignore List (OSINT Filter)</h3>
                 <div className="mb-3 flex gap-2">
                    <input 
                      type="text" 
                      placeholder="Add user to ignore..." 
                      className="flex-1 text-[10px] p-2 border border-slate-200 rounded bg-slate-50 outline-none focus:ring-1 focus:ring-indigo-500"
                      value={newIgnoreUser}
                      onChange={e => setNewIgnoreUser(e.target.value)}
                      onKeyDown={e => e.key === 'Enter' && addIgnoredUser(newIgnoreUser)}
                    />
                    <button onClick={() => addIgnoredUser(newIgnoreUser)} className="px-2 py-1 bg-slate-200 rounded text-[10px] font-bold text-slate-600 hover:bg-slate-300 transition shrink-0">Add</button>
                 </div>
                 <div className="flex flex-wrap gap-1.5 mb-8">
                    {ignoredUsers.map(u => (
                      <div key={u} className="flex items-center gap-1 px-2 py-1 bg-slate-100 border border-slate-200 rounded text-[10px] font-medium text-slate-600 animate-in fade-in zoom-in duration-200">
                        {u}
                        <button onClick={() => removeIgnoredUser(u)} className="ml-1 text-slate-400 hover:text-red-500">
                          <svg className="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M6 18L18 6M6 6l12 12" /></svg>
                        </button>
                      </div>
                    ))}
                    {ignoredUsers.length === 0 && <div className="text-[10px] text-slate-400 italic">No users ignored</div>}
                 </div>

                 <h3 className="text-xs font-bold text-slate-400 uppercase tracking-widest mb-3">Graph Display</h3>
                 <div className="space-y-4">
                    <div className="flex items-center justify-between">
                      <span className="text-[11px] font-medium text-slate-600">Minimum connections</span>
                      <div className="flex gap-2">
                         {[1, 2, 3, 5].map(v => (
                           <button 
                             key={v} 
                             onClick={() => setMinDegree(v)}
                             className={`w-7 h-7 rounded text-[10px] font-bold transition ${minDegree === v ? 'bg-indigo-600 text-white shadow-sm' : 'bg-slate-100 text-slate-400 hover:bg-slate-200'}`}
                           >
                             {v}+
                           </button>
                         ))}
                      </div>
                    </div>
                    <div className="p-3 bg-slate-50 border border-slate-200 rounded-lg text-[10px] text-slate-500 leading-relaxed italic">
                      Increasing the minimum connection requirement helps clean up the graph by removing users only tied to one subject.
                    </div>
                 </div>
               </>
            )}

            {activeTab === 'logs' && (
              <>
                <h3 className="text-xs font-bold text-slate-400 uppercase tracking-widest mb-4">Parser Logs</h3>
                <div className="space-y-1">
                  {filteredAnalysis?.logs.map((log, idx) => (
                    <div key={idx} className="text-[9px] font-mono p-2 border-l-2 border-slate-200 bg-slate-50 text-slate-500 tracking-tight break-all">
                      {log}
                    </div>
                  ))}
                  {!filteredAnalysis && (
                    <div className="text-center py-8 text-slate-400 italic text-xs font-mono">
                      No logs available.
                    </div>
                  )}
                </div>
              </>
            )}
          </div>
          
          {analysis && (
            <div className="p-5 border-t border-slate-100 flex gap-3 shrink-0 bg-slate-50">
               <button onClick={() => { setSelectedUser(null); setHighlightedPath(null); }} className="flex-1 py-2.5 text-xs font-bold text-slate-600 bg-white border border-slate-200 shadow-sm rounded-lg hover:bg-slate-50 transition cursor-pointer">
                 Clear Select
               </button>
               <button onClick={exportJSON} className="flex-1 py-2.5 text-xs font-bold text-white bg-slate-900 border border-slate-900 shadow-sm rounded-lg hover:bg-slate-800 transition cursor-pointer">
                 Save JS
               </button>
            </div>
          )}
        </section>
      </div>
    </div>
  );
}
