import { useEffect, useMemo, useState } from 'react';
import {
  AlertTriangle,
  CalendarClock,
  ClipboardList,
  Database,
  DatabaseBackup,
  LogOut,
  Moon,
  Network,
  RefreshCw,
  Settings as SettingsIcon,
  Shield,
} from 'lucide-react';
import { api, errorMessage } from './api.js';
import { Dashboard } from './components/Dashboard.jsx';
import { Login } from './components/Login.jsx';
import { Nodes } from './components/Nodes.jsx';
import { Operations } from './components/Operations.jsx';
import { Repositories } from './components/Repositories.jsx';
import { Scheduler } from './components/Scheduler.jsx';
import { Settings } from './components/Settings.jsx';
import { VMDetail } from './components/VMDetail.jsx';

export default function App() {
  const [health, setHealth] = useState(null);
  const [vms, setVms] = useState([]);
  const [jobs, setJobs] = useState([]);
  const [schedules, setSchedules] = useState([]);
  const [nodes, setNodes] = useState([]);
  const [selectedVm, setSelectedVm] = useState(null);
  const [session, setSession] = useState(null);
  const [sessionLoading, setSessionLoading] = useState(true);
  const [view, setView] = useState('dashboard');
  const [error, setError] = useState('');
  const [loading, setLoading] = useState(true);

  async function refresh() {
    setError('');
    try {
      const [healthResult, vmsResult, jobsResult, schedulesResult, nodesResult] = await Promise.allSettled([
        api.get('/health'),
        api.get('/vms'),
        api.get('/jobs'),
        api.get('/schedules'),
        api.get('/nodes'),
      ]);

      if (healthResult.status === 'fulfilled') {
        setHealth(healthResult.value.data);
      } else {
        setHealth(healthResult.reason.response?.data || { ok: false, checks: {} });
      }

      if (vmsResult.status === 'fulfilled') setVms(vmsResult.value.data);
      if (jobsResult.status === 'fulfilled') setJobs(jobsResult.value.data);
      if (schedulesResult.status === 'fulfilled') setSchedules(schedulesResult.value.data);
      if (nodesResult.status === 'fulfilled') setNodes(nodesResult.value.data);

      const firstFailure = [healthResult, vmsResult, jobsResult, schedulesResult, nodesResult].find((result) => result.status === 'rejected');
      if (firstFailure) setError(errorMessage(firstFailure.reason));
    } catch (requestError) {
      setError(errorMessage(requestError));
    } finally {
      setLoading(false);
    }
  }

  useEffect(() => {
    loadSession();
  }, []);

  useEffect(() => {
    if (!session?.authenticated) return undefined;
    refresh();
    const timer = window.setInterval(refresh, 5000);
    return () => window.clearInterval(timer);
  }, [session?.authenticated]);

  const currentVm = useMemo(
    () => vms.find((vm) => vm.id === selectedVm) || null,
    [selectedVm, vms],
  );

  async function loadSession() {
    try {
      const result = await api.get('/auth/session');
      setSession(result.data);
    } catch {
      setSession({ authenticated: false, user: null });
    } finally {
      setSessionLoading(false);
    }
  }

  async function logout() {
    await api.post('/auth/logout');
    setSession({ authenticated: false, user: null });
    setVms([]);
    setJobs([]);
    setSchedules([]);
    setNodes([]);
  }

  if (sessionLoading) {
    return <main className="min-h-screen bg-zinc-950 text-zinc-100" />;
  }

  if (!session?.authenticated) {
    return <Login onLogin={loadSession} />;
  }

  const pageTitle = currentVm
    ? currentVm.name
    : {
      dashboard: 'Backups',
      nodes: 'Nodes',
      repositories: 'Repositories',
      operations: 'Operations',
      scheduler: 'Scheduler',
      settings: 'Settings',
    }[view] || 'Backups';

  return (
    <main className="min-h-screen bg-zinc-950 text-zinc-100">
      <div className="grid min-h-screen lg:grid-cols-[260px_1fr]">
        <aside className="flex flex-col border-r border-zinc-800 bg-zinc-900/80">
          <button
            className="flex h-20 w-full items-center gap-3 border-b border-zinc-800 px-6 text-left"
            onClick={() => {
              setSelectedVm(null);
              setView('dashboard');
            }}
            type="button"
          >
            <span className="flex h-9 w-9 items-center justify-center rounded-md text-red-400">
              <DatabaseBackup className="h-6 w-6" />
            </span>
            <span>
              <span className="block text-base font-semibold tracking-wide text-zinc-100">Incus Backup</span>
              <span className="block text-xs text-zinc-500">Management UI</span>
            </span>
          </button>

          <nav className="space-y-1 px-4 py-6">
            <NavButton active={view === 'nodes' && !currentVm} icon={Network} label="Nodes" onClick={() => switchView('nodes')} />
            <NavButton active={view === 'repositories' && !currentVm} icon={Database} label="Repositories" onClick={() => switchView('repositories')} />
            <NavButton active={view === 'dashboard' || Boolean(currentVm)} icon={CalendarClock} label="Backups" onClick={() => switchView('dashboard')} />
            <NavButton active={view === 'operations' && !currentVm} icon={ClipboardList} label="Operations" onClick={() => switchView('operations')} />
            <NavButton active={view === 'scheduler' && !currentVm} icon={Shield} label="Scheduler" onClick={() => switchView('scheduler')} />
            <NavButton active={view === 'settings' && !currentVm} icon={SettingsIcon} label="Settings" onClick={() => switchView('settings')} />
          </nav>

          <div className="mt-auto hidden border-t border-zinc-800 px-6 py-4 text-xs text-zinc-500 lg:block">
            <div>v0.1.0</div>
            <div className="mt-2 text-red-400">Management</div>
          </div>
        </aside>

        <section className="min-w-0">
          <header className="flex h-20 items-center justify-between border-b border-zinc-800 bg-zinc-900/80 px-6">
            <div className="flex items-center gap-3">
              <button className="hidden h-9 w-9 items-center justify-center rounded-md border border-zinc-800 text-zinc-400 lg:inline-flex" type="button">
                <DatabaseBackup className="h-4 w-4" />
              </button>
              <h1 className="text-lg font-semibold tracking-wide text-zinc-100">{pageTitle}</h1>
            </div>
            <div className="flex items-center gap-2 rounded-full border border-zinc-800 bg-zinc-950 px-3 py-2">
              <span className="px-2 text-sm font-medium text-zinc-200">{session.user?.username || 'admin'}</span>
              <button className="flex h-7 w-7 items-center justify-center rounded-full text-zinc-400 hover:text-zinc-100" onClick={refresh} title="Refresh" type="button">
                <RefreshCw className="h-4 w-4" />
              </button>
              <button className="flex h-7 w-7 items-center justify-center rounded-full text-zinc-400 hover:text-zinc-100" title="Theme" type="button">
                <Moon className="h-4 w-4" />
              </button>
              <button className="flex h-7 w-7 items-center justify-center rounded-full text-zinc-400 hover:text-zinc-100" onClick={logout} title="Logout" type="button">
                <LogOut className="h-4 w-4" />
              </button>
            </div>
          </header>

          <div className="app-grid-bg min-h-[calc(100vh-5rem)] px-5 py-7 sm:px-8">
            {error ? (
              <div className="mb-5 flex items-center gap-2 text-sm text-amber-300">
                <AlertTriangle className="h-4 w-4" />
                {error}
              </div>
            ) : null}

            <div className="mx-auto max-w-[1500px]">
              {view === 'nodes' ? (
                <Nodes nodes={nodes} onChanged={refresh} />
              ) : view === 'repositories' ? (
                <Repositories nodes={nodes} onChanged={refresh} />
              ) : view === 'operations' ? (
                <Operations />
              ) : view === 'settings' ? (
                <Settings nodes={nodes} onChanged={refresh} />
              ) : view === 'scheduler' ? (
                <Scheduler onChanged={refresh} schedules={schedules} vms={vms} />
              ) : currentVm ? (
                <VMDetail vm={currentVm} jobs={jobs} onBack={() => setSelectedVm(null)} onChanged={refresh} />
              ) : (
                <Dashboard
                  health={health}
                  jobs={jobs}
                  loading={loading}
                  onCreateSchedule={() => switchView('scheduler')}
                  onManage={(vmName) => {
                    setSelectedVm(vmName);
                    setView('dashboard');
                  }}
                  schedules={schedules}
                  vms={vms}
                />
              )}
            </div>
          </div>
        </section>
      </div>
    </main>
  );

  function switchView(nextView) {
    setSelectedVm(null);
    setView(nextView);
  }
}

function NavButton({ active, icon: Icon, label, onClick }) {
  return (
    <button
      className={`flex h-11 w-full items-center gap-3 rounded-md px-3 text-left text-sm font-semibold transition ${
        active
          ? 'border-l-4 border-red-500 bg-red-950/40 text-zinc-100'
          : 'text-zinc-400 hover:bg-zinc-800/70 hover:text-zinc-100'
      }`}
      onClick={onClick}
      type="button"
    >
      <Icon className={`h-4 w-4 ${active ? 'text-red-400' : 'text-zinc-500'}`} />
      {label}
    </button>
  );
}
