import { useState, type ReactNode } from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faCircleCheck, faCircle } from '@fortawesome/pro-duotone-svg-icons';
import { Button } from '@/components/base/buttons/button';
import { cx } from '@/utils/cx';
import { SETUP_STEP_NAMES, SETUP_STEP_LABELS, type SetupStepName, type SetupState } from '@/lib/setup-state';
import { WizardLayoutContext } from './wizard-layout-context';

type WizardShellProps = {
    state: SetupState;
    activeStep: SetupStepName;
    onSelectStep: (step: SetupStepName) => void;
    onDismiss: () => void;
    // Form column (middle pane). The active step component renders
    // its form into this slot. The right pane is filled via the
    // WizardLayoutContext + a portal — see wizard-step.tsx.
    children: ReactNode;
};

// Layout shell for the onboarding wizard. Three-pane layout:
//   left   — step navigator (fixed width)
//   middle — form (flexible, the focus column)
//   right  — preview pane fed by the active step component (sticky,
//            hides below xl breakpoint)
//
// The whole shell is `fixed inset-0` so the document body cannot
// scroll while the wizard is mounted — fixes the double-scrollbar
// bug where the body was rendered taller than the viewport and
// scrolled alongside the form column. The form and preview columns
// each scroll independently inside the shell.
//
// The header has a "Skip for now" affordance that dismisses the
// wizard for this workspace; once dismissed it never auto-shows
// again on login.
export const WizardShell = ({
    state,
    activeStep,
    onSelectStep,
    onDismiss,
    children,
}: WizardShellProps) => {
    const completedCount = SETUP_STEP_NAMES.filter((s) => state.steps[s].completed).length;
    const totalSteps = SETUP_STEP_NAMES.length;
    const progressPct = Math.round((completedCount / totalSteps) * 100);

    // Callback ref → state — guarantees that consumers re-render once
    // the aside is mounted (a plain useRef would not propagate the
    // attached node back through the context). The element is also
    // updated to null on unmount so the context is always honest about
    // whether the slot is currently available for portals.
    const [rightPaneEl, setRightPaneEl] = useState<HTMLElement | null>(null);

    return (
        <WizardLayoutContext.Provider value={{ rightPaneEl }}>
        <div className="fixed inset-0 z-50 flex flex-col bg-primary">
            {/* Header — pinned. Progress bar always visible (grey
                track when 0%), sits flush under the title row. */}
            <header className="shrink-0 border-b border-secondary bg-primary">
                <div className="mx-auto flex w-full max-w-screen-2xl items-center justify-between gap-6 px-8 pt-4 pb-3">
                    <div className="flex items-center gap-4">
                        <div>
                            <h1 className="text-lg font-bold text-primary">Set up your hospital</h1>
                            <p className="text-xs text-tertiary">
                                {completedCount} of {totalSteps} steps complete · finish setup to start
                                using your workspace
                            </p>
                        </div>
                    </div>
                    <Button color="link-gray" size="sm" onClick={onDismiss}>
                        Skip for now
                    </Button>
                </div>
                <div className="mx-auto w-full max-w-screen-2xl px-8 pb-3">
                    <div className="h-1.5 w-full overflow-hidden rounded-full bg-secondary">
                        <div
                            className="h-full rounded-full bg-brand-solid transition-all duration-300"
                            style={{ width: `${progressPct}%` }}
                        />
                    </div>
                </div>
            </header>

            {/* Body — three columns inside a fixed-height flex row.
                min-h-0 on the row + each column lets the inner
                overflow-y-auto actually take effect. */}
            <div className="mx-auto flex min-h-0 w-full max-w-screen-2xl flex-1 gap-6 px-8 py-6">
                {/* Left — step navigator. Scrolls if it overflows on
                    very short viewports, but in practice it fits. */}
                <nav className="w-60 shrink-0 overflow-y-auto">
                    <ol className="flex flex-col gap-1">
                        {SETUP_STEP_NAMES.map((step, idx) => {
                            const meta = SETUP_STEP_LABELS[step];
                            const status = state.steps[step];
                            const isActive = step === activeStep;
                            const isComplete = status.completed;
                            return (
                                <li key={step}>
                                    <button
                                        type="button"
                                        onClick={() => onSelectStep(step)}
                                        className={cx(
                                            'group flex w-full items-start gap-3 rounded-lg border px-3 py-2.5 text-left transition',
                                            isActive
                                                ? 'border-brand bg-brand-primary'
                                                : 'border-transparent hover:bg-secondary',
                                        )}
                                    >
                                        <span className="mt-0.5 shrink-0">
                                            <FontAwesomeIcon
                                                icon={isComplete ? faCircleCheck : faCircle}
                                                className={cx(
                                                    'size-5',
                                                    isComplete
                                                        ? 'text-success-primary'
                                                        : 'text-quaternary',
                                                )}
                                            />
                                        </span>
                                        <span className="flex-1">
                                            <span className="block text-xs font-medium text-tertiary">
                                                Step {idx + 1}
                                            </span>
                                            <span
                                                className={cx(
                                                    'block text-sm font-semibold',
                                                    isActive ? 'text-brand-primary' : 'text-primary',
                                                )}
                                            >
                                                {meta.title}
                                            </span>
                                        </span>
                                    </button>
                                </li>
                            );
                        })}
                    </ol>
                </nav>

                {/* Middle — form column. min-w-0 prevents children from
                    forcing the column wider than its flex basis (long
                    inputs, etc.). overflow-y-auto so it scrolls
                    independently of the right pane. */}
                <main className="flex min-w-0 flex-1 flex-col overflow-y-auto">{children}</main>

                {/* Right — preview pane. Always rendered as a stable
                    portal target (so the active step's WizardStep can
                    createPortal into it via WizardLayoutContext).
                    Hidden below xl breakpoint (1280px) so the wizard
                    collapses cleanly to two columns on smaller screens.
                    Independent scroll. */}
                <aside
                    ref={setRightPaneEl}
                    className="hidden w-80 shrink-0 overflow-y-auto xl:block"
                />
            </div>
        </div>
        </WizardLayoutContext.Provider>
    );
};
