import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import {
    Plug,
    Zap,
    Server,
    ShieldCheck,
    HelpCircle,
    ArrowRight,
    Info,
    Bot,
    UserCheck,
    Database,
    ListChecks,
    ChevronRight,
    ArrowDown,
    type LucideIcon,
} from 'lucide-react';

// ─────────────────────────────────────────────────────────────────────────────
// Origin resolution
// ─────────────────────────────────────────────────────────────────────────────

function resolveOrigin(): string {
    // Prefer the configured backend origin so the managed Codex command targets
    // the reachable MCP endpoint in split-host deployments.
    const configured =
        typeof process !== 'undefined' && process.env
            ? process.env.REACT_APP_BACKEND_URL || process.env.API_BASE_URL
            : undefined;
    if (configured) return configured.replace(/\/+$/, '');
    if (typeof window !== 'undefined' && window.location?.origin) return window.location.origin;
    return 'https://your-nexuscrm-host';
}

// ─────────────────────────────────────────────────────────────────────────────
// Section registry (drives the sticky "on this page" nav + scroll spy)
// ─────────────────────────────────────────────────────────────────────────────

interface SectionDef {
    id: string;
    label: string;
    icon: LucideIcon;
}

const SECTIONS: SectionDef[] = [
    { id: 'how-it-works', label: 'How it works', icon: Info },
    { id: 'codex-cli', label: 'Codex CLI', icon: Bot },
    { id: 'claude-code', label: 'Claude Code', icon: Bot },
    { id: 'manage-access', label: 'Manage your access', icon: ShieldCheck },
    { id: 'faq', label: 'Frequently asked', icon: HelpCircle },
];

// ─────────────────────────────────────────────────────────────────────────────
// Shared building blocks
// ─────────────────────────────────────────────────────────────────────────────

const Callout: React.FC<{
    title: string;
    tone?: 'info' | 'success' | 'warning';
    icon?: React.ReactNode;
    children: React.ReactNode;
}> = ({ title, tone = 'info', icon, children }) => {
    const toneClasses: Record<string, string> = {
        info: 'bg-blue-50 border-blue-200 text-blue-900',
        success: 'bg-emerald-50 border-emerald-200 text-emerald-900',
        warning: 'bg-amber-50 border-amber-200 text-amber-900',
    };
    return (
        <div className={`rounded-xl border p-4 ${toneClasses[tone]}`}>
            <div className="flex items-start gap-3">
                <div className="shrink-0 mt-0.5">{icon ?? <Info size={18} />}</div>
                <div className="min-w-0">
                    <p className="text-sm font-semibold">{title}</p>
                    <div className="mt-1 text-sm opacity-90">{children}</div>
                </div>
            </div>
        </div>
    );
};

const SectionHeading: React.FC<{ eyebrow: string; title: string; subtitle?: string }> = ({
    eyebrow,
    title,
    subtitle,
}) => (
    <div className="mb-5">
        <p className="text-xs font-semibold uppercase tracking-wide text-blue-600">{eyebrow}</p>
        <h2 className="mt-1 text-xl font-bold text-slate-900 tracking-tight">{title}</h2>
        {subtitle && <p className="mt-1.5 text-sm text-slate-600 leading-relaxed">{subtitle}</p>}
    </div>
);

// ─────────────────────────────────────────────────────────────────────────────
// Architecture diagram — a theme-aware CSS flow-box, left-to-right on desktop
// and top-down on mobile. Built from the app's card/badge vocabulary so it
// matches the surrounding typography and reads as an intentional diagram.
// ─────────────────────────────────────────────────────────────────────────────

const DiagramNode: React.FC<{
    icon: LucideIcon;
    title: string;
    lines: string[];
    accent?: 'default' | 'brand' | 'guard' | 'data';
}> = ({ icon: Icon, title, lines, accent = 'default' }) => {
    const accentClasses: Record<string, string> = {
        default:
            'border-slate-200 bg-white dark:border-slate-600 dark:bg-slate-800',
        brand:
            'border-blue-200 bg-blue-50 dark:border-blue-700 dark:bg-blue-900/40',
        guard:
            'border-emerald-200 bg-emerald-50 dark:border-emerald-700 dark:bg-emerald-900/30',
        data:
            'border-indigo-200 bg-indigo-50 dark:border-indigo-700 dark:bg-indigo-900/30',
    };
    const iconClasses: Record<string, string> = {
        default: 'text-slate-500 dark:text-slate-300',
        brand: 'text-blue-600 dark:text-blue-300',
        guard: 'text-emerald-600 dark:text-emerald-300',
        data: 'text-indigo-600 dark:text-indigo-300',
    };
    return (
        <div className={`flex-1 min-w-0 rounded-xl border p-4 ${accentClasses[accent]}`}>
            <div className="flex items-center gap-2">
                <Icon size={18} className={iconClasses[accent]} />
                <p className="text-sm font-semibold text-slate-900 dark:text-slate-100">{title}</p>
            </div>
            <ul className="mt-2 space-y-1">
                {lines.map(line => (
                    <li key={line} className="text-xs text-slate-600 dark:text-slate-300 leading-relaxed break-words">
                        {line}
                    </li>
                ))}
            </ul>
        </div>
    );
};

const FlowArrow: React.FC = () => (
    <div className="flex items-center justify-center text-slate-300 dark:text-slate-600 shrink-0" aria-hidden="true">
        <ChevronRight size={22} className="hidden lg:block" />
        <ArrowDown size={20} className="lg:hidden" />
    </div>
);

const ArchitectureDiagram: React.FC = () => (
    <div className="rounded-2xl border border-slate-200 bg-white p-5 sm:p-6 dark:border-slate-700 dark:bg-slate-900">
        <div className="flex flex-col lg:flex-row lg:items-stretch gap-3">
            <DiagramNode
                icon={Bot}
                title="MCP profile status"
                lines={[
                    'Codex CLI — Staging OAuth and read accepted',
                    'Claude Code — Staging OAuth/revoke accepted; read pending',
                ]}
            />
            <FlowArrow />
            <DiagramNode
                icon={Server}
                title="NexusCRM access"
                lines={['Administrator-managed OAuth profiles', 'Read-only MCP tools']}
                accent="brand"
            />
            <FlowArrow />
            <DiagramNode
                icon={Plug}
                title="NexusCRM platform"
                lines={['Browser sign-in', 'Read-only tools']}
            />
            <FlowArrow />
            <DiagramNode
                icon={ShieldCheck}
                title="Per-request security check"
                lines={['Your identity', 'Your permissions', 'Active employee', 'Environment binding']}
                accent="guard"
            />
            <FlowArrow />
            <DiagramNode
                icon={Database}
                title="Read-only CRM data"
                lines={['Only what you can see', 'Nothing more']}
                accent="data"
            />
        </div>
    </div>
);

// ─────────────────────────────────────────────────────────────────────────────
// Section: How it works
// ─────────────────────────────────────────────────────────────────────────────

const HowItWorksSection: React.FC = () => (
    <section id="how-it-works" className="scroll-mt-24">
        <SectionHeading
            eyebrow="Overview"
            title="How it works"
            subtitle="Use only an administrator-provisioned client profile with a documented acceptance status. Each profile has an exact registered callback and explicit scope; do not reuse another client's Client ID or callback. Every request is checked against your identity and permissions before it reaches read-only CRM data."
        />
        <ArchitectureDiagram />
        <div className="mt-4">
            <Callout title="Same authority, every path" tone="success" icon={<ShieldCheck size={18} />}>
                When a client profile is accepted, the assistant acts as you. It sees only the records your profile
                allows, and access ends automatically when your NexusCRM account is deactivated.
            </Callout>
        </div>
    </section>
);

// ─────────────────────────────────────────────────────────────────────────────
// Section: Codex CLI
// ─────────────────────────────────────────────────────────────────────────────

const CodexCliSection: React.FC<{ mcpUrl: string }> = ({ mcpUrl }) => {
    const addCommand = `codex mcp add nexuscrm --url "${mcpUrl}" --oauth-client-id nexuscrm-codex-connect`;
    const loginCommand = 'codex mcp login nexuscrm --scopes external.records.read';
    return (
        <section id="codex-cli" className="scroll-mt-24">
            <SectionHeading
                eyebrow="Codex CLI"
                title="Validated Codex CLI setup"
                subtitle="Codex 0.142.3 completed administrator-managed OAuth and one read-only CRM tool call in Formal Staging. Keep the explicit read-only scope login below; production acceptance is tracked separately."
            />
            <div className="rounded-xl border border-slate-200 bg-white p-5 space-y-4">
                <div className="space-y-3">
                    <p className="text-sm font-medium text-slate-800">1. Add the managed Codex setup:</p>
                    <pre className="overflow-x-auto rounded-lg bg-slate-900 px-4 py-3 text-sm leading-relaxed text-slate-100">
                        <code>{addCommand}</code>
                    </pre>
                    <p className="text-sm font-medium text-slate-800">
                        2. Request the approved read-only scope and complete browser sign-in:
                    </p>
                    <pre className="overflow-x-auto rounded-lg bg-slate-900 px-4 py-3 text-sm leading-relaxed text-slate-100">
                        <code>{loginCommand}</code>
                    </pre>
                </div>
            </div>
            <div className="mt-4 space-y-4">
                <Callout title="Formal Staging OAuth and read passed" tone="success" icon={<ShieldCheck size={18} />}>
                    With test-only <code className="font-mono">gpt-5.5</code>, Codex 0.142.3 initialized MCP, listed the
                    four current read tools, and completed one approved <code className="font-mono">list_objects</code>{' '}
                    call. No production acceptance is claimed by this Staging result.
                </Callout>
                <Callout title="Keep the explicit read-only login" tone="info" icon={<Info size={18} />}>
                    The accepted Codex run requested <code className="font-mono">external.records.read</code> explicitly in
                    step 2. Do not change the authorization server, persist an OAuth resource option, or request another scope.
                </Callout>
                <Callout title="Registered callback and resource behavior" tone="success" icon={<ShieldCheck size={18} />}>
                    With callback port <code className="font-mono">59152</code>, Codex 0.142.3 uses the single registered
                    callback <code className="font-mono">http://127.0.0.1:59152/callback/l-qlK3CGE-2s</code>. Do not
                    substitute another path or another client&apos;s callback. The managed profile deliberately does not persist
                    an OAuth resource: discovery supplies exactly one during sign-in.
                </Callout>
            </div>
        </section>
    );
};

// ─────────────────────────────────────────────────────────────────────────────
// Section: Claude Code
// ─────────────────────────────────────────────────────────────────────────────

const ClaudeCodeSection: React.FC<{ mcpUrl: string }> = ({ mcpUrl }) => {
    const addCommand = `claude mcp add --transport http nexuscrm --scope user --client-id nexuscrm-claude-code-connect --callback-port 3118 "${mcpUrl}"`;

    return (
        <section id="claude-code" className="scroll-mt-24">
            <SectionHeading
                eyebrow="Claude Code"
                title="Managed Claude Code setup"
                subtitle="Claude Code 2.1.221 completed administrator-managed OAuth in Formal Staging. A real CRM tool call remains pending on the tested CC Switch model channel."
            />
            <div className="rounded-xl border border-slate-200 bg-white p-5 space-y-4">
                <p className="text-sm font-medium text-slate-800">Add the managed Claude Code setup:</p>
                <pre className="overflow-x-auto rounded-lg bg-slate-900 px-4 py-3 text-sm leading-relaxed text-slate-100">
                    <code>{addCommand}</code>
                </pre>
            </div>
            <div className="mt-4 space-y-4">
                <Callout title="Use only the dedicated Claude Code profile" tone="info" icon={<ShieldCheck size={18} />}>
                    <code className="font-mono">--scope user</code> chooses Claude&apos;s local configuration placement; it does not
                    request an OAuth scope. The administrator-managed public client permits only{' '}
                    <code className="font-mono">external.records.read</code>, uses authorization code with PKCE, and issues no
                    refresh tokens. Keep <code className="font-mono">--callback-port 3118</code> fixed: it is the fixed port for
                    its pre-registered redirect URI <code className="font-mono">http://localhost:3118/callback</code>.
                </Callout>
                <Callout title="OAuth and revoke passed; real MCP read is pending" tone="warning" icon={<Info size={18} />}>
                    Formal Staging accepted the omitted-scope authorization by selecting the sole allowed{' '}
                    <code className="font-mono">external.records.read</code> scope. The connection appeared in Connected apps,
                    and disconnecting it required authentication again. The tested CC Switch model channel ended before a{' '}
                    <code className="font-mono">list_objects</code> call was issued, so Claude data access is not accepted yet.
                </Callout>
            </div>
        </section>
    );
};

// ─────────────────────────────────────────────────────────────────────────────
// Section: Manage your access
// ─────────────────────────────────────────────────────────────────────────────

const ManageAccessSection: React.FC<{ onOpenConnections: () => void }> = ({ onOpenConnections }) => (
    <section id="manage-access" className="scroll-mt-24">
        <SectionHeading
            eyebrow="Stay in control"
            title="Manage your access"
            subtitle="Review and disconnect the OAuth connections you have authorized from NexusCRM at any time."
        />
        <div className="grid grid-cols-1 gap-4">
            <button
                type="button"
                onClick={onOpenConnections}
                className="group text-left rounded-xl border border-slate-200 bg-white p-5 hover:border-blue-300 hover:shadow-sm transition-all"
            >
                <div className="flex items-center justify-between">
                    <div className="w-11 h-11 rounded-xl bg-blue-50 flex items-center justify-center">
                        <Plug size={22} className="text-blue-600" />
                    </div>
                    <ArrowRight size={16} className="text-slate-400 group-hover:text-blue-600" />
                </div>
                <h3 className="mt-3 text-sm font-semibold text-slate-900">Connected apps</h3>
                <p className="mt-1 text-sm text-slate-600">
                    Review and disconnect the AI clients you authorized with OAuth.
                </p>
            </button>
        </div>
    </section>
);

// ─────────────────────────────────────────────────────────────────────────────
// Section: FAQ
// ─────────────────────────────────────────────────────────────────────────────

const FAQS: Array<{ q: string; a: React.ReactNode }> = [
    {
        q: 'What happens when I leave?',
        a: 'Your access is revoked automatically at offboarding. When your NexusCRM account is deactivated, every connected app stops working immediately — there is nothing for you to clean up.',
    },
    {
        q: 'Do I need an administrator to set this up?',
        a: 'Only use the client configuration with the acceptance status documented on this page. An administrator provisions the Client ID, exact callback, and allowed scope for each supported OAuth client. After that, users sign in and can revoke their own OAuth connections.',
    },
    {
        q: 'Is a managed profile more powerful than the CRM UI?',
        a: 'No. An OAuth connection acts as you and sees only what your permissions allow. The available MCP tools are read-only.',
    },
    {
        q: 'Can the assistant change my data?',
        a: 'The connected tools are read-only and bounded by your field-level and record-level security. Any write still goes through the same approval processes as the UI.',
    },
    {
        q: 'Can I paste the MCP URL into another client?',
        a: 'No. Do not reuse another client\'s configuration. A client configuration appears here only with its managed OAuth acceptance status; do not use it for data access until that status is accepted.',
    },
];

const FaqSection: React.FC = () => (
    <section id="faq" className="scroll-mt-24">
        <SectionHeading eyebrow="Questions" title="Frequently asked" subtitle="Short answers to the most common questions." />
        <div className="space-y-3">
            {FAQS.map(item => (
                <div key={item.q} className="rounded-xl border border-slate-200 bg-white p-5">
                    <p className="text-sm font-semibold text-slate-900">{item.q}</p>
                    <p className="mt-1.5 text-sm text-slate-600 leading-relaxed">{item.a}</p>
                </div>
            ))}
        </div>
    </section>
);

// ─────────────────────────────────────────────────────────────────────────────
// Page
// ─────────────────────────────────────────────────────────────────────────────

export const AiIntegrationHelp: React.FC = () => {
    const navigate = useNavigate();
    const origin = useMemo(() => resolveOrigin(), []);
    const mcpUrl = `${origin}/mcp`;
    const [activeSection, setActiveSection] = useState<string>(SECTIONS[0].id);

    const openConnections = useCallback(() => navigate('/settings/connections'), [navigate]);

    // Scroll spy: highlight the section nearest the top of the viewport.
    useEffect(() => {
        if (typeof IntersectionObserver === 'undefined') return;
        const observer = new IntersectionObserver(
            entries => {
                const visible = entries
                    .filter(entry => entry.isIntersecting)
                    .sort((a, b) => a.boundingClientRect.top - b.boundingClientRect.top);
                if (visible.length > 0) {
                    setActiveSection(visible[0].target.id);
                }
            },
            { rootMargin: '-96px 0px -60% 0px', threshold: 0 },
        );
        for (const section of SECTIONS) {
            const el = document.getElementById(section.id);
            if (el) observer.observe(el);
        }
        return () => observer.disconnect();
    }, []);

    const handleNavClick = useCallback((id: string) => {
        const el = document.getElementById(id);
        if (el) {
            el.scrollIntoView({ behavior: 'smooth', block: 'start' });
            setActiveSection(id);
        }
    }, []);

    return (
        <div className="h-full overflow-y-auto bg-slate-50">
            {/* Hero */}
            <div className="bg-gradient-to-br from-blue-600 to-indigo-700 text-white">
                <div className="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8 py-10">
                    <div className="flex items-center gap-2 text-blue-100 text-sm font-medium mb-3">
                        <Plug size={16} />
                        <span>AI &amp; integrations</span>
                    </div>
                    <h1 className="text-3xl font-bold tracking-tight">Connect your AI assistant to NexusCRM</h1>
                    <p className="mt-2 text-blue-100 max-w-2xl leading-relaxed">
                        Choose a documented client path and sign in as yourself. Do not reuse a Client ID or callback from
                        another client. The same permissions, approvals, and audit trail apply on every supported path.
                    </p>
                    <div className="mt-5">
                        <button
                            type="button"
                            onClick={() => handleNavClick('codex-cli')}
                            className="inline-flex items-center gap-2 px-4 py-2 text-sm font-semibold rounded-lg bg-white text-blue-700 hover:bg-blue-50 transition-colors shrink-0"
                        >
                            <Zap size={16} />
                            <span>View client setup</span>
                        </button>
                    </div>
                </div>
            </div>

            {/* Body: sticky section nav + content */}
            <div className="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
                <div className="flex flex-col lg:flex-row gap-8">
                    <nav className="lg:w-64 shrink-0">
                        <ul className="space-y-1 lg:sticky lg:top-6">
                            <li className="px-3 pb-2 text-xs font-semibold uppercase tracking-wide text-slate-400 flex items-center gap-1.5">
                                <ListChecks size={13} />
                                <span>On this page</span>
                            </li>
                            {SECTIONS.map(section => {
                                const Icon = section.icon;
                                const isActive = section.id === activeSection;
                                return (
                                    <li key={section.id}>
                                        <button
                                            type="button"
                                            onClick={() => handleNavClick(section.id)}
                                            aria-current={isActive ? 'true' : undefined}
                                            className={`w-full flex items-center gap-2.5 px-3 py-2 rounded-lg text-sm text-left transition-colors ${
                                                isActive
                                                    ? 'bg-blue-50 text-blue-700 font-semibold'
                                                    : 'text-slate-600 hover:bg-slate-100'
                                            }`}
                                        >
                                            <Icon size={16} className={isActive ? 'text-blue-600' : 'text-slate-400'} />
                                            <span className="min-w-0">{section.label}</span>
                                        </button>
                                    </li>
                                );
                            })}
                        </ul>
                    </nav>

                    <div className="min-w-0 flex-1 max-w-3xl space-y-12">
                        <HowItWorksSection />
                        <CodexCliSection mcpUrl={mcpUrl} />
                        <ClaudeCodeSection mcpUrl={mcpUrl} />
                        <ManageAccessSection onOpenConnections={openConnections} />
                        <FaqSection />

                        <div className="pt-6 border-t border-slate-200 flex items-center justify-between text-sm">
                            <span className="inline-flex items-center gap-1.5 text-slate-500">
                                <Server size={14} />
                                <span>Use the client-specific setup above</span>
                            </span>
                            <button
                                type="button"
                                onClick={openConnections}
                                className="inline-flex items-center gap-1.5 text-slate-500 hover:text-slate-700"
                            >
                                <UserCheck size={14} />
                                <span>Manage connected apps</span>
                            </button>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    );
};

export default AiIntegrationHelp;
