'use client';
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { AlertTriangle, ArrowUpCircle, CheckCircle2, Database, ExternalLink, Eye, EyeOff, GitPullRequest, Loader2, Lock, Puzzle, RefreshCw, ShieldAlert, } from 'lucide-react';
import { useState } from 'react';
import { SettingsCard, SettingsControlRow, SettingsSaveBar } from './components.js';
import { useUpdates, } from './useUpdates.js';
const SEVERITY = {
    patch: { banner: 'border-brand/30 bg-brand/10', text: 'text-brand', label: 'Patch' },
    minor: { banner: 'border-warning/30 bg-warning/10', text: 'text-warning', label: 'Minor' },
    major: {
        banner: 'border-destructive/30 bg-destructive/10',
        text: 'text-destructive',
        label: 'Major',
    },
    security: {
        banner: 'border-destructive/40 bg-destructive/15',
        text: 'text-destructive',
        label: 'Security',
    },
};
const CHANGE_TYPE = {
    feature: { label: 'Feature', className: 'border-brand/30 bg-brand/10 text-brand' },
    improvement: {
        label: 'Improvement',
        className: 'border-border bg-muted text-muted-foreground',
    },
    fix: { label: 'Fix', className: 'border-border bg-muted text-muted-foreground' },
    breaking: {
        label: 'Breaking',
        className: 'border-destructive/30 bg-destructive/10 text-destructive',
    },
    security: {
        label: 'Security',
        className: 'border-destructive/40 bg-destructive/15 text-destructive',
    },
    deprecation: { label: 'Deprecated', className: 'border-warning/30 bg-warning/10 text-warning' },
};
const ghInputClass = 'w-full rounded-md border border-border bg-input-background px-3 py-2 text-base text-foreground focus-visible:ring-2 focus-visible:ring-ring focus-visible:outline-none';
/** Group a flat changelog list into per-version buckets (order preserved). */
function groupByVersion(changelog) {
    const groups = [];
    for (const item of changelog) {
        const last = groups[groups.length - 1];
        if (last && last.version === item.version) {
            last.items.push(item);
        }
        else {
            groups.push({ version: item.version, date: item.date, items: [item] });
        }
    }
    return groups;
}
function ChangeTypeBadge({ type }) {
    if (!type)
        return null;
    const meta = CHANGE_TYPE[type];
    return (_jsx("span", { className: `inline-flex shrink-0 items-center rounded border px-1.5 py-0.5 text-xs font-medium ${meta.className}`, children: meta.label }));
}
/** A bordered notice row used for migration / breaking-change callouts. */
function Notice({ tone, icon, title, children, }) {
    const toneClass = tone === 'destructive'
        ? 'border-destructive/30 bg-destructive/10 text-destructive'
        : 'border-warning/30 bg-warning/10 text-warning';
    return (_jsxs("div", { className: `mt-3 flex items-start gap-2.5 rounded-md border p-3 ${toneClass}`, children: [_jsx("span", { className: "mt-0.5 shrink-0", "aria-hidden": "true", children: icon }), _jsxs("div", { className: "min-w-0 text-sm", children: [_jsx("p", { className: "font-medium", children: title }), children && _jsx("div", { className: "text-foreground/80 mt-1 space-y-1", children: children })] })] }));
}
export function UpdatesTab({ role }) {
    const { info, checking, hasChecked, error, applying, prResult, canManage, form, setField, dirty, repoError, hasErrors, saveState, save, reset, check, apply, } = useUpdates({ role });
    const [showToken, setShowToken] = useState(false);
    const severity = info?.updateAvailable ? SEVERITY[info.severity ?? 'patch'] : null;
    const changelogGroups = info?.changelog ? groupByVersion(info.changelog) : [];
    return (_jsxs(_Fragment, { children: [_jsx(SettingsCard, { title: "Actuate CMS", description: "Keep your CMS up to date with the latest features and security patches.", actions: _jsxs("button", { type: "button", onClick: check, disabled: checking, className: "border-border text-foreground hover:bg-accent inline-flex items-center gap-2 rounded-md border px-4 py-2 text-sm font-medium transition-colors disabled:opacity-50", children: [_jsx(RefreshCw, { size: 16, className: checking ? 'animate-spin' : '', "aria-hidden": "true" }), checking ? 'Checking…' : 'Check for Updates'] }), children: _jsxs("p", { className: "text-muted-foreground text-sm", children: ["Current version:", ' ', _jsx("span", { className: "text-foreground font-mono font-medium", children: info?.current ?? '…' })] }) }), error && (_jsxs("div", { role: "alert", className: "border-destructive/30 bg-destructive/10 text-destructive flex items-center gap-3 rounded-lg border p-3 text-sm", children: [_jsx(AlertTriangle, { size: 20, className: "shrink-0", "aria-hidden": "true" }), _jsx("span", { className: "flex-1", children: error }), _jsx("button", { type: "button", onClick: check, className: "border-destructive/40 rounded-md border px-3 py-1 transition-colors hover:opacity-80", children: "Retry" })] })), hasChecked && info && !info.updateAvailable && !error && (_jsxs("div", { className: "border-success/30 bg-success/10 flex items-center gap-3 rounded-lg border p-4", children: [_jsx(CheckCircle2, { size: 24, className: "text-success shrink-0", "aria-hidden": "true" }), _jsxs("div", { children: [_jsx("h3", { className: "text-foreground font-medium", children: "You're up to date!" }), _jsxs("p", { className: "text-muted-foreground mt-0.5 text-sm", children: ["Actuate CMS ", _jsx("span", { className: "font-mono", children: info.current }), " is the latest version."] })] })] })), info?.updateAvailable && severity && (_jsxs("div", { className: `rounded-lg border p-4 ${severity.banner}`, children: [_jsxs("div", { className: "flex items-start gap-3", children: [info.severity === 'security' ? (_jsx(ShieldAlert, { size: 24, className: `mt-0.5 shrink-0 ${severity.text}`, "aria-hidden": "true" })) : (_jsx(ArrowUpCircle, { size: 24, className: `mt-0.5 shrink-0 ${severity.text}`, "aria-hidden": "true" })), _jsxs("div", { className: "flex-1", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx("h3", { className: `font-medium ${severity.text}`, children: info.severity === 'security' ? 'Security update available' : 'Update available' }), _jsx("span", { className: `inline-flex items-center rounded border px-2 py-0.5 text-xs font-medium ${severity.banner} ${severity.text}`, children: severity.label })] }), _jsxs("p", { className: "text-muted-foreground mt-1 text-sm", children: [_jsx("span", { className: "font-mono", children: info.current }), " \u2192", ' ', _jsx("span", { className: "text-foreground font-mono font-medium", children: info.latest }), info.releaseDate && (_jsxs("span", { className: "ml-2 text-xs opacity-70", children: ["Released ", info.releaseDate] }))] })] })] }), info.hasMigrations && (_jsx(Notice, { tone: "warning", icon: _jsx(Database, { size: 16 }), title: "Database migrations required", children: _jsxs("p", { children: ["Run", ' ', _jsx("code", { className: "bg-muted rounded px-1 font-mono text-xs", children: "npx prisma migrate deploy" }), ' ', "after upgrading. On Vercel this runs automatically at build time."] }) })), info.breakingChanges && info.breakingChanges.length > 0 && (_jsx(Notice, { tone: "destructive", icon: _jsx(AlertTriangle, { size: 16 }), title: "Breaking changes in this release", children: _jsx("ul", { className: "list-disc space-y-1 pl-4", children: info.breakingChanges.map((c, i) => (_jsx("li", { children: c }, i))) }) })), _jsxs("div", { className: "mt-4 flex flex-wrap items-center gap-3", children: [canManage ? (_jsx("button", { type: "button", onClick: apply, disabled: applying, className: "bg-brand text-brand-foreground inline-flex items-center gap-2 rounded-md px-4 py-2 text-sm font-medium transition-opacity hover:opacity-90 disabled:opacity-50", children: applying ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { size: 16, className: "animate-spin", "aria-hidden": "true" }), "Creating PR\u2026"] })) : (_jsxs(_Fragment, { children: [_jsx(GitPullRequest, { size: 16, "aria-hidden": "true" }), "Create Update PR"] })) })) : (_jsxs("span", { className: "text-muted-foreground inline-flex items-center gap-1.5 text-xs", children: [_jsx(Lock, { size: 14, "aria-hidden": "true" }), "Ask an administrator to apply this update."] })), canManage && (_jsx("span", { className: "text-muted-foreground text-xs", children: "Opens a pull request on your repository" }))] }), info.updateCommand && (_jsxs("div", { className: "border-border bg-card mt-3 rounded-md border p-3", children: [_jsx("p", { className: "text-muted-foreground mb-1 text-xs", children: "Or update manually:" }), _jsx("code", { className: "bg-muted text-foreground block rounded px-2 py-1.5 font-mono text-xs select-all", children: info.updateCommand })] }))] })), info?.updateAvailable && changelogGroups.length > 0 && (_jsx(SettingsCard, { title: "Changelog", description: info.source === 'npm'
                    ? 'Version history from npm. Connect the update server for full release notes.'
                    : "What's new since your current version.", children: _jsx("div", { className: "max-h-80 space-y-4 overflow-y-auto pr-1", children: changelogGroups.map((group) => (_jsxs("div", { className: "border-border border-b pb-3 last:border-0 last:pb-0", children: [_jsxs("div", { className: "mb-1.5 flex items-baseline gap-3", children: [_jsx("span", { className: "text-foreground font-mono text-sm font-medium", children: group.version }), group.date && (_jsx("span", { className: "text-muted-foreground text-xs", children: group.date }))] }), _jsx("ul", { className: "space-y-1.5", children: group.items.map((item, i) => (_jsxs("li", { className: "flex items-start gap-2 text-sm", children: [_jsx(ChangeTypeBadge, { type: item.type }), _jsx("span", { className: "text-muted-foreground min-w-0", children: item.summary })] }, i))) })] }, group.version))) }) })), info?.updateAvailable && info.pluginCompatibility && info.pluginCompatibility.length > 0 && (_jsx(SettingsCard, { title: "Plugin compatibility", description: "Latest published versions of the official plugins for this release.", children: _jsx("ul", { className: "grid gap-2 sm:grid-cols-2", children: info.pluginCompatibility.map((plugin) => (_jsxs("li", { className: "border-border flex items-center justify-between gap-3 rounded-md border px-3 py-2 text-sm", children: [_jsxs("span", { className: "text-foreground inline-flex min-w-0 items-center gap-2", children: [_jsx(Puzzle, { size: 14, className: "text-muted-foreground shrink-0", "aria-hidden": "true" }), _jsx("span", { className: "truncate font-mono text-xs", children: plugin.name.replace('@actuate-media/', '') })] }), _jsxs("span", { className: "text-muted-foreground inline-flex shrink-0 items-center gap-1.5", children: [plugin.minVersion && (_jsx("span", { className: "font-mono text-xs", children: plugin.minVersion })), _jsx(CheckCircle2, { size: 14, className: "text-success", "aria-hidden": "true" })] })] }, plugin.name))) }) })), prResult && (_jsx("div", { className: "border-success/30 bg-success/10 rounded-lg border p-4", children: _jsxs("div", { className: "flex items-start gap-3", children: [_jsx(GitPullRequest, { size: 20, className: "text-success mt-0.5 shrink-0", "aria-hidden": "true" }), _jsxs("div", { children: [_jsx("h3", { className: "text-foreground font-medium", children: "Pull Request Created" }), _jsxs("p", { className: "text-muted-foreground mt-1 text-sm", children: ["PR #", prResult.prNumber, " has been created on your repository. Review and merge it to apply the update, then run", ' ', _jsx("code", { className: "bg-muted rounded px-1 font-mono text-xs", children: "npx prisma migrate deploy" }), "."] }), _jsxs("a", { href: prResult.prUrl, target: "_blank", rel: "noopener noreferrer", className: "text-brand mt-2 inline-flex items-center gap-1.5 text-sm font-medium hover:underline", children: [_jsx(ExternalLink, { size: 16, "aria-hidden": "true" }), "View Pull Request"] })] })] }) })), canManage && (_jsxs(SettingsCard, { title: "GitHub Integration", description: "Connect your repository to enable one-click update PRs. Credentials are encrypted at rest (AES-256-GCM).", children: [_jsxs("div", { className: "space-y-4", children: [_jsx(SettingsControlRow, { label: "Repository", htmlFor: "updates-gh-repo", align: "start", description: _jsxs(_Fragment, { children: ["e.g.", ' ', _jsx("code", { className: "bg-muted rounded px-1 font-mono", children: "actuate-media/my-client-site" })] }), control: _jsxs("div", { className: "w-72 max-w-full", children: [_jsx("input", { id: "updates-gh-repo", type: "text", value: form.githubRepo, onChange: (e) => setField('githubRepo', e.target.value), placeholder: "owner/repo", "aria-invalid": Boolean(repoError), "aria-describedby": repoError ? 'updates-gh-repo-error' : undefined, className: ghInputClass }), repoError && (_jsx("p", { id: "updates-gh-repo-error", className: "text-destructive mt-1 text-xs", children: repoError }))] }) }), _jsx(SettingsControlRow, { label: _jsxs("span", { className: "inline-flex items-center gap-2", children: ["GitHub token", info?.hasGithubToken && !form.githubToken && (_jsx("span", { className: "text-success text-xs font-normal", children: "Saved" }))] }), htmlFor: "updates-gh-token", align: "start", description: _jsxs(_Fragment, { children: ["Needs ", _jsx("code", { className: "bg-muted rounded px-1 font-mono", children: "repo" }), " scope. Create one at", ' ', _jsx("a", { href: "https://github.com/settings/tokens", target: "_blank", rel: "noopener noreferrer", className: "text-brand hover:underline", children: "github.com/settings/tokens" }), "."] }), control: _jsxs("div", { className: "relative w-72 max-w-full", children: [_jsx("input", { id: "updates-gh-token", type: showToken ? 'text' : 'password', value: form.githubToken, onChange: (e) => setField('githubToken', e.target.value), placeholder: info?.hasGithubToken ? '••••••••••••••••' : 'ghp_… or github_pat_…', className: `${ghInputClass} pr-10` }), _jsx("button", { type: "button", onClick: () => setShowToken((s) => !s), "aria-label": showToken ? 'Hide token' : 'Show token', className: "text-muted-foreground hover:text-foreground absolute top-1/2 right-2 -translate-y-1/2 p-1", children: showToken ? (_jsx(EyeOff, { size: 16, "aria-hidden": "true" })) : (_jsx(Eye, { size: 16, "aria-hidden": "true" })) })] }) })] }), _jsx(SettingsSaveBar, { dirty: dirty, canEdit: canManage, hasErrors: hasErrors, saveState: saveState, onSave: save, onReset: reset })] })), _jsx(SettingsCard, { title: "How Updates Work", children: _jsx("ol", { className: "text-muted-foreground space-y-1.5 text-sm", children: [
                        'Click “Check for Updates” to see if a new version is available.',
                        'Add your GitHub token and repository above (admins only). They’re encrypted at rest — never stored in plaintext.',
                        'Click “Create Update PR” to open a pull request that bumps your CMS packages automatically.',
                        'Review and merge the PR, then deploy. Database migrations run automatically via prisma migrate deploy.',
                    ].map((step, i) => (_jsxs("li", { className: "flex items-start gap-2", children: [_jsx("span", { className: "bg-brand/10 text-brand mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded-full text-[10px] font-medium", children: i + 1 }), _jsx("span", { children: step })] }, i))) }) })] }));
}
//# sourceMappingURL=UpdatesTab.js.map