import React, { useState, useEffect, useRef } from 'react';
import VirtualCanvas from './components/VirtualCanvas';
import { io } from 'socket.io-client';

const socket = io('http://localhost:3000');

function App() {
  const [activeTab, setActiveTab] = useState('Dashboard');
  const [surfaces, setSurfaces] = useState([
    {
      type: 'quad',
      name: 'Screen 1',
      selected: true,
      vertices: [
        { x: 0.1, y: 0.1 },
        { x: 0.4, y: 0.1 },
        { x: 0.4, y: 0.4 },
        { x: 0.1, y: 0.4 }
      ]
    }
  ]);
  const [dragging, setDragging] = useState(null); // { type: 'vertex'|'surface', sIndex, vIndex, startPos }
  const [stats, setStats] = useState({ cpu: '0', mem: { used: '0', total: '0' }, temp: '0' });
  const [mapperStatus, setMapperStatus] = useState('unknown');
  const [logs, setLogs] = useState([]);
  const [mediaFiles, setMediaFiles] = useState([]);
  const [manifest, setManifest] = useState({ surfaces: [] });

  useEffect(() => {
    // Stats Polling
    const statsInterval = setInterval(async () => {
      try {
        const res = await fetch('http://localhost:3000/system/stats');
        const data = await res.json();
        setStats(data);
      } catch (e) {}
    }, 2000);

    // Initial Data Fetch
    fetch('http://localhost:3000/mapper/status').then(r => r.json()).then(d => setMapperStatus(d.status));
    fetch('http://localhost:3000/media').then(r => r.json()).then(d => setMediaFiles(d.files || []));
    fetch('http://localhost:3000/manifest').then(r => r.json()).then(d => setManifest(d));

    // Socket Listeners
    socket.on('mapper:status', (data) => setMapperStatus(data.status));
    socket.on('mapper:logs', (data) => {
      setLogs(prev => [...prev, ...data.logs].slice(-50));
    });

    return () => {
      clearInterval(statsInterval);
      socket.off('mapper:status');
      socket.off('mapper:logs');
    };
  }, []);

  const fetchMedia = async () => {
    const res = await fetch('http://localhost:3000/media');
    const data = await res.json();
    setMediaFiles(data.files || []);
  };

  const handleFileUpload = async (e) => {
    const file = e.target.files[0];
    if (!file) return;
    const formData = new FormData();
    formData.append('file', file);
    await fetch('http://localhost:3000/media/upload', { method: 'POST', body: formData });
    fetchMedia();
  };

  const deleteMedia = async (filename) => {
    await fetch(`http://localhost:3000/media/${filename}`, { method: 'DELETE' });
    fetchMedia();
  };

  const assignMedia = async (filename) => {
    const selectedIndex = surfaces.findIndex(s => s.selected);
    if (selectedIndex === -1) return alert('Please select a surface first');
    const surface = surfaces[selectedIndex];
    
    await fetch('http://localhost:3000/media/assign', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ surfaceIndex: selectedIndex, filename, surfaceName: surface.name })
    });
    
    const res = await fetch('http://localhost:3000/manifest');
    const data = await res.json();
    setManifest(data);
  };

  const handleVertexMouseDown = (e, sIndex, vIndex) => {
    e.stopPropagation();
    setDragging({ type: 'vertex', sIndex, vIndex });
  };

  const handleSurfaceMoveStart = (e, sIndex) => {
    e.stopPropagation();
    const svg = e.currentTarget.closest('svg');
    const rect = svg.getBoundingClientRect();
    const x = (e.clientX - rect.left) / rect.width;
    const y = (e.clientY - rect.top) / rect.height;
    setDragging({ type: 'surface', sIndex, startPos: { x, y } });
  };

  const handleMouseMove = (e) => {
    if (!dragging) return;
    const svg = e.currentTarget.querySelector('svg');
    if (!svg) return;
    const rect = svg.getBoundingClientRect();
    const x = (e.clientX - rect.left) / rect.width;
    const y = (e.clientY - rect.top) / rect.height;

    const newSurfaces = [...surfaces];
    const s = newSurfaces[dragging.sIndex];

    if (dragging.type === 'vertex') {
      const boundedX = Math.max(0, Math.min(1, x));
      const boundedY = Math.max(0, Math.min(1, y));
      s.vertices[dragging.vIndex] = { x: boundedX, y: boundedY };
      socket.emit('vertex:move', { surfaceIndex: dragging.sIndex, vertexIndex: dragging.vIndex, x: boundedX, y: boundedY });
    } else if (dragging.type === 'surface') {
      const dx = x - dragging.startPos.x;
      const dy = y - dragging.startPos.y;
      s.vertices = s.vertices.map(v => ({ x: v.x + dx, y: v.y + dy }));
      setDragging({ ...dragging, startPos: { x, y } });
      s.vertices.forEach((v, vi) => {
        socket.emit('vertex:move', { surfaceIndex: dragging.sIndex, vertexIndex: vi, x: v.x, y: v.y });
      });
    }
    setSurfaces(newSurfaces);
  };

  const handleMouseUp = () => setDragging(null);

  const handleSurfaceSelect = (sIndex) => {
    const newSurfaces = surfaces.map((s, i) => ({ ...s, selected: i === sIndex }));
    setSurfaces(newSurfaces);
    socket.emit('surface:select', { surfaceIndex: sIndex });
  };

  const addSurface = (type) => {
    const newSurface = {
      type,
      name: `New ${type}`,
      selected: true,
      vertices: type === 'quad' 
        ? [{ x: 0.4, y: 0.4 }, { x: 0.6, y: 0.4 }, { x: 0.6, y: 0.6 }, { x: 0.4, y: 0.6 }]
        : [{ x: 0.4, y: 0.4 }, { x: 0.6, y: 0.4 }, { x: 0.5, y: 0.6 }]
    };
    setSurfaces(surfaces.map(s => ({ ...s, selected: false })).concat(newSurface));
    socket.emit('surface:add', { type });
  };

  const deleteSurface = (sIndex) => {
    const newSurfaces = surfaces.filter((_, i) => i !== sIndex);
    setSurfaces(newSurfaces);
    socket.emit('surface:delete', { surfaceIndex: sIndex });
  };

  const renameSurface = (sIndex) => {
    const newName = prompt('Enter new name for surface:', surfaces[sIndex].name || `Surface ${sIndex}`);
    if (newName) {
      const newSurfaces = [...surfaces];
      newSurfaces[sIndex].name = newName;
      setSurfaces(newSurfaces);
    }
  };

  const highlightSurface = (sIndex) => {
    socket.emit('surface:highlight', { surfaceIndex: sIndex });
  };

  const renderDashboard = () => (
    <div className="space-y-6">
      <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
        <div className="bg-gray-900 p-6 rounded-xl border border-gray-800 text-center">
          <div className="text-3xl font-mono text-emerald-500">{stats.cpu}%</div>
          <div className="text-xs uppercase text-gray-500 mt-2 font-bold tracking-widest">CPU LOAD</div>
        </div>
        <div className="bg-gray-900 p-6 rounded-xl border border-gray-800 text-center">
          <div className="text-3xl font-mono text-blue-500">{stats.mem.used}MB</div>
          <div className="text-xs uppercase text-gray-500 mt-2 font-bold tracking-widest">RAM USAGE</div>
        </div>
        <div className="bg-gray-900 p-6 rounded-xl border border-gray-800 text-center">
          <div className="text-3xl font-mono text-orange-500">{stats.temp}°C</div>
          <div className="text-xs uppercase text-gray-500 mt-2 font-bold tracking-widest">CPU TEMP</div>
        </div>
      </div>
      <div className="bg-gray-900 p-6 rounded-xl border border-gray-800 flex items-center justify-between">
        <div className="flex items-center gap-4">
          <div className={`w-3 h-3 rounded-full ${mapperStatus === 'running' ? 'bg-emerald-500 animate-pulse' : 'bg-red-500'}`}></div>
          <div>
            <div className="text-lg font-bold text-white">ofxPiMapper</div>
            <div className="text-xs text-gray-500 uppercase font-bold tracking-wider">{mapperStatus}</div>
          </div>
        </div>
        <div className="flex gap-2">
          <button onClick={() => fetch('http://localhost:3000/mapper/start', { method: 'POST' })} className="bg-emerald-600 hover:bg-emerald-500 px-4 py-2 rounded-md text-xs font-bold uppercase transition-colors">Start</button>
          <button onClick={() => fetch('http://localhost:3000/mapper/stop', { method: 'POST' })} className="bg-red-600 hover:bg-red-500 px-4 py-2 rounded-md text-xs font-bold uppercase transition-colors">Stop</button>
          <button onClick={() => fetch('http://localhost:3000/mapper/restart', { method: 'POST' })} className="bg-orange-600 hover:bg-orange-500 px-4 py-2 rounded-md text-xs font-bold uppercase transition-colors">Restart</button>
        </div>
      </div>
    </div>
  );

  const renderMapping = () => (
    <div className="grid grid-cols-1 lg:grid-cols-4 gap-6">
      <div className="lg:col-span-3 space-y-4">
        <div className="relative bg-gray-950 rounded-lg overflow-hidden aspect-video border border-gray-800"
             onMouseMove={handleMouseMove} onMouseUp={handleMouseUp} onMouseLeave={handleMouseUp}>
          <VirtualCanvas 
            surfaces={surfaces} 
            onVertexMove={handleVertexMouseDown} 
            onSurfaceSelect={handleSurfaceSelect}
            onSurfaceMoveStart={handleSurfaceMoveStart}
          />
        </div>
        <div className="flex gap-4">
          <button onClick={() => addSurface('quad')} className="bg-blue-600 hover:bg-blue-500 px-6 py-3 rounded-lg text-sm font-bold transition-all shadow-lg">+ Add Quad</button>
          <button onClick={() => addSurface('triangle')} className="bg-emerald-600 hover:bg-emerald-500 px-6 py-3 rounded-lg text-sm font-bold transition-all shadow-lg">+ Add Triangle</button>
          <button onClick={() => fetch('http://localhost:3000/mapper/save', { method: 'POST' })} className="bg-purple-600 hover:bg-purple-500 px-6 py-3 rounded-lg text-sm font-bold transition-all ml-auto flex items-center gap-2">
            💾 Save Mapping
          </button>
        </div>
      </div>
      <div className="space-y-4">
        <h3 className="text-[10px] font-bold uppercase tracking-widest text-gray-500">Surface Hierarchy</h3>
        <div className="space-y-2 max-h-[500px] overflow-y-auto pr-2 custom-scrollbar">
          {surfaces.map((s, i) => (
            <div key={i} className={`p-4 rounded-xl border transition-all cursor-pointer ${s.selected ? 'bg-blue-600/10 border-blue-500' : 'bg-gray-900 border-gray-800 hover:border-gray-700'}`}
                 onClick={() => handleSurfaceSelect(i)}>
              <div className="flex justify-between items-center mb-3">
                <div className="flex flex-col">
                  <span className="font-bold text-xs">{s.name || `Surface ${i}`}</span>
                  <span className="text-[9px] uppercase tracking-widest text-gray-500 font-mono">{s.type}</span>
                </div>
                <button onClick={(e) => { e.stopPropagation(); deleteSurface(i); }} className="text-gray-600 hover:text-red-500">✕</button>
              </div>
              <div className="flex gap-2">
                <button onClick={(e) => { e.stopPropagation(); highlightSurface(i); }} className="flex-1 bg-gray-800 hover:bg-gray-700 py-1 rounded text-[9px] uppercase font-bold tracking-widest">Highlight</button>
                <button onClick={(e) => { e.stopPropagation(); renameSurface(i); }} className="flex-1 bg-gray-800 hover:bg-gray-700 py-1 rounded text-[9px] uppercase font-bold tracking-widest text-blue-400">Rename</button>
              </div>
            </div>
          ))}
        </div>
      </div>
    </div>
  );

  const renderMedia = () => (
    <div className="grid grid-cols-1 md:grid-cols-2 gap-8">
      <div className="bg-gray-900 rounded-xl border border-gray-800 p-6 space-y-4">
        <h2 className="text-xl font-bold">Media Vault</h2>
        <div className="grid grid-cols-2 gap-4">
          {mediaFiles.map((f, i) => (
            <div key={i} className="bg-gray-800 p-4 rounded-lg flex flex-col items-center gap-3 border border-transparent hover:border-blue-500 transition-all cursor-pointer group">
              <div className="w-full aspect-video bg-black/50 rounded flex items-center justify-center text-gray-600">
                <svg className="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M15 10l4.553-2.276A1 1 0 0121 8.618v6.764a1 1 0 01-1.447.894L15 14M5 18h8a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v8a2 2 0 002 2z" /></svg>
              </div>
              <span className="text-[10px] font-medium truncate w-full text-center">{f}</span>
              <div className="flex gap-2 opacity-0 group-hover:opacity-100 transition-opacity">
                <button onClick={() => assignMedia(f)} className="text-[9px] bg-blue-600 px-2 py-1 rounded font-bold uppercase">Assign</button>
                <button onClick={() => deleteMedia(f)} className="text-[9px] bg-red-600 px-2 py-1 rounded font-bold uppercase">Delete</button>
              </div>
            </div>
          ))}
          <label className="border-2 border-dashed border-gray-700 hover:border-blue-500/50 hover:bg-blue-500/5 aspect-video rounded-lg flex flex-col items-center justify-center cursor-pointer transition-all group">
            <svg className="w-8 h-8 text-gray-600 group-hover:text-blue-500 mb-2" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M12 4v16m8-8H4" /></svg>
            <span className="text-[10px] text-gray-500 group-hover:text-blue-500 font-bold uppercase">Upload</span>
            <input type="file" className="hidden" onChange={handleFileUpload} />
          </label>
        </div>
      </div>
      <div className="bg-gray-900 rounded-xl border border-gray-800 p-6">
        <h2 className="text-xl font-bold mb-4">Live Assignment</h2>
        <div className="space-y-4">
          {manifest.surfaces.length === 0 ? (
            <div className="text-sm text-gray-500 italic">No media assigned yet. Select a surface in Mapping tab and click Assign here.</div>
          ) : (
            manifest.surfaces.map((s, i) => (
              <div key={i} className="flex justify-between items-center p-3 bg-black/30 border border-gray-800 rounded-lg">
                <div className="flex flex-col">
                  <span className="text-sm font-bold">{s.name}</span>
                  <span className="text-[10px] text-gray-500 font-mono">{s.source}</span>
                </div>
                <div className="text-[9px] font-bold text-blue-500 uppercase tracking-widest bg-blue-500/10 px-2 py-1 rounded">Active</div>
              </div>
            ))
          )}
        </div>
      </div>
    </div>
  );

  const [networks, setNetworks] = useState([]);
  const [isScanning, setIsScanning] = useState(false);

  const scanWiFi = async () => {
    setIsScanning(true);
    try {
      const res = await fetch('http://localhost:3000/network/scan');
      const data = await res.json();
      setNetworks(data.networks || []);
    } catch (e) {}
    setIsScanning(false);
  };

  const connectToWiFi = async (ssid) => {
    const password = prompt(`Enter password for ${ssid}:`);
    if (password === null) return;
    await fetch('http://localhost:3000/network/connect', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ ssid, password })
    });
    alert(`Connecting to ${ssid}...`);
  };

  const [apSsid, setApSsid] = useState('MPVJ-AP');
  const [apPass, setApPass] = useState('');
  const [isRebooting, setIsRebooting] = useState(false);

  const updateAP = async () => {
    if (apPass.length > 0 && apPass.length < 8) return alert('Password must be at least 8 characters');
    if (!confirm('The system will reboot to apply changes. Continue?')) return;
    
    setIsRebooting(true);
    await fetch('http://localhost:3000/network/ap/update', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ ssid: apSsid, password: apPass })
    });
  };

  if (isRebooting) {
    return (
      <div className="min-h-screen bg-black text-white flex flex-col items-center justify-center space-y-6">
        <div className="w-16 h-16 border-4 border-blue-600 border-t-transparent rounded-full animate-spin"></div>
        <div className="text-center">
          <h1 className="text-2xl font-bold mb-2">System Rebooting...</h1>
          <p className="text-gray-500 max-w-xs">Applying new network settings. Please reconnect to the new WiFi SSID in about 60 seconds.</p>
        </div>
      </div>
    );
  }

  const renderNetwork = () => (
    <div className="max-w-2xl mx-auto space-y-6">
      <div className="bg-gray-900 p-6 rounded-xl border border-gray-800">
        <h2 className="text-xl font-bold mb-4 flex justify-between items-center">
          <span>WiFi Client (Venue)</span>
          <button onClick={scanWiFi} className={`text-[10px] bg-gray-800 hover:bg-gray-700 px-3 py-1 rounded uppercase font-bold tracking-widest transition-all ${isScanning ? 'animate-pulse' : ''}`}>
            {isScanning ? 'Scanning...' : 'Scan Networks'}
          </button>
        </h2>
        <div className="space-y-2">
          {networks.length === 0 ? (
            <div className="text-center py-8 text-gray-600 italic text-sm">No networks found. Click Scan to start.</div>
          ) : (
            networks.map((n, i) => (
              <div key={i} className="flex justify-between items-center p-4 bg-black/30 border border-gray-800 rounded-lg hover:border-gray-600 cursor-pointer group transition-all"
                   onClick={() => connectToWiFi(n.ssid)}>
                <div className="flex items-center gap-3">
                  <svg className="w-4 h-4 text-gray-500" fill="currentColor" viewBox="0 0 20 20"><path fillRule="evenodd" d="M17.707 9.293a1 1 0 010 1.414l-7 7a1 1 0 01-1.414 0l-7-7a1 1 0 011.414-1.414L10 14.586l6.293-6.293a1 1 0 011.414 0z" clipRule="evenodd" /></svg>
                  <span className="text-sm font-medium">{n.ssid}</span>
                </div>
                <div className="flex items-center gap-4">
                  <span className={`text-xs font-mono font-bold ${n.strength > 70 ? 'text-emerald-500' : 'text-blue-500'}`}>{n.strength}%</span>
                  <button className="text-[9px] bg-blue-600 hover:bg-blue-500 px-3 py-1 rounded font-bold uppercase opacity-0 group-hover:opacity-100 transition-all">Connect</button>
                </div>
              </div>
            ))
          )}
        </div>
      </div>
      <div className="bg-gray-900 p-6 rounded-xl border border-gray-800">
        <h2 className="text-xl font-bold mb-4">AP Configuration</h2>
        <div className="space-y-4">
          <div className="grid grid-cols-2 gap-4">
            <div>
              <label className="text-[10px] font-bold text-gray-500 uppercase block mb-1">SSID</label>
              <input type="text" className="w-full bg-black border border-gray-800 rounded px-3 py-2 text-sm focus:border-blue-500 outline-none text-white" value={apSsid} onChange={e => setApSsid(e.target.value)} />
            </div>
            <div>
              <label className="text-[10px] font-bold text-gray-500 uppercase block mb-1">Password</label>
              <input type="password" className="w-full bg-black border border-gray-800 rounded px-3 py-2 text-sm focus:border-blue-500 outline-none text-white" placeholder="Min 8 chars" value={apPass} onChange={e => setApPass(e.target.value)} />
            </div>
          </div>
          <button onClick={updateAP} className="w-full bg-blue-600 hover:bg-blue-500 py-3 rounded-lg font-bold uppercase text-[10px] tracking-widest transition-all">Update & Reboot</button>
        </div>
      </div>
    </div>
  );

  const renderSystem = () => (
    <div className="space-y-6">
      <div className="grid grid-cols-2 gap-6">
        <button onClick={() => fetch('http://localhost:3000/system/reboot', { method: 'POST' })} className="bg-orange-600/5 hover:bg-orange-600/10 border border-orange-600/20 p-8 rounded-2xl flex flex-col items-center gap-4 transition-all group">
          <div className="p-4 bg-orange-600/20 rounded-full group-hover:scale-110 transition-transform">
            <svg className="w-8 h-8 text-orange-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" /></svg>
          </div>
          <span className="text-sm font-bold uppercase tracking-widest text-orange-500">System Reboot</span>
        </button>
        <button onClick={() => fetch('http://localhost:3000/system/shutdown', { method: 'POST' })} className="bg-red-600/5 hover:bg-red-600/10 border border-red-600/20 p-8 rounded-2xl flex flex-col items-center gap-4 transition-all group">
          <div className="p-4 bg-red-600/20 rounded-full group-hover:scale-110 transition-transform">
            <svg className="w-8 h-8 text-red-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M18.364 5.636l-3.536 3.536m0 5.656L18.364 18.364M5.636 18.364l3.536-3.536m0-5.656L5.636 5.636M10.586 7.586a2 2 0 112.828 2.828l-2.828-2.828zm2.828 6l2.828 2.828a2 2 0 11-2.828-2.828l2.828-2.828z" /></svg>
          </div>
          <span className="text-sm font-bold uppercase tracking-widest text-red-500">System Shutdown</span>
        </button>
      </div>
      <div className="bg-gray-900 border border-gray-800 rounded-xl overflow-hidden flex flex-col h-[400px]">
        <div className="bg-gray-800 px-4 py-2 flex justify-between items-center border-b border-gray-700">
          <span className="text-[10px] font-bold uppercase tracking-widest text-gray-400">ofxPiMapper Live Logs</span>
          <button onClick={() => setLogs([])} className="text-[9px] text-gray-500 hover:text-white uppercase font-bold">Clear</button>
        </div>
        <div className="p-4 font-mono text-[10px] overflow-y-auto space-y-1 bg-black/50 flex-1 custom-scrollbar">
          {logs.map((log, i) => <div key={i} className="text-gray-400"><span className="text-blue-500/50">[{new Date().toLocaleTimeString()}]</span> {log}</div>)}
          {logs.length === 0 && <div className="text-gray-600 italic">No logs received yet...</div>}
        </div>
      </div>
    </div>
  );

  return (
    <div className="min-h-screen bg-black text-white flex flex-col font-sans">
      <header className="border-b border-gray-800 p-4 flex flex-col sm:flex-row justify-between items-center bg-gray-950/80 backdrop-blur-md sticky top-0 z-50 gap-4">
        <div className="flex items-center gap-3">
          <div className="bg-blue-600 p-1.5 rounded-lg shadow-lg shadow-blue-900/40">
            <svg className="w-5 h-5 text-white" fill="currentColor" viewBox="0 0 20 20"><path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm1-11a1 1 0 10-2 0v2H7a1 1 0 100 2h2v2a1 1 0 102 0v-2h2a1 1 0 100-2h-2V7z" clipRule="evenodd" /></svg>
          </div>
          <h1 className="text-lg font-black tracking-tighter uppercase">Modern PocketVJ</h1>
        </div>
        <div className="flex bg-gray-900 p-1 rounded-xl border border-gray-800 shadow-inner">
          {['Dashboard', 'Mapping', 'Media', 'Network', 'System'].map(tab => (
            <button key={tab} onClick={() => setActiveTab(tab)}
                    className={`px-4 py-2 rounded-lg text-[10px] font-bold uppercase tracking-widest transition-all ${activeTab === tab ? 'bg-gray-800 text-white shadow-md' : 'text-gray-500 hover:text-gray-300'}`}>
              {tab}
            </button>
          ))}
        </div>
      </header>

      <main className="flex-1 p-6 max-w-7xl mx-auto w-full">
        {activeTab === 'Dashboard' && renderDashboard()}
        {activeTab === 'Mapping' && renderMapping()}
        {activeTab === 'Media' && renderMedia()}
        {activeTab === 'Network' && renderNetwork()}
        {activeTab === 'System' && renderSystem()}
      </main>

      <footer className="p-4 border-t border-gray-800 bg-gray-950/50 text-center text-[9px] text-gray-600 font-bold tracking-[0.3em] uppercase">
        Pi 3B Appliance // mpvj.local // eth0: dhcp // wlan0: 192.168.4.1
      </footer>
    </div>
  );
}

export default App;
