// @ts-nocheck
import { useEffect, useRef, useState } from 'react';
import { logout, login } from './lib/auth';
import { api } from './lib/api';
import { CONFIG } from './lib/config';
import { extensionTypeFromDocPath, parseDocsSummary, titleFromSlug } from './lib/docs';
import { maybeMigrateLegacyHashRoute, navigate, usePathLocation } from './lib/navigation';
import { Footer } from './components/ui';
import { useToast } from './components/toast';
import { PlatformAccessDenied } from './components/states';
import { DeploymentDetail } from './features/deployments';
import { DocsPage } from './features/docs';
import { HomePage } from './features/home';
import { ProjectsList, ProjectDetail } from './features/projects';
import { ExtensionDetailPage } from './features/resources';
import { TeamDetail, TeamsList } from './features/teams';
import { CommandPalette } from './components/command-palette';

function Sidebar({ currentView, docsItems = [], availableExtensionTypes = [], currentDocSlug = '', docsDefaultSlug = '' }) {
    const isHomeActive = currentView === 'home';
    const isProjectsActive = currentView === 'projects' || currentView === 'project-detail' || currentView === 'deployment-detail' || currentView === 'extension-detail';
    const isTeamsActive = currentView === 'teams' || currentView === 'team-detail';
    const isDocsActive = currentView === 'docs';
    const enabledExtensionTypes = new Set(availableExtensionTypes || []);
    const visibleDocsItems = docsItems.filter((item) => {
        const extensionType = extensionTypeFromDocPath(item.path);
        if (!extensionType) return true;
        return enabledExtensionTypes.has(extensionType);
    });

    return (
        <aside className="mono-sidebar">
            <div className="mono-brand" onClick={() => navigate('/projects')}>
                <div
                    className="mono-brand-logo svg-mask"
                    aria-hidden="true"
                    style={{
                        maskImage: 'url(/assets/logo.svg)',
                        WebkitMaskImage: 'url(/assets/logo.svg)',
                    }}
                ></div>
                <div>
                    <strong>RISE</strong>
                    <p>OPS TERMINAL</p>
                </div>
            </div>

            <nav className="mono-nav" aria-label="Main">
                <a
                    href="/home"
                    onClick={(e) => {
                        e.preventDefault();
                        navigate('/home');
                    }}
                    className={isHomeActive ? 'active' : ''}
                >
                    Home
                </a>
                <a
                    href={docsDefaultSlug ? `/docs/${docsDefaultSlug}` : '/docs'}
                    onClick={(e) => {
                        e.preventDefault();
                        navigate(docsDefaultSlug ? `/docs/${docsDefaultSlug}` : '/docs');
                    }}
                    className={isDocsActive ? 'active' : ''}
                >
                    Docs
                </a>
                {isDocsActive && visibleDocsItems.length > 0 && (
                    <div className="mono-subnav" aria-label="Documentation pages">
                        {visibleDocsItems.map((item) => (
                            <a
                                key={item.slug}
                                href={`/docs/${item.slug}`}
                                onClick={(e) => {
                                    e.preventDefault();
                                    navigate(`/docs/${item.slug}`);
                                }}
                                className={`${currentDocSlug === item.slug ? 'active' : ''} depth-${Math.min(item.depth || 0, 3)}`.trim()}
                            >
                                {item.title}
                            </a>
                        ))}
                    </div>
                )}
                <a
                    href="/projects"
                    onClick={(e) => {
                        e.preventDefault();
                        navigate('/projects');
                    }}
                    className={isProjectsActive ? 'active' : ''}
                >
                    Projects
                </a>
                <a
                    href="/teams"
                    onClick={(e) => {
                        e.preventDefault();
                        navigate('/teams');
                    }}
                    className={isTeamsActive ? 'active' : ''}
                >
                    Teams
                </a>
            </nav>

            <div className="mono-shortcut-hint" aria-label="Command palette shortcut">
                <span>Command palette</span>
                <code>Ctrl/Cmd + K</code>
            </div>
        </aside>
    );
}

function TopBar({ user, onLogout, breadcrumbs = [] }) {
    const [isProfileOpen, setIsProfileOpen] = useState(false);
    const profileRef = useRef(null);

    useEffect(() => {
        function handleClickOutside(event) {
            if (profileRef.current && !profileRef.current.contains(event.target)) {
                setIsProfileOpen(false);
            }
        }

        if (isProfileOpen) {
            document.addEventListener('mousedown', handleClickOutside);
            return () => document.removeEventListener('mousedown', handleClickOutside);
        }
    }, [isProfileOpen]);

    return (
        <header className="mono-topbar">
            <div>
                <p className="mono-kicker">context</p>
                <div className="mono-breadcrumbs">
                    {breadcrumbs.map((crumb, idx) => {
                        const isLast = idx === breadcrumbs.length - 1;
                        return (
                            <span key={`${crumb.label}-${idx}`} className="mono-breadcrumb-item">
                                {crumb.href && !isLast ? (
                                    <a
                                        href={crumb.href}
                                        onClick={(e) => {
                                            e.preventDefault();
                                            navigate(crumb.href);
                                        }}
                                    >
                                        {crumb.label}
                                    </a>
                                ) : (
                                    <strong>{crumb.label}</strong>
                                )}
                                {!isLast && <span className="mono-breadcrumb-sep">/</span>}
                            </span>
                        );
                    })}
                </div>
            </div>
            <div className="mono-topbar-actions">
                <div className="mono-profile" ref={profileRef}>
                    <button
                        onClick={() => setIsProfileOpen(!isProfileOpen)}
                        className="mono-ghost-button"
                        aria-label="Account"
                        title="Account"
                    >
                        <span
                            className="w-4 h-4 svg-mask inline-block"
                            aria-hidden="true"
                            style={{
                                maskImage: 'url(/assets/user.svg)',
                                WebkitMaskImage: 'url(/assets/user.svg)',
                            }}
                        ></span>
                    </button>
                    {isProfileOpen && (
                        <div className="mono-popover">
                            <p>{user?.email}</p>
                            <button
                                onClick={() => {
                                    setIsProfileOpen(false);
                                    onLogout();
                                }}
                            >
                                <span className="inline-flex items-center gap-2">
                                    <span
                                        className="w-4 h-4 svg-mask inline-block"
                                        aria-hidden="true"
                                        style={{
                                            maskImage: 'url(/assets/logout.svg)',
                                            WebkitMaskImage: 'url(/assets/logout.svg)',
                                        }}
                                    ></span>
                                    Logout
                                </span>
                            </button>
                        </div>
                    )}
                </div>
            </div>
        </header>
    );
}

function LoginPage() {
    const [status, setStatus] = useState('');
    const [loading, setLoading] = useState(false);

    const handleLogin = async () => {
        setStatus('Redirecting to login...');
        setLoading(true);
        try {
            await login();
        } catch (error) {
            setStatus(`Error: ${error.message}`);
            setLoading(false);
        }
    };

    return (
        <div className="mono-login-wrap">
            <div className="mono-login-card">
                <div className="text-center mb-8">
                    <div
                        className="mono-login-logo svg-mask mx-auto mb-4"
                        aria-hidden="true"
                        style={{
                            maskImage: 'url(/assets/logo.svg)',
                            WebkitMaskImage: 'url(/assets/logo.svg)',
                        }}
                    ></div>
                    <h1 className="mono-login-title">RISE</h1>
                    <p className="mono-login-subtitle">Container deployment platform</p>
                </div>

                {loading ? (
                    <div className="flex flex-col items-center gap-4 py-8">
                        <div className="w-12 h-12 border-2 border-gray-300 border-t-transparent rounded-full animate-spin"></div>
                        <p className="text-gray-300">{status}</p>
                    </div>
                ) : (
                    <>
                        <button onClick={handleLogin} className="mono-login-button">
                            login_with_oauth
                        </button>
                        {status && <p className="text-center text-sm text-red-300 mt-3">{status}</p>}
                    </>
                )}
            </div>
        </div>
    );
}

export function App() {
    const [user, setUser] = useState(null);
    const [authChecked, setAuthChecked] = useState(false);
    const [platformAccessDenied, setPlatformAccessDenied] = useState(false);
    const [version, setVersion] = useState(null);
    const [commandPaletteOpen, setCommandPaletteOpen] = useState(false);
    const [paletteProjects, setPaletteProjects] = useState([]);
    const [paletteTeams, setPaletteTeams] = useState([]);
    const [docsItems, setDocsItems] = useState([]);
    const [availableExtensionTypes, setAvailableExtensionTypes] = useState([]);
    const pathname = usePathLocation();
    const { showToast } = useToast();
    const defaultDocSlug = docsItems[0]?.slug || '';

    useEffect(() => {
        maybeMigrateLegacyHashRoute();

        if (window.location.hash && (window.location.hash.includes('access_token=') || window.location.hash.includes('error='))) {
            const fragment = window.location.hash.substring(1);
            const params = new URLSearchParams(fragment);
            const returnPath = sessionStorage.getItem('oauth_return_path');

            const error = params.get('error');
            const errorDescription = params.get('error_description');
            const accessToken = params.get('access_token');

            if (error) {
                const message = errorDescription || `OAuth flow failed: ${error}`;
                showToast(message, 'error');
            } else if (accessToken) {
                const expiresIn = params.get('expires_in');
                const expiresAt = params.get('expires_at');

                let expiresAtDate;
                if (expiresAt) {
                    expiresAtDate = new Date(expiresAt);
                } else if (expiresIn) {
                    expiresAtDate = new Date(Date.now() + parseInt(expiresIn) * 1000);
                }

                const message = `OAuth flow successful! Token expires ${expiresAtDate ? expiresAtDate.toLocaleString() : 'soon'}`;
                showToast(message, 'success');
            }

            sessionStorage.removeItem('oauth_return_path');

            if (returnPath) {
                navigate(returnPath);
            } else {
                navigate('/projects');
            }
        }

        async function loadUser() {
            try {
                const userData = await api.getMe();
                setUser(userData);
            } catch (err) {
                console.error('Failed to load user:', err);
                setUser(null);
            } finally {
                setAuthChecked(true);
            }
        }
        loadUser();
    }, []);

    useEffect(() => {
        const handler = (e) => {
            const isModifierK = (e.metaKey || e.ctrlKey) && e.key.toLowerCase() === 'k';
            if (!isModifierK) return;

            const target = e.target;
            const isTypingTarget =
                target instanceof HTMLInputElement ||
                target instanceof HTMLTextAreaElement ||
                target?.isContentEditable;
            const modalOpen = Boolean(document.querySelector('.modal-backdrop'));

            if (isTypingTarget && !modalOpen) return;

            e.preventDefault();
            setCommandPaletteOpen(true);
        };

        window.addEventListener('keydown', handler);
        return () => window.removeEventListener('keydown', handler);
    }, []);

    useEffect(() => {
        async function loadDocsSummary() {
            try {
                const [summaryResponse, extensionTypesResponse] = await Promise.all([
                    fetch('/static/docs/FRONTEND_DOCS.md'),
                    api.getExtensionTypes().catch(() => ({ extension_types: [] })),
                ]);
                if (!summaryResponse.ok) return;

                const summary = await summaryResponse.text();
                setDocsItems(parseDocsSummary(summary));
                setAvailableExtensionTypes((extensionTypesResponse.extension_types || []).map((ext) => ext.extension_type));
            } catch (err) {
                console.error('Failed to load docs summary:', err);
            }
        }
        loadDocsSummary();
    }, []);

    useEffect(() => {
        if (pathname === '/docs' && docsItems.length > 0) {
            window.history.replaceState({}, '', `/docs/${docsItems[0].slug}`);
            window.dispatchEvent(new Event('rise:navigate'));
        }
    }, [pathname, docsItems]);

    useEffect(() => {
        async function fetchVersion() {
            try {
                const response = await fetch(`${CONFIG.backendUrl}/api/v1/version`);
                const data = await response.json();
                setVersion(data);
            } catch (err) {
                console.error('Failed to fetch version:', err);
            }
        }
        fetchVersion();
    }, []);

    useEffect(() => {
        if (!user) {
            setPaletteProjects([]);
            setPaletteTeams([]);
            return;
        }

        async function loadPaletteTargets() {
            try {
                const [projects, teams] = await Promise.all([api.getProjects(), api.getTeams()]);
                setPaletteProjects(projects || []);
                setPaletteTeams(teams || []);
            } catch (err) {
                // Check if this is a platform access denial
                if (err.isPlatformAccessDenied) {
                    setPlatformAccessDenied(true);
                    return;
                }
                console.error('Failed to load command palette targets:', err);
            }
        }

        loadPaletteTargets();
    }, [user?.id]);

    const handleLogout = () => {
        logout();
    };

    if (!authChecked) {
        return (
            <div className="mono-login-wrap">
                <div className="w-8 h-8 border-2 border-gray-300 border-t-transparent rounded-full animate-spin"></div>
            </div>
        );
    }

    if (!user) {
        return <LoginPage />;
    }

    if (platformAccessDenied) {
        return <PlatformAccessDenied userEmail={user.email} onLogout={handleLogout} />;
    }

    let view = 'projects';
    let params = {};
    const route = pathname.replace(/^\//, '');

    if (route.startsWith('project/')) {
        const parts = route.split('/');
        if (parts[2] === 'extensions') {
            if (parts.length === 3) {
                view = 'project-detail';
                params.projectName = parts[1];
                params.tab = 'extensions';
            } else if (parts.length === 4 && parts[3] === '@new') {
                view = 'extension-create';
                params.projectName = parts[1];
                params.extensionType = null;
            } else if (parts.length === 5 && parts[3]) {
                if (parts[4] === '@new') {
                    view = 'extension-detail';
                    params.projectName = parts[1];
                    params.extensionType = parts[3];
                    params.extensionInstance = null;
                } else {
                    view = 'extension-detail';
                    params.projectName = parts[1];
                    params.extensionType = parts[3];
                    params.extensionInstance = parts[4];
                }
            } else if (parts.length === 4 && parts[3]) {
                view = 'extension-detail';
                params.projectName = parts[1];
                params.extensionType = parts[3];
                params.extensionInstance = null;
            }
        } else {
            view = 'project-detail';
            params.projectName = parts[1];
            params.tab = parts[2] || 'overview';
        }
    } else if (route.startsWith('team/')) {
        view = 'team-detail';
        params.teamName = route.split('/')[1];
    } else if (route.startsWith('deployment/')) {
        view = 'deployment-detail';
        const parts = route.split('/');
        params.projectName = parts[1];
        params.deploymentId = parts[2];
    } else if (route.startsWith('docs')) {
        view = 'docs';
        const parts = route.split('/');
        params.docSlug = parts.slice(1).join('/') || '';
    } else if (route === 'home') {
        view = 'home';
    } else if (route === 'teams') {
        view = 'teams';
    } else {
        view = 'projects';
    }

    const projectTabLabelMap = {
        deployments: 'Deployments',
        'service-accounts': 'Service Accounts',
        'env-vars': 'Environment Variables',
        domains: 'Domains',
        extensions: 'Extensions',
        access: 'Access',
    };
    const breadcrumbs =
        view === 'home'
            ? [{ label: 'Home' }]
            : view === 'projects'
            ? [{ label: 'Projects' }]
            : view === 'teams'
            ? [{ label: 'Teams' }]
            : view === 'docs'
            ? (() => {
                  const slug = params.docSlug || defaultDocSlug || '';
                  const crumbs = [{ label: 'Docs', href: defaultDocSlug ? `/docs/${defaultDocSlug}` : '/docs' }];
                  if (slug) {
                      const idx = docsItems.findIndex((item) => item.slug === slug);
                      if (idx >= 0) {
                          const item = docsItems[idx];
                          // Walk backward to collect ancestors at each shallower depth
                          const ancestors = [];
                          let targetDepth = (item.depth || 0) - 1;
                          for (let i = idx - 1; i >= 0 && targetDepth >= 0; i--) {
                              if ((docsItems[i].depth || 0) === targetDepth) {
                                  ancestors.unshift(docsItems[i]);
                                  targetDepth--;
                              }
                          }
                          for (const anc of ancestors) {
                              crumbs.push({ label: anc.title, href: `/docs/${anc.slug}` });
                          }
                          crumbs.push({ label: item.title });
                      } else {
                          crumbs.push({ label: titleFromSlug(slug) });
                      }
                  }
                  return crumbs;
              })()
            : view === 'project-detail'
            ? [
                  { label: 'Projects', href: '/projects' },
                  { label: `Project: ${params.projectName}` },
                  ...(params.tab && params.tab !== 'overview'
                      ? [{ label: projectTabLabelMap[params.tab] || params.tab }]
                      : []),
              ]
            : view === 'team-detail'
            ? [
                  { label: 'Teams', href: '/teams' },
                  { label: `Team: ${params.teamName}` },
              ]
            : view === 'deployment-detail'
            ? [
                  { label: 'Projects', href: '/projects' },
                  { label: `Project: ${params.projectName}`, href: `/project/${params.projectName}` },
                  { label: `Deployment: ${params.deploymentId}` },
              ]
            : view === 'extension-detail' || view === 'extension-create'
            ? [
                  { label: 'Projects', href: '/projects' },
                  { label: `Project: ${params.projectName}`, href: `/project/${params.projectName}` },
                  { label: 'Extensions', href: `/project/${params.projectName}/extensions` },
                  {
                      label: params.extensionInstance
                          ? `Extension: ${params.extensionInstance}`
                          : params.extensionType
                          ? `Extension: ${params.extensionType}`
                          : 'Extension',
                  },
              ]
            : [{ label: 'Projects' }];

    const commandItems = [
        {
            id: 'go-projects',
            label: 'Navigate: Projects',
            keywords: ['projects', 'navigation', 'list'],
            run: () => navigate('/projects'),
        },
        {
            id: 'go-home',
            label: 'Navigate: Home',
            keywords: ['home', 'welcome', 'getting started'],
            run: () => navigate('/home'),
        },
        {
            id: 'go-teams',
            label: 'Navigate: Teams',
            keywords: ['teams', 'navigation', 'list'],
            run: () => navigate('/teams'),
        },
        {
            id: 'create-project',
            label: 'Action: Create project',
            keywords: ['project', 'create', 'new'],
            run: () => navigate('/projects?create=project'),
        },
        {
            id: 'create-team',
            label: 'Action: Create team',
            keywords: ['team', 'create', 'new'],
            run: () => navigate('/teams?create=team'),
        },
        {
            id: 'open-docs',
            label: 'Open: Docs',
            keywords: ['help', 'docs', 'onboarding'],
            run: () => navigate(defaultDocSlug ? `/docs/${defaultDocSlug}` : '/docs'),
        },
    ];

    if (view === 'project-detail' && params?.projectName) {
        commandItems.unshift({
            id: 'go-project-overview',
            label: `Navigate: Project ${params.projectName}`,
            keywords: ['project', 'detail', params.projectName],
            run: () => navigate(`/project/${params.projectName}`),
        });
    }

    const projectCommands = paletteProjects.map((project) => ({
        id: `project-${project.id || project.name}`,
        label: `Project: ${project.name}`,
        keywords: ['project', project.name, project.owner_team_name, project.owner_user_email].filter(Boolean),
        run: () => navigate(`/project/${project.name}`),
    }));

    const teamCommands = paletteTeams.map((team) => ({
        id: `team-${team.id || team.name}`,
        label: `Team: ${team.name}`,
        keywords: ['team', team.name],
        run: () => navigate(`/team/${team.name}`),
    }));

    commandItems.push(...projectCommands, ...teamCommands);

    const createIntent = new URLSearchParams(window.location.search).get('create');

    return (
        <div className="mono-app">
            <div className="mono-shell">
                <Sidebar
                    currentView={view}
                    docsItems={docsItems}
                    availableExtensionTypes={availableExtensionTypes}
                    currentDocSlug={params.docSlug || ''}
                    docsDefaultSlug={defaultDocSlug}
                />
                <div className="mono-main-shell">
                    <TopBar
                        user={user}
                        onLogout={handleLogout}
                        breadcrumbs={breadcrumbs}
                    />
                    <main className="mono-main">
                        {view === 'home' && <HomePage publicUrl={CONFIG?.backendUrl} version={version?.version} />}
                        {view === 'projects' && <ProjectsList openCreate={createIntent === 'project'} />}
                        {view === 'teams' && <TeamsList currentUser={user} openCreate={createIntent === 'team'} />}
                        {view === 'docs' && <DocsPage initialSlug={params.docSlug} />}
                        {view === 'project-detail' && <ProjectDetail projectName={params.projectName} initialTab={params.tab} />}
                        {view === 'team-detail' && <TeamDetail teamName={params.teamName} currentUser={user} />}
                        {view === 'deployment-detail' && <DeploymentDetail projectName={params.projectName} deploymentId={params.deploymentId} />}
                        {view === 'extension-detail' && <ExtensionDetailPage projectName={params.projectName} extensionType={params.extensionType} extensionInstance={params.extensionInstance} />}
                    </main>
                    <Footer version={version} />
                </div>
            </div>
            <CommandPalette
                isOpen={commandPaletteOpen}
                onClose={() => setCommandPaletteOpen(false)}
                items={commandItems}
            />
        </div>
    );
}
