'use client';
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
/**
 * Web preview tab — embeds the running dev server as an iframe inside
 * the application page's right pane. Wired to the same deploy state
 * as the top-bar Run button so there's a single source of truth.
 *
 * States:
 *   - Ready   → <iframe src={url}> with an "open in new tab" badge
 *   - Booting → spinner + "Starting dev server…"
 *   - Idle    → friendly empty state pointing at the Run button
 *   - Error   → deploy error with a retry hint
 *
 * The iframe is always mounted once we have a URL so switching tabs
 * (IDE → Terminal → Web) does NOT tear down the preview session. It
 * is loaded without a `sandbox` attribute because Vite HMR needs
 * websockets and script execution; this is safe because the target
 * is always localhost on the user's machine.
 */
import { useCallback } from 'react';
import { ExternalLink, Globe, Hammer, Loader2, Play, Square, TriangleAlert } from 'lucide-react';
import { DeploymentState } from '../../../../../../packages/core/src/domain/generated/output.js';
export function WebPreviewTab({ deploy, isBuilding = false }) {
    const openInNewTab = useCallback(() => {
        if (deploy.url)
            window.open(deploy.url, '_blank', 'noopener,noreferrer');
    }, [deploy.url]);
    // While the project tree is still being produced we own this pane —
    // no iframe, no "Start preview" CTA, just a soft progress placeholder
    // so the Web tab feels alive from the first moment the user lands.
    if (isBuilding && deploy.status !== DeploymentState.Ready) {
        return _jsx(BuildingStub, {});
    }
    // Ready — live iframe
    if (deploy.status === DeploymentState.Ready && deploy.url) {
        return (
        // Outer container is themed (not hard-coded bg-white) so the
        // URL bar gets a proper dark-mode surface underneath; only the
        // iframe itself is forced white so the rendered app has a
        // neutral canvas.
        _jsxs("div", { className: "bg-background flex min-h-0 flex-1 flex-col", children: [_jsxs("div", { className: "border-border bg-muted/70 text-foreground flex h-8 shrink-0 items-center gap-2 border-b px-2 text-[11px] dark:bg-neutral-900", children: [_jsxs("span", { className: "relative flex h-2 w-2 shrink-0", children: [_jsx("span", { className: "absolute inline-flex h-full w-full animate-ping rounded-full bg-emerald-400 opacity-60" }), _jsx("span", { className: "relative inline-flex h-2 w-2 rounded-full bg-emerald-500" })] }), _jsx("span", { className: "text-foreground/90 truncate font-mono", children: deploy.url }), _jsx("div", { className: "flex-1" }), _jsxs("button", { type: "button", onClick: openInNewTab, className: "text-muted-foreground hover:text-foreground hover:bg-background/60 inline-flex cursor-pointer items-center gap-1 rounded px-1.5 py-0.5 transition-colors dark:hover:bg-neutral-800", title: "Open in a new browser tab", children: [_jsx(ExternalLink, { className: "h-3 w-3" }), _jsx("span", { children: "Open" })] }), _jsxs("button", { type: "button", onClick: deploy.stop, disabled: deploy.stopLoading, className: "text-muted-foreground hover:bg-destructive/10 hover:text-destructive inline-flex cursor-pointer items-center gap-1 rounded px-1.5 py-0.5 transition-colors disabled:cursor-not-allowed disabled:opacity-50", title: "Stop the dev server", "aria-label": "Stop the dev server", children: [deploy.stopLoading ? (_jsx(Loader2, { className: "h-3 w-3 animate-spin" })) : (_jsx(Square, { className: "h-3 w-3 fill-current" })), _jsx("span", { children: "Stop" })] })] }), _jsx("iframe", { src: deploy.url, className: "min-h-0 w-full flex-1 border-0 bg-white", title: "Application preview" }, deploy.url)] }));
    }
    // Booting — spinner
    if (deploy.status === DeploymentState.Booting || deploy.deployLoading) {
        return (_jsx(EmptyState, { icon: _jsx(Loader2, { className: "text-muted-foreground h-8 w-8 animate-spin" }), title: "Starting dev server\u2026", description: "Installing dependencies and booting the app. This can take a minute on the first run." }));
    }
    // Error
    if (deploy.deployError) {
        return (_jsx(EmptyState, { icon: _jsx(TriangleAlert, { className: "h-8 w-8 text-red-500" }), title: "Failed to start dev server", description: deploy.deployError, actionLabel: "Retry", onAction: deploy.deploy }));
    }
    // Idle — CTA kicks off the dev server. Doubles as the redundant
    // entry point for users who land here from the IDE/Terminal tabs and
    // want to see the preview — clicking the Web tab itself ALSO starts
    // the dev server (see app-view-tabs.tsx), so this is the "I'm
    // already here, just start it" affordance.
    return (_jsx(EmptyState, { icon: _jsx(Globe, { className: "text-muted-foreground h-8 w-8" }), title: "No live preview yet", description: "Click Start preview to install dependencies and run the app locally. Your live preview will appear here.", actionLabel: "Start preview", actionIcon: _jsx(Play, { className: "h-3.5 w-3.5 fill-current" }), onAction: deploy.deploy }));
}
/**
 * "Building your app…" placeholder for the Web pane — visible while
 * the scaffolder or the agent is still producing the app. A sibling
 * of EmptyState but with its own richer visual so it reads as an
 * active progress stub rather than an error-adjacent empty state.
 */
function BuildingStub() {
    return (_jsxs("div", { className: "relative flex min-h-0 flex-1 items-center justify-center overflow-hidden p-6", children: [_jsx("div", { "aria-hidden": true, className: "from-primary/10 via-background to-background pointer-events-none absolute inset-0 bg-gradient-to-br" }), _jsx("div", { "aria-hidden": true, className: "bg-[radial-gradient(circle,theme(colors.muted.DEFAULT)_1px,transparent_1px)] pointer-events-none absolute inset-0 [background-size:24px_24px] opacity-20" }), _jsxs("div", { className: "relative flex max-w-sm flex-col items-center gap-4 text-center", children: [_jsxs("div", { className: "bg-background border-border ring-primary/10 relative inline-flex size-12 items-center justify-center rounded-full border shadow-sm ring-4", children: [_jsx(Hammer, { className: "text-primary size-5" }), _jsx("span", { className: "bg-primary absolute -end-1 -top-1 inline-flex size-3 items-center justify-center rounded-full", children: _jsx(Loader2, { className: "text-primary-foreground size-2.5 animate-spin" }) })] }), _jsxs("div", { className: "flex flex-col gap-1", children: [_jsx("h3", { className: "text-foreground text-sm font-semibold", children: "Building your app\u2026" }), _jsx("p", { className: "text-muted-foreground text-xs leading-relaxed", children: "Setting up the project tree, installing dependencies, and generating components. Your live preview will land here the moment the app is ready." })] }), _jsxs("div", { className: "text-muted-foreground inline-flex items-center gap-1.5 text-[11px]", children: [_jsx(Loader2, { className: "size-3 animate-spin" }), _jsx("span", { children: "Working on it" })] })] })] }));
}
function EmptyState({ icon, title, description, actionLabel, actionIcon, onAction, }) {
    return (_jsx("div", { className: "flex min-h-0 flex-1 items-center justify-center p-6", children: _jsxs("div", { className: "flex max-w-sm flex-col items-center gap-3 text-center", children: [icon, _jsx("h3", { className: "text-foreground text-sm font-semibold", children: title }), _jsx("p", { className: "text-muted-foreground text-xs leading-relaxed", children: description }), actionLabel && onAction ? (_jsxs("button", { type: "button", onClick: onAction, className: "border-primary/40 bg-primary/5 text-primary hover:bg-primary/10 mt-2 inline-flex h-8 cursor-pointer items-center gap-1.5 rounded-md border px-3 text-xs font-medium transition-colors", children: [actionIcon, _jsx("span", { children: actionLabel })] })) : null] }) }));
}
