import { useEffect, useState, useCallback } from 'react';
import { PageParseAPI, getAirgapMode, setAirgapMode, subscribeToJobs, API_BASE_URL } from './services/api';
import type { Task, PageRecord } from './services/api';
import { FileUploader } from './components/FileUploader';
import { CodeEditor } from './components/CodeEditor';
import { TaskList } from './components/TaskList';
import { TelemetryPanel } from './components/TelemetryPanel';
import { PageHistory } from './components/PageHistory';
import { PageDetails } from './components/PageDetails';
import { ChatPanel } from './components/ChatPanel';
import {
  ScanFace, Upload, Database, History, MessageSquare, Code, Cpu,
  Wifi, WifiOff, Sun, Moon, Settings
} from 'lucide-react';

type View = 'upload' | 'tasks' | 'history' | 'chat' | 'code';

function App() {
  const [tasks, setTasks] = useState<Task[]>([]);
  const [pages, setPages] = useState<PageRecord[]>([]);
  const [isAirgapped, setIsAirgapped] = useState(getAirgapMode());
  const [serverOnline, setServerOnline] = useState(false);
  const [isProcessing, setIsProcessing] = useState(false);
  const [selectedPage, setSelectedPage] = useState<PageRecord | null>(null);
  const [activeView, setActiveView] = useState<View>('upload');
  const [isDarkMode, setIsDarkMode] = useState(() => {
    const saved = localStorage.getItem('pageparse_theme');
    if (saved) return saved === 'dark';
    return window.matchMedia('(prefers-color-scheme: dark)').matches;
  });
  const [showSettings, setShowSettings] = useState(false);
  const [webhookUrl, setWebhookUrl] = useState('');
  const [webhookConfigured, setWebhookConfigured] = useState(false);

  const loadData = useCallback(async () => {
    try {
      const [allTasks, allPages] = await Promise.all([
        PageParseAPI.getTasks(),
        PageParseAPI.getPages(),
      ]);
      setTasks(allTasks);
      setPages(allPages);
      if (selectedPage) {
        const updated = allPages.find(p => p.id === selectedPage.id);
        if (updated) setSelectedPage(updated);
      }
    } catch (err) {
      console.error('Error loading data:', err);
    }
  }, [selectedPage]);

  const checkConnectivity = useCallback(async () => {
    if (isAirgapped) { setServerOnline(false); return; }
    setServerOnline(await PageParseAPI.checkServerConnection());
  }, [isAirgapped]);

  useEffect(() => {
    const unsub = subscribeToJobs((jobs) => {
      const processing = jobs.some(j => j.status !== 'saved' && j.status !== 'failed');
      setIsProcessing(processing);
      if (jobs.some(j => j.status === 'saved')) loadData();
    });
    return () => unsub();
  }, [loadData]);

  useEffect(() => {
    checkConnectivity();
    loadData();
    const interval = setInterval(() => { if (!isAirgapped) checkConnectivity(); }, 10000);
    return () => clearInterval(interval);
  }, [isAirgapped, checkConnectivity, loadData]);

  useEffect(() => {
    document.documentElement.setAttribute('data-theme', isDarkMode ? 'dark' : 'light');
    localStorage.setItem('pageparse_theme', isDarkMode ? 'dark' : 'light');
  }, [isDarkMode]);

  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      if (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement || e.target instanceof HTMLSelectElement) return;
      if (e.ctrlKey || e.metaKey) return;
      switch (e.key) {
        case '1': setActiveView('upload'); break;
        case '2': setActiveView('tasks'); break;
        case '3': setActiveView('history'); break;
        case '4': setActiveView('chat'); break;
        case '5': setActiveView('code'); break;
        case 't': case 'T': setIsDarkMode(prev => !prev); break;
        case '?': setShowSettings(prev => !prev); break;
        case 'Escape': setShowSettings(false); break;
      }
    };
    window.addEventListener('keydown', handleKeyDown);
    return () => window.removeEventListener('keydown', handleKeyDown);
  }, []);

  useEffect(() => {
    if ('serviceWorker' in navigator) {
      navigator.serviceWorker.register('/static/sw.js').catch(() => {});
    }
  }, []);

  const handleAirgapChange = () => {
    const newVal = !isAirgapped;
    setIsAirgapped(newVal);
    setAirgapMode(newVal);
  };

  const handleWebhookConfig = async () => {
    try {
      await fetch(`${API_BASE_URL}/webhook`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ url: webhookUrl, secret: '' }),
      });
      setWebhookConfigured(true);
      setTimeout(() => setShowSettings(false), 1500);
    } catch (err) {
      console.error(err);
    }
  };

  const navItems: { view: View; icon: typeof Upload; label: string; shortcut: string }[] = [
    { view: 'upload', icon: Upload, label: 'Ingest', shortcut: '1' },
    { view: 'tasks', icon: Database, label: 'Records', shortcut: '2' },
    { view: 'history', icon: History, label: 'History', shortcut: '3' },
    { view: 'chat', icon: MessageSquare, label: 'AI Chat', shortcut: '4' },
    { view: 'code', icon: Code, label: 'Code', shortcut: '5' },
  ];

  if (selectedPage) {
    return (
      <PageDetails
        page={selectedPage}
        tasks={tasks}
        onBack={() => setSelectedPage(null)}
        onPageChanged={loadData}
      />
    );
  }

  return (
    <div className="app-shell">
      {/* SIDEBAR */}
      <aside className="sidebar">
        <div className="sidebar-brand" onClick={() => setActiveView('upload')}>
          <ScanFace />
          <h1>PageParse</h1>
        </div>

        {navItems.map(item => (
          <button
            key={item.view}
            className={`nav-item ${activeView === item.view ? 'active' : ''}`}
            onClick={() => setActiveView(item.view)}
            title={`${item.label} (${item.shortcut})`}
          >
            <item.icon />
            <span>{item.label}</span>
            <span className="shortcut-hint">{item.shortcut}</span>
          </button>
        ))}

        <div className="sidebar-spacer" />

        <div className="sidebar-footer">
          <button className="nav-item" onClick={() => setIsDarkMode(prev => !prev)} title="Toggle theme (T)">
            {isDarkMode ? <Sun size={18} /> : <Moon size={18} />}
            <span>{isDarkMode ? 'Light Mode' : 'Dark Mode'}</span>
          </button>
          <button className="nav-item" onClick={() => setShowSettings(true)} title="Settings (?)">
            <Settings size={18} />
            <span>Settings</span>
          </button>
          <div className="switch-row">
            <span style={{ fontSize: 12, color: 'var(--text-tertiary)' }}>Air-gap</span>
            <label className="switch">
              <input type="checkbox" checked={isAirgapped} onChange={handleAirgapChange} />
              <span className="slider" />
            </label>
          </div>
          <div className={`connection-badge ${serverOnline ? 'online' : 'offline'}`}>
            {serverOnline ? <Wifi size={14} /> : <WifiOff size={14} />}
            <span>{isAirgapped ? 'Air-gapped' : serverOnline ? 'Online' : 'Offline'}</span>
          </div>
          <div className="text-xs text-tertiary" style={{ textAlign: 'center' }}>
            ? for keyboard shortcuts
          </div>
        </div>
      </aside>

      {/* MAIN */}
      <main className="main-content">
        <div className="page-header">
          <h2>
            {activeView === 'upload' && 'Ingestion Portal'}
            {activeView === 'tasks' && `Records (${tasks.length})`}
            {activeView === 'history' && `History (${pages.length})`}
            {activeView === 'chat' && 'AI Assistant'}
            {activeView === 'code' && 'Code Paste & Analyze'}
          </h2>
          <div className="header-actions">
            <div className="switch-row">
              <Cpu size={16} className={isProcessing ? 'animate-pulse' : ''} style={{ color: isProcessing ? 'var(--purple)' : 'var(--text-tertiary)' }} />
              <span className="text-xs text-tertiary">{isProcessing ? 'Inference Active' : 'Idle'}</span>
            </div>
          </div>
        </div>

        {activeView === 'upload' && (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 24 }}>
            <FileUploader
              onJobStarted={() => setIsProcessing(true)}
              onJobFinished={() => { setTimeout(loadData, 500); }}
              isAirgapped={isAirgapped}
            />
            <TelemetryPanel isProcessing={isProcessing} />
            <TaskList tasks={tasks} onTasksChanged={loadData} variant="compact" />
          </div>
        )}

        {activeView === 'tasks' && (
          <TaskList tasks={tasks} onTasksChanged={loadData} />
        )}

        {activeView === 'history' && (
          <PageHistory
            pages={pages}
            tasks={tasks}
            onPagesChanged={loadData}
            onSelectPage={setSelectedPage}
          />
        )}

        {activeView === 'chat' && (
          <div className="section" style={{ maxWidth: 720 }}>
            <div className="section-header">
              <h3><MessageSquare size={16} className="text-secondary" /> PageParse AI Chat</h3>
            </div>
            <div className="section-body">
              <ChatPanel />
            </div>
          </div>
        )}

        {activeView === 'code' && (
          <CodeEditor />
        )}
      </main>

      {/* SETTINGS MODAL */}
      {showSettings && (
        <div className="modal-overlay" onClick={() => setShowSettings(false)}>
          <div className="modal" style={{ maxWidth: 500 }} onClick={e => e.stopPropagation()}>
            <div className="modal-header">
              <h3><Settings size={16} /> Settings</h3>
            </div>
            <div className="modal-body" style={{ gridTemplateColumns: '1fr' }}>
              <div className="flex flex-col gap-4">
                <div>
                  <label className="text-xs font-semibold text-tertiary" style={{ textTransform: 'uppercase', letterSpacing: '0.5px' }}>Webhook URL</label>
                  <div className="flex gap-2 mt-2">
                    <input className="input" value={webhookUrl} onChange={e => setWebhookUrl(e.target.value)} placeholder="https://hooks.example.com/pageparse" />
                    <button className="btn btn-sm btn-primary" onClick={handleWebhookConfig}>Save</button>
                  </div>
                  {webhookConfigured && <div className="text-xs text-success mt-1">Webhook configured!</div>}
                </div>
                <div>
                  <label className="text-xs font-semibold text-tertiary" style={{ textTransform: 'uppercase', letterSpacing: '0.5px' }}>Keyboard Shortcuts</label>
                  <div className="flex flex-col gap-1 mt-2 text-sm">
                    <div className="flex justify-between"><span>Ingest view</span><span className="font-mono text-tertiary">1</span></div>
                    <div className="flex justify-between"><span>Records view</span><span className="font-mono text-tertiary">2</span></div>
                    <div className="flex justify-between"><span>History view</span><span className="font-mono text-tertiary">3</span></div>
                    <div className="flex justify-between"><span>AI Chat view</span><span className="font-mono text-tertiary">4</span></div>
                    <div className="flex justify-between"><span>Code view</span><span className="font-mono text-tertiary">5</span></div>
                    <div className="flex justify-between"><span>Toggle theme</span><span className="font-mono text-tertiary">T</span></div>
                    <div className="flex justify-between"><span>Settings</span><span className="font-mono text-tertiary">?</span></div>
                    <div className="flex justify-between"><span>Close modal</span><span className="font-mono text-tertiary">Esc</span></div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

export default App;
