'use client';
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
/**
 * PublishToGitHubModal — owner picker + repo name + visibility for one-click
 * GitHub publishing. Designed for non-technical users:
 *   • Title is "Publish to GitHub" (not "create remote").
 *   • Owner dropdown lists the authenticated user's personal account first
 *     and every org they belong to. The default selection is the personal
 *     account so the happy path is "click Publish".
 *   • Repo name is pre-filled with a sensible default (the application slug)
 *     and is freely editable.
 *   • Visibility toggle defaults to Public.
 *
 * The modal is purely presentational — it doesn't talk to the API directly.
 * The parent button hands it the owner list and a submit callback.
 */
import { useEffect, useMemo, useState } from 'react';
import { ExternalLink, Loader2, Lock, Unlock, AlertTriangle } from 'lucide-react';
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from '../../ui/dialog.js';
import { Button } from '../../ui/button.js';
import { Input } from '../../ui/input.js';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '../../ui/select.js';
import { Switch } from '../../ui/switch.js';
import { cn } from '../../../lib/utils.js';
import { GitHubIcon } from './cloud-provider-icons.js';
const REPO_NAME_PATTERN = /^[A-Za-z0-9._-]+$/;
export function PublishToGitHubModal({ open, onOpenChange, owners, defaultRepoName, initialOwnerLogin, onSubmit, }) {
    return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { className: "max-w-md", children: [_jsxs(DialogHeader, { children: [_jsxs(DialogTitle, { className: "flex items-center gap-2", children: [_jsx(GitHubIcon, { className: "size-5" }), "Publish to GitHub"] }), _jsx(DialogDescription, { children: "Pick where this app should live on GitHub and what to call it. We'll create the repository and push the code in one go." })] }), _jsx(PublishToGitHubForm, { owners: owners, defaultRepoName: defaultRepoName, initialOwnerLogin: initialOwnerLogin, onSubmit: onSubmit, onCancel: () => onOpenChange(false), variant: "dialog" })] }) }));
}
export function PublishToGitHubForm({ owners, defaultRepoName, initialOwnerLogin, onSubmit, onCancel, variant = 'dialog', }) {
    const initialOwner = useMemo(() => {
        if (initialOwnerLogin) {
            const match = owners.find((o) => o.login === initialOwnerLogin);
            if (match)
                return match.login;
        }
        return owners[0]?.login ?? '';
    }, [owners, initialOwnerLogin]);
    const [ownerLogin, setOwnerLogin] = useState(initialOwner);
    const [repoName, setRepoName] = useState(defaultRepoName);
    // Private by default — protect the user's code unless they
    // explicitly choose to make it public. Earlier versions defaulted
    // to public which leaked an unknown amount of user code to the
    // open internet on the very first publish click.
    const [isPublic, setIsPublic] = useState(false);
    const [submitting, setSubmitting] = useState(false);
    const [error, setError] = useState(null);
    // Re-sync defaults whenever the owner list or default name changes
    // from the parent (e.g. new app context, first load of /orgs). For
    // the dialog variant this mirrors the old open-state reset.
    useEffect(() => {
        setOwnerLogin(initialOwner);
        setRepoName(defaultRepoName);
        setError(null);
        setSubmitting(false);
    }, [initialOwner, defaultRepoName]);
    const trimmedName = repoName.trim();
    const nameValid = trimmedName.length > 0 && REPO_NAME_PATTERN.test(trimmedName);
    const ownerValid = ownerLogin.trim().length > 0;
    const canSubmit = nameValid && ownerValid && !submitting;
    const previewUrl = ownerValid && nameValid ? `github.com/${ownerLogin}/${trimmedName}` : null;
    async function handleSubmit() {
        if (!canSubmit)
            return;
        setSubmitting(true);
        setError(null);
        try {
            await onSubmit({
                ownerLogin,
                repoName: trimmedName,
                visibility: isPublic ? 'public' : 'private',
            });
        }
        catch (err) {
            const msg = err instanceof Error ? err.message : 'Failed to publish';
            // GitHubRepoNameTakenError message: 'Repository "name" already exists on owner.'
            // Detect it and offer a clear rename suggestion so the user
            // doesn't need to guess what went wrong.
            if (/already exists/i.test(msg)) {
                // Suggest a numbered variant of whatever they typed.
                const suggestion = /\d+$/.test(trimmedName)
                    ? trimmedName.replace(/\d+$/, (n) => String(Number(n) + 1))
                    : `${trimmedName}-2`;
                setError(`"${trimmedName}" is already taken on GitHub — try "${suggestion}" or any other unique name.`);
            }
            else {
                setError(msg);
            }
        }
        finally {
            setSubmitting(false);
        }
    }
    const isSubpanel = variant === 'subpanel';
    return (_jsxs("div", { className: cn('flex flex-col', isSubpanel ? 'gap-3 px-4 py-3' : 'gap-0'), children: [_jsxs("div", { className: cn('grid', isSubpanel ? 'gap-3' : 'gap-4 py-2'), children: [_jsxs("label", { className: "grid gap-1.5", children: [_jsx("span", { className: "text-muted-foreground text-[10px] font-medium tracking-wide uppercase", children: "Owner" }), _jsxs(Select, { value: ownerLogin, onValueChange: setOwnerLogin, disabled: submitting, children: [_jsx(SelectTrigger, { className: isSubpanel ? 'h-8 text-xs' : undefined, children: _jsx(SelectValue, { placeholder: "Choose an owner\u2026" }) }), _jsx(SelectContent, { children: owners.map((owner) => (_jsx(SelectItem, { value: owner.login, children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "font-medium", children: owner.login }), _jsx("span", { className: "text-muted-foreground text-xs", children: owner.kind === 'user' ? 'personal' : 'organization' })] }) }, owner.login))) })] })] }), _jsxs("label", { className: "grid gap-1.5", children: [_jsx("span", { className: "text-muted-foreground text-[10px] font-medium tracking-wide uppercase", children: "Repository name" }), _jsx(Input, { value: repoName, onChange: (e) => setRepoName(e.target.value), placeholder: "my-cool-app", disabled: submitting, autoComplete: "off", spellCheck: false, className: isSubpanel ? 'h-8 text-xs' : undefined }), !nameValid && repoName.length > 0 ? (_jsxs("span", { className: "text-destructive flex items-center gap-1 text-xs", children: [_jsx(AlertTriangle, { className: "size-3" }), "Use letters, numbers, dots, dashes, or underscores."] })) : null] }), _jsxs("div", { className: cn('bg-muted/40 flex items-center justify-between rounded-md border', isSubpanel ? 'px-2.5 py-1.5' : 'px-3 py-2'), children: [_jsxs("div", { className: "flex items-center gap-2", children: [isPublic ? (_jsx(Unlock, { className: "size-4 text-emerald-500" })) : (_jsx(Lock, { className: "text-muted-foreground size-4" })), _jsxs("div", { children: [_jsx("div", { className: cn('font-medium', isSubpanel ? 'text-xs' : 'text-sm'), children: isPublic ? 'Public' : 'Private' }), _jsx("div", { className: cn('text-muted-foreground', isSubpanel ? 'text-[10px]' : 'text-xs'), children: isPublic
                                                    ? 'Anyone can see this repository on GitHub.'
                                                    : 'Only you and people you invite can see it.' })] })] }), _jsx(Switch, { checked: isPublic, onCheckedChange: setIsPublic, disabled: submitting, "aria-label": "Toggle public visibility" })] }), previewUrl ? (_jsxs("div", { className: cn('text-muted-foreground inline-flex items-center gap-1', isSubpanel ? 'text-[10px]' : 'text-xs'), children: [_jsx(ExternalLink, { className: "size-3" }), _jsx("span", { className: "truncate", children: previewUrl })] })) : null, error ? (_jsxs("p", { className: "text-destructive flex items-start gap-1 text-xs", children: [_jsx(AlertTriangle, { className: "mt-px size-3 shrink-0" }), _jsx("span", { children: error })] })) : null] }), isSubpanel ? (_jsxs("div", { className: "flex items-center justify-end gap-2 pt-1", children: [_jsx(Button, { variant: "ghost", size: "sm", onClick: onCancel, disabled: submitting, className: "h-7 cursor-pointer text-[11px]", children: "Cancel" }), _jsx(Button, { size: "sm", onClick: handleSubmit, disabled: !canSubmit, className: "h-7 cursor-pointer text-[11px]", children: submitting ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { className: "size-3 animate-spin" }), "Publishing\u2026"] })) : ('Publish') })] })) : (_jsxs(DialogFooter, { children: [_jsx(Button, { variant: "ghost", onClick: onCancel, disabled: submitting, className: "cursor-pointer", children: "Cancel" }), _jsx(Button, { onClick: handleSubmit, disabled: !canSubmit, className: "cursor-pointer", children: submitting ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { className: "size-3 animate-spin" }), "Publishing\u2026"] })) : ('Publish') })] }))] }));
}
