import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import { useState, useEffect, useCallback } from 'react';
import {
  Home,
  Users,
  Network,
  Shield,
  Mail,
  Calendar as CalendarIcon,
  FolderOpen,
  Activity,
  Wifi,
  Server,
  Key,
  Package2,
  Settings as SettingsIcon,
  Link2,
  RefreshCw,
  AlertTriangle,
  User,
} from 'lucide-react';
import { healthAPI, cellAPI } from './services/api';
import { ConfigProvider } from './contexts/ConfigContext';
import { DraftConfigProvider, useDraftConfig } from './contexts/DraftConfigContext';
import { AuthProvider, useAuth } from './contexts/AuthContext';
import PrivateRoute from './components/PrivateRoute';
import Sidebar from './components/Sidebar';
import Dashboard from './pages/Dashboard';
import Peers from './pages/Peers';
import NetworkServices from './pages/NetworkServices';
import WireGuard from './pages/WireGuard';
import Email from './pages/Email';
import Calendar from './pages/Calendar';
import Files from './pages/Files';
import Routing from './pages/Routing';
import Logs from './pages/Logs';
import Settings from './pages/Settings';
import Vault from './pages/Vault';
import ContainerDashboard from './components/ContainerDashboard';
import CellNetwork from './pages/CellNetwork';
import Login from './pages/Login';
import AccountSettings from './pages/AccountSettings';
import PeerDashboard from './pages/PeerDashboard';
import MyServices from './pages/MyServices';

function PendingRestartBanner({ pending, onApply, onCancel }) {
  const [confirming, setConfirming] = useState(false);
  const [applying, setApplying] = useState(false);
  const [cancelling, setCancelling] = useState(false);

  const handleApply = async () => {
    setApplying(true);
    setConfirming(false);
    try {
      await onApply();
    } finally {
      setApplying(false);
    }
  };

  const handleCancel = async () => {
    setCancelling(true);
    try {
      await onCancel();
    } finally {
      setCancelling(false);
    }
  };

  return (
    <>
      <div className="mb-6 bg-warning-50 border border-warning-300 rounded-lg p-4">
        <div className="flex items-center justify-between">
          <div className="flex items-start gap-3">
            <AlertTriangle className="h-5 w-5 text-warning-500 mt-0.5 flex-shrink-0" />
            <div>
              <p className="text-sm font-medium text-warning-800">
                Configuration changes pending — containers need restart
              </p>
              {pending.changes?.length > 0 && (
                <ul className="mt-1 text-xs text-warning-700 list-disc list-inside">
                  {pending.changes.map((c, i) => <li key={i}>{c}</li>)}
                </ul>
              )}
            </div>
          </div>
          <div className="ml-4 flex-shrink-0 flex items-center gap-2">
            <button
              onClick={handleCancel}
              disabled={applying || cancelling}
              className="flex items-center gap-1.5 px-3 py-1.5 bg-white hover:bg-gray-50 disabled:opacity-50 text-warning-700 text-sm font-medium rounded-md border border-warning-300 transition-colors"
            >
              {cancelling ? 'Discarding…' : 'Discard'}
            </button>
            <button
              onClick={() => setConfirming(true)}
              disabled={applying || cancelling}
              className="flex items-center gap-1.5 px-3 py-1.5 bg-warning-600 hover:bg-warning-700 disabled:opacity-50 text-white text-sm font-medium rounded-md transition-colors"
            >
              <RefreshCw className={`h-4 w-4 ${applying ? 'animate-spin' : ''}`} />
              {applying ? 'Restarting…' : 'Apply Now'}
            </button>
          </div>
        </div>
      </div>

      {confirming && (
        <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40">
          <div className="bg-white rounded-xl shadow-2xl p-6 max-w-sm w-full mx-4">
            <div className="flex items-center gap-3 mb-3">
              <AlertTriangle className="h-6 w-6 text-warning-500 flex-shrink-0" />
              <h3 className="text-base font-semibold text-gray-900">Restart containers?</h3>
            </div>
            <p className="text-sm text-gray-600 mb-5">
              All containers will be restarted to apply the new configuration.
              The UI will be briefly unavailable during the restart.
            </p>
            <div className="flex gap-3 justify-end">
              <button
                onClick={() => setConfirming(false)}
                className="px-4 py-2 text-sm font-medium text-gray-700 bg-gray-100 hover:bg-gray-200 rounded-md transition-colors"
              >
                Cancel
              </button>
              <button
                onClick={handleApply}
                className="px-4 py-2 text-sm font-medium text-white bg-warning-600 hover:bg-warning-700 rounded-md transition-colors"
              >
                Restart now
              </button>
            </div>
          </div>
        </div>
      )}
    </>
  );
}

// AppCore is the real application — it consumes DraftConfigContext and must
// be rendered inside DraftConfigProvider (see App below).
function AppCore() {
  const [isOnline, setIsOnline] = useState(false);
  const [isLoading, setIsLoading] = useState(true);
  const [pending, setPending] = useState({ needs_restart: false, changes: [] });

  const checkHealth = useCallback(async () => {
    try {
      await healthAPI.check();
      setIsOnline(true);
    } catch {
      setIsOnline(false);
    } finally {
      setIsLoading(false);
    }
  }, []);

  const checkPending = useCallback(async () => {
    try {
      const res = await cellAPI.getPending();
      setPending(res.data);
    } catch {
      // ignore — not critical
    }
  }, []);

  useEffect(() => {
    checkHealth();
    checkPending();
    const healthInterval = setInterval(checkHealth, 5000);
    const pendingInterval = setInterval(checkPending, 5000);
    return () => {
      clearInterval(healthInterval);
      clearInterval(pendingInterval);
    };
  }, [checkHealth, checkPending]);

  const [applyStatus, setApplyStatus] = useState(null); // null | 'saving' | 'restarting' | 'done' | 'timeout' | 'error'
  const [applyError, setApplyError] = useState('');

  const { flushAll, hasDirty } = useDraftConfig();

  const handleApply = useCallback(async () => {
    setApplyError('');
    if (hasDirty()) {
      setApplyStatus('saving');
      try {
        await flushAll();
      } catch {
        // flush errors are shown via Settings toasts; continue with apply
      }
    }
    try {
      await cellAPI.applyPending();
    } catch (err) {
      setApplyStatus('error');
      setApplyError(err?.response?.data?.error || 'Apply request failed');
      setTimeout(() => setApplyStatus(null), 6000);
      return;
    }
    setPending({ needs_restart: false, changes: [] });
    setApplyStatus('restarting');

    // Poll health until API responds again (max 45 s; it may briefly drop if cell-api restarts)
    const deadline = Date.now() + 45000;
    while (Date.now() < deadline) {
      await new Promise(r => setTimeout(r, 2000));
      try {
        await healthAPI.check();
        setIsOnline(true);
        setApplyStatus('done');
        setTimeout(() => setApplyStatus(null), 4000);
        return;
      } catch {
        setIsOnline(false);
      }
    }
    setApplyStatus('timeout');
    setApplyError('Containers may still be starting — check docker logs if services are unavailable');
    setTimeout(() => setApplyStatus(null), 8000);
  }, [flushAll, hasDirty]);

  const handleCancel = useCallback(async () => {
    await cellAPI.cancelPending();
    setPending({ needs_restart: false, changes: [] });
    window.dispatchEvent(new CustomEvent('pic-config-discarded'));
  }, []);

  const adminNavigation = [
    { name: 'Dashboard', href: '/', icon: Home },
    { name: 'Peers', href: '/peers', icon: Users },
    { name: 'Network Services', href: '/network', icon: Network },
    { name: 'WireGuard', href: '/wireguard', icon: Shield },
    { name: 'Email', href: '/email', icon: Mail },
    { name: 'Calendar', href: '/calendar', icon: CalendarIcon },
    { name: 'Files', href: '/files', icon: FolderOpen },
    { name: 'Routing', href: '/routing', icon: Wifi },
    { name: 'Vault', href: '/vault', icon: Key },
    { name: 'Containers', href: '/containers', icon: Package2 },
    { name: 'Cell Network', href: '/cell-network', icon: Link2 },
    { name: 'Logs', href: '/logs', icon: Activity },
    { name: 'Settings', href: '/settings', icon: SettingsIcon },
    { name: 'Account', href: '/account', icon: User },
  ];

  const peerNavigation = [
    { name: 'Dashboard', href: '/', icon: Home },
    { name: 'My Services', href: '/my-services', icon: FolderOpen },
    { name: 'Account', href: '/account', icon: User },
  ];

  const { user } = useAuth();
  const navigation = user?.role === 'peer' ? peerNavigation : adminNavigation;

  if (isLoading) {
    return (
      <div className="min-h-screen bg-gray-50 flex items-center justify-center">
        <div className="text-center">
          <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-primary-600 mx-auto"></div>
          <p className="mt-4 text-gray-600">Connecting to Personal Internet Cell...</p>
        </div>
      </div>
    );
  }

  return (
    <Router>
      <Routes>
        <Route path="/login" element={<Login />} />
        <Route path="*" element={
          <ConfigProvider>
            <div className="min-h-screen bg-gray-50">
              <Sidebar navigation={navigation} isOnline={isOnline} />
              <div className="lg:pl-72">
                <main className="py-10">
                  <div className="px-4 sm:px-6 lg:px-8">
                    {!isOnline && (
                      <div className="mb-6 bg-danger-50 border border-danger-200 rounded-lg p-4">
                        <div className="flex">
                          <div className="flex-shrink-0">
                            <Server className="h-5 w-5 text-danger-400" />
                          </div>
                          <div className="ml-3">
                            <h3 className="text-sm font-medium text-danger-800">
                              Backend Unavailable
                            </h3>
                            <div className="mt-2 text-sm text-danger-700">
                              <p>
                                Unable to connect to the Personal Internet Cell backend.
                                Please ensure the API server is running on port 3000.
                              </p>
                            </div>
                          </div>
                        </div>
                      </div>
                    )}

                    {isOnline && pending.needs_restart && !applyStatus && (
                      <PendingRestartBanner pending={pending} onApply={handleApply} onCancel={handleCancel} />
                    )}

                    {applyStatus === 'saving' && (
                      <div className="mb-6 bg-blue-50 border border-blue-200 rounded-lg p-4 flex items-center gap-3">
                        <RefreshCw className="h-5 w-5 text-blue-500 animate-spin flex-shrink-0" />
                        <span className="text-sm font-medium text-blue-800">Saving settings…</span>
                      </div>
                    )}

                    {applyStatus === 'restarting' && (
                      <div className="mb-6 bg-blue-50 border border-blue-200 rounded-lg p-4 flex items-center gap-3">
                        <RefreshCw className="h-5 w-5 text-blue-500 animate-spin flex-shrink-0" />
                        <span className="text-sm font-medium text-blue-800">Restarting containers — please wait…</span>
                      </div>
                    )}

                    {applyStatus === 'done' && (
                      <div className="mb-6 bg-green-50 border border-green-200 rounded-lg p-4 flex items-center gap-3">
                        <span className="h-5 w-5 text-green-500 flex-shrink-0 text-lg leading-none">✓</span>
                        <span className="text-sm font-medium text-green-800">Containers restarted successfully</span>
                      </div>
                    )}

                    {(applyStatus === 'timeout' || applyStatus === 'error') && (
                      <div className="mb-6 bg-danger-50 border border-danger-200 rounded-lg p-4 flex items-center gap-3">
                        <AlertTriangle className="h-5 w-5 text-danger-500 flex-shrink-0" />
                        <span className="text-sm font-medium text-danger-800">{applyError}</span>
                      </div>
                    )}

                    <Routes>
                      <Route path="/" element={<PrivateRoute><RoleHome isOnline={isOnline} /></PrivateRoute>} />
                      <Route path="/account" element={<PrivateRoute><AccountSettings /></PrivateRoute>} />
                      <Route path="/my-services" element={<PrivateRoute requireRole="peer"><MyServices /></PrivateRoute>} />
                      <Route path="/peers" element={<PrivateRoute requireRole="admin"><Peers /></PrivateRoute>} />
                      <Route path="/network" element={<PrivateRoute requireRole="admin"><NetworkServices /></PrivateRoute>} />
                      <Route path="/wireguard" element={<PrivateRoute requireRole="admin"><WireGuard /></PrivateRoute>} />
                      <Route path="/email" element={<PrivateRoute requireRole="admin"><Email /></PrivateRoute>} />
                      <Route path="/calendar" element={<PrivateRoute requireRole="admin"><Calendar /></PrivateRoute>} />
                      <Route path="/files" element={<PrivateRoute requireRole="admin"><Files /></PrivateRoute>} />
                      <Route path="/routing" element={<PrivateRoute requireRole="admin"><Routing /></PrivateRoute>} />
                      <Route path="/vault" element={<PrivateRoute requireRole="admin"><Vault /></PrivateRoute>} />
                      <Route path="/containers" element={<PrivateRoute requireRole="admin"><ContainerDashboard /></PrivateRoute>} />
                      <Route path="/cell-network" element={<PrivateRoute requireRole="admin"><CellNetwork /></PrivateRoute>} />
                      <Route path="/logs" element={<PrivateRoute requireRole="admin"><Logs /></PrivateRoute>} />
                      <Route path="/settings" element={<PrivateRoute requireRole="admin"><Settings /></PrivateRoute>} />
                    </Routes>
                  </div>
                </main>
              </div>
            </div>
          </ConfigProvider>
        } />
      </Routes>
    </Router>
  );
}

function RoleHome({ isOnline }) {
  const { user } = useAuth();
  return user?.role === 'peer' ? <PeerDashboard /> : <Dashboard isOnline={isOnline} />;
}

function App() {
  return (
    <AuthProvider>
      <DraftConfigProvider>
        <AppCore />
      </DraftConfigProvider>
    </AuthProvider>
  );
}

export default App;
