import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useCallback, useEffect, useMemo, useState, } from "react";
import { AlertCircle, Bug, Check, Copy, Filter, Search, } from "lucide-react";
import { DeleteIcon } from "../../../components/ui/delete-icon";
import { toast } from "sonner";
import { Badge } from "../../../components/ui/badge";
import { Button } from "../../../components/ui/button";
import { SettingsCard as Card } from "../SettingsCard";
import { SettingsPanelLayout } from "../SettingsPanelLayout";
import { Input } from "../../../components/ui/input";
import { SearchInput } from "../../../components/SearchInput";
import { Select } from "../../../components/ui/select";
import { formatPersistentLogsForCopy } from "../../../task-board/persistentLogCopy";
import { useEditContext } from "../../client/editContext";
import { LoadingState } from "../../ui/LoadingState";
import { getPersistentLogsAdmin, purgePersistentLogs, } from "../../../task-board/services/taskService";
import { formatPersistentLogEventType, formatPersistentLogStage, formatPersistentLogStatus, persistentLogContextPartTooltip, persistentLogCreatedAtTooltip, persistentLogDurationTooltip, persistentLogEventTypeTooltip, persistentLogSeqTooltip, persistentLogSourceTooltip, persistentLogStageTooltip, persistentLogStatusTooltip, persistentLogToolCallTooltip, PERSISTENT_LOG_FIELD_HINT, } from "../../../task-board/persistentLogLabels";
const DEFAULT_LIMIT = "200";
const SUCCESS_OPTIONS = [
    { value: "", label: "All results" },
    { value: "true", label: "Successful only" },
    { value: "false", label: "Failed only" },
];
function createDefaultDraft() {
    return {
        agentId: "",
        projectId: "",
        taskId: "",
        runId: "",
        eventType: "",
        stage: "",
        status: "",
        source: "",
        searchTerm: "",
        success: "",
        limit: DEFAULT_LIMIT,
    };
}
function trimOrNull(value) {
    const trimmed = value.trim();
    return trimmed.length > 0 ? trimmed : null;
}
function toFilters(draft) {
    const parsedLimit = Number.parseInt(draft.limit, 10);
    return {
        agentId: trimOrNull(draft.agentId),
        projectId: trimOrNull(draft.projectId),
        taskId: trimOrNull(draft.taskId),
        runId: trimOrNull(draft.runId),
        eventType: trimOrNull(draft.eventType),
        stage: trimOrNull(draft.stage),
        status: trimOrNull(draft.status),
        source: trimOrNull(draft.source),
        searchTerm: trimOrNull(draft.searchTerm),
        success: draft.success === "true"
            ? true
            : draft.success === "false"
                ? false
                : null,
        limit: Number.isFinite(parsedLimit) && parsedLimit > 0 ? parsedLimit : 200,
    };
}
function formatDuration(durationMs) {
    if (typeof durationMs !== "number" ||
        !Number.isFinite(durationMs) ||
        durationMs < 0) {
        return null;
    }
    if (durationMs < 1000)
        return `${durationMs}ms`;
    return `${(durationMs / 1000).toFixed(durationMs >= 10000 ? 0 : 1)}s`;
}
function shortenGuid(value) {
    if (!value)
        return null;
    return value.length > 8 ? value.slice(0, 8) : value;
}
function trimPreview(value, maxLength = 800) {
    if (!value)
        return null;
    const trimmed = value.trim();
    if (!trimmed)
        return null;
    return trimmed.length > maxLength
        ? `${trimmed.slice(0, maxLength)}...`
        : trimmed;
}
function buildContextLine(entry) {
    const parts = [];
    if (entry.agentId)
        parts.push(`Agent ${shortenGuid(entry.agentId)}`);
    if (entry.projectId)
        parts.push(`Project ${shortenGuid(entry.projectId)}`);
    if (entry.taskId)
        parts.push(`Task ${shortenGuid(entry.taskId)}`);
    if (entry.runId)
        parts.push(`Run ${shortenGuid(entry.runId)}`);
    if (entry.userId)
        parts.push(entry.userId);
    return parts;
}
function renderPreviewBlock(label, value) {
    const preview = trimPreview(value);
    if (!preview)
        return null;
    return (_jsxs("div", { className: "grid gap-1", children: [_jsx("div", { className: "text-neutral-grey-50 text-[10px] font-medium tracking-wider", children: label }), _jsx("pre", { className: "border-border-default bg-neutral-grey-5 text-neutral-grey-100 overflow-x-auto rounded border p-2 text-[11px] leading-tight whitespace-pre-wrap", children: preview })] }));
}
function LogRow({ entry }) {
    const createdAt = useMemo(() => new Date(entry.createdAt), [entry.createdAt]);
    const hasValidCreatedAt = !Number.isNaN(createdAt.getTime());
    const contextParts = buildContextLine(entry);
    const duration = formatDuration(entry.durationMs);
    const tone = entry.success === false || entry.status?.toLowerCase() === "failed"
        ? "destructive"
        : entry.success === true
            ? "default"
            : "secondary";
    const contextLine = contextParts.length > 0 ? contextParts.join(" · ") : "None";
    const contextTitle = contextParts
        .map((part) => `${persistentLogContextPartTooltip(part)}`)
        .join("\n\n");
    const hasPayloadBlocks = Boolean(trimPreview(entry.payloadPreview) ||
        trimPreview(entry.resultPreview) ||
        trimPreview(entry.metadataJson));
    const hasExpandableDetails = hasPayloadBlocks ||
        Boolean(entry.error) ||
        typeof entry.seq === "number" ||
        Boolean(duration) ||
        Boolean(entry.toolCallId?.trim());
    const summaryText = entry.summary?.trim() || "No summary";
    return (_jsxs("tr", { className: "border-border-default text-neutral-grey-100 border-t align-middle text-[11px] leading-snug", children: [_jsx("td", { className: "text-neutral-grey-50 max-w-[200px] px-3 py-1.5 whitespace-nowrap", children: _jsx("div", { className: "cursor-help truncate font-mono", title: persistentLogCreatedAtTooltip({
                        hasValidDate: hasValidCreatedAt,
                        localDisplay: hasValidCreatedAt
                            ? createdAt.toLocaleString()
                            : entry.createdAt,
                        isoUtc: hasValidCreatedAt ? createdAt.toISOString() : undefined,
                        raw: entry.createdAt,
                    }), children: hasValidCreatedAt ? createdAt.toLocaleString() : entry.createdAt }) }), _jsx("td", { className: "max-w-[120px] px-3 py-1.5", children: _jsx(Badge, { variant: "outline", className: "text-2xs max-w-full cursor-help leading-none font-normal", title: persistentLogEventTypeTooltip(entry.eventType), children: _jsx("span", { className: "truncate", children: formatPersistentLogEventType(entry.eventType) }) }) }), _jsx("td", { className: "max-w-[140px] px-3 py-1.5", children: _jsx(Badge, { variant: "outline", className: "text-2xs max-w-full cursor-help leading-none font-normal", title: persistentLogStageTooltip(entry.stage), children: _jsx("span", { className: "truncate", children: formatPersistentLogStage(entry.stage) }) }) }), _jsx("td", { className: "max-w-[200px] min-w-0 px-3 py-1.5", children: _jsxs("div", { className: "flex max-w-full min-w-0 items-center gap-1.5", children: [entry.status ? (_jsx(Badge, { variant: tone, className: "text-2xs max-w-28 shrink-0 cursor-help leading-none font-normal", title: persistentLogStatusTooltip(entry.status), children: _jsx("span", { className: "truncate", children: formatPersistentLogStatus(entry.status) }) })) : (_jsx("span", { className: "text-neutral-grey-50 shrink-0", children: "\u2014" })), entry.source ? (_jsx("span", { className: "text-neutral-grey-50 min-w-0 cursor-help truncate", title: persistentLogSourceTooltip(entry.source), children: entry.source })) : null] }) }), _jsx("td", { className: "max-w-xl min-w-[200px] px-3 py-1.5", children: !hasExpandableDetails ? (_jsx("div", { className: "text-neutral-grey-100 truncate", title: summaryText, children: summaryText })) : (_jsxs("details", { className: "group min-w-0", children: [_jsxs("summary", { className: "flex cursor-pointer list-none items-center gap-2 [&::-webkit-details-marker]:hidden", children: [_jsxs("span", { className: "text-neutral-grey-100 min-w-0 flex-1 truncate text-left", title: entry.error ? `${summaryText}\n\n${entry.error}` : summaryText, children: [entry.error ? (_jsxs("span", { className: "text-feedback-red", "aria-hidden": true, children: ["\u26A0", " "] })) : null, summaryText] }), _jsx("span", { className: "text-neutral-grey-50 shrink-0 underline-offset-2 group-open:font-medium group-hover:underline", children: "Details" })] }), _jsxs("div", { className: "border-border-default mt-2 grid gap-2 border-t pt-2 text-[11px] leading-snug", children: [typeof entry.seq === "number" || duration || entry.toolCallId ? (_jsxs("div", { className: "text-neutral-grey-50 flex flex-wrap gap-x-3 gap-y-1", children: [typeof entry.seq === "number" ? (_jsxs("span", { className: "cursor-help", title: persistentLogSeqTooltip(entry.seq), children: ["Seq ", entry.seq] })) : null, duration ? (_jsx("span", { className: "cursor-help", title: persistentLogDurationTooltip(duration), children: duration })) : null, entry.toolCallId ? (_jsxs("span", { className: "cursor-help", title: persistentLogToolCallTooltip(entry.toolCallId), children: ["Tool ", entry.toolCallId] })) : null] })) : null, entry.error ? (_jsx("div", { className: "badge-pad border-feedback-red bg-feedback-red-light text-feedback-red rounded border", children: entry.error })) : null, hasPayloadBlocks ? (_jsxs("div", { className: "grid gap-2", children: [renderPreviewBlock("Payload", entry.payloadPreview), renderPreviewBlock("Result", entry.resultPreview), renderPreviewBlock("Metadata", entry.metadataJson)] })) : null] })] })) }), _jsx("td", { className: "text-neutral-grey-50 max-w-[220px] min-w-0 px-3 py-1.5", children: _jsx("div", { className: "cursor-help truncate", title: contextTitle, children: contextLine }) })] }));
}
export function PersistentLogsPanel() {
    const editContext = useEditContext();
    const [draft, setDraft] = useState(createDefaultDraft);
    const [filters, setFilters] = useState({
        limit: 200,
    });
    const [logs, setLogs] = useState([]);
    const [loggingEnabled, setLoggingEnabled] = useState(true);
    const [isLoading, setIsLoading] = useState(false);
    const [isPurging, setIsPurging] = useState(false);
    const [error, setError] = useState(null);
    const [hasCopied, setHasCopied] = useState(false);
    const copyText = useMemo(() => formatPersistentLogsForCopy(logs, {
        title: "Agent and taskboard logs",
    }), [logs]);
    const loadLogs = useCallback(async () => {
        setIsLoading(true);
        setError(null);
        const result = await getPersistentLogsAdmin(filters);
        if (result.type === "success") {
            setLogs(result.data?.logs || []);
            setLoggingEnabled(result.data?.loggingEnabled !== false);
            setError(null);
        }
        else if (result.type === "unauthorized") {
            setLogs([]);
            setError("Administrator access is required to view agent and taskboard logs.");
        }
        else {
            setLogs([]);
            setError(result.summary || "Failed to load agent and taskboard logs.");
        }
        setIsLoading(false);
    }, [filters]);
    useEffect(() => {
        void loadLogs();
    }, [loadLogs]);
    useEffect(() => {
        if (!hasCopied)
            return;
        const timeoutId = window.setTimeout(() => setHasCopied(false), 1500);
        return () => window.clearTimeout(timeoutId);
    }, [hasCopied]);
    const handleDraftChange = useCallback((key, value) => {
        setDraft((current) => ({ ...current, [key]: value }));
    }, []);
    const handleApplyFilters = useCallback((event) => {
        event?.preventDefault();
        setFilters(toFilters(draft));
    }, [draft]);
    const handleResetFilters = useCallback(() => {
        const nextDraft = createDefaultDraft();
        setDraft(nextDraft);
        setFilters(toFilters(nextDraft));
    }, []);
    const handlePurge = useCallback(async () => {
        const runPurge = async () => {
            setIsPurging(true);
            const result = await purgePersistentLogs();
            setIsPurging(false);
            if (result.type === "success") {
                toast.success("Agent and taskboard log table truncated.");
                await loadLogs();
                return;
            }
            toast.error(result.summary || "Failed to purge persistent logs.");
        };
        if (editContext?.confirm) {
            editContext.confirm({
                header: "Purge agent and taskboard logs",
                message: "This will truncate the stored agent and taskboard log table.\n\nThis action cannot be undone.",
                acceptLabel: "Purge",
                showCancel: true,
                accept: () => {
                    void runPurge();
                },
            });
            return;
        }
        if (typeof window !== "undefined" &&
            window.confirm("This will truncate the stored agent and taskboard log table. Continue?")) {
            await runPurge();
        }
    }, [editContext, loadLogs]);
    const handleCopy = useCallback(async () => {
        if (!copyText)
            return;
        try {
            await navigator.clipboard.writeText(copyText);
            setHasCopied(true);
        }
        catch (error) {
            console.error("Failed to copy persistent logs:", error);
            toast.error("Failed to copy agent and taskboard logs.");
        }
    }, [copyText]);
    return (_jsxs(SettingsPanelLayout, { contentClassName: "grid gap-4", children: [_jsx(Card, { icon: _jsx(Filter, { strokeWidth: 1, className: "h-5 w-5" }), title: "Filters", description: "Narrow the stored agent and taskboard log entries by id, type, or result.", children: _jsxs("form", { className: "grid gap-4", onSubmit: handleApplyFilters, children: [!loggingEnabled ? (_jsxs("div", { className: "border-feedback-orange bg-feedback-orange-light text-feedback-orange rounded border px-3 py-2 text-sm", children: ["Logging is currently disabled. Enable", " ", _jsx("strong", { children: "Enable Agent and Taskboard Logging" }), " on the Parhelia settings item to capture new entries."] })) : null, _jsxs("div", { className: "grid gap-3 md:grid-cols-2 xl:grid-cols-4", children: [_jsx(SearchInput, { value: draft.searchTerm, onChange: (value) => handleDraftChange("searchTerm", value), placeholder: "Search summary, payload, metadata" }), _jsx(Input, { value: draft.agentId, onChange: (event) => handleDraftChange("agentId", event.target.value), placeholder: "Agent ID" }), _jsx(Input, { value: draft.projectId, onChange: (event) => handleDraftChange("projectId", event.target.value), placeholder: "Project ID" }), _jsx(Input, { value: draft.taskId, onChange: (event) => handleDraftChange("taskId", event.target.value), placeholder: "Task ID" }), _jsx(Input, { value: draft.runId, onChange: (event) => handleDraftChange("runId", event.target.value), placeholder: "Run ID" }), _jsx(Input, { value: draft.eventType, onChange: (event) => handleDraftChange("eventType", event.target.value), placeholder: "Event type" }), _jsx(Input, { value: draft.stage, onChange: (event) => handleDraftChange("stage", event.target.value), placeholder: "Stage" }), _jsx(Input, { value: draft.status, onChange: (event) => handleDraftChange("status", event.target.value), placeholder: "Status" }), _jsx(Input, { value: draft.source, onChange: (event) => handleDraftChange("source", event.target.value), placeholder: "Source" }), _jsx(Select, { value: draft.success, onValueChange: (value) => handleDraftChange("success", value), options: SUCCESS_OPTIONS, placeholder: "All results" }), _jsx(Input, { value: draft.limit, onChange: (event) => handleDraftChange("limit", event.target.value), placeholder: "Limit", inputMode: "numeric" })] }), _jsxs("div", { className: "flex flex-wrap gap-2", children: [_jsxs(Button, { type: "submit", size: "sm", children: [_jsx(Search, { className: "h-4 w-4" }), "Apply Filters"] }), _jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: handleResetFilters, children: "Reset" }), _jsxs(Button, { type: "button", variant: "outline", size: "sm", onClick: () => void handleCopy(), disabled: !copyText, children: [hasCopied ? (_jsx(Check, { className: "h-4 w-4" })) : (_jsx(Copy, { className: "h-4 w-4" })), hasCopied ? "Copied Results" : "Copy Results"] }), _jsxs(Button, { type: "button", variant: "outline", size: "sm", className: "text-neutral-grey-50 hover:bg-neutral-grey-5 hover:text-neutral-grey-100", onClick: () => void handlePurge(), disabled: isPurging, children: [_jsx(DeleteIcon, { size: "lg" }), isPurging ? "Purging..." : "Purge Log Table"] })] })] }) }), _jsxs(Card, { icon: _jsx(Bug, { strokeWidth: 1, className: "h-5 w-5" }), title: "Entries", description: "Latest stored agent and taskboard log rows after applying the current filters.", children: [error ? (_jsx("div", { className: "border-feedback-red bg-feedback-red-light text-feedback-red rounded border p-3 text-sm", children: error })) : isLoading && logs.length === 0 ? (_jsx(LoadingState, { message: "Loading agent and taskboard logs...", className: "py-10", spinnerClassName: "text-neutral-grey-50", spinnerSize: "sm", textClassName: "text-neutral-grey-50" })) : logs.length === 0 ? (_jsx("div", { className: "border-border-default text-neutral-grey-50 rounded border border-dashed px-4 py-10 text-center text-sm", children: "No log entries matched the current filters." })) : (_jsxs("div", { className: "grid gap-2", children: [_jsx("p", { className: "text-2xs text-neutral-grey-50 leading-snug", children: PERSISTENT_LOG_FIELD_HINT }), _jsx("div", { className: "border-border-default overflow-x-auto rounded border", children: _jsxs("table", { className: "min-w-full border-collapse", children: [_jsx("thead", { className: "bg-neutral-grey-5", children: _jsxs("tr", { className: "text-neutral-grey-50 text-left text-[11px] font-medium tracking-wider", children: [_jsx("th", { className: "px-3 py-2", children: "Time" }), _jsx("th", { className: "px-3 py-2", children: "Type" }), _jsx("th", { className: "px-3 py-2", children: "Step" }), _jsx("th", { className: "px-3 py-2", children: "State" }), _jsx("th", { className: "px-3 py-2", children: "Summary" }), _jsx("th", { className: "px-3 py-2", children: "Context" })] }) }), _jsx("tbody", { children: logs.map((entry) => (_jsx(LogRow, { entry: entry }, entry.logId))) })] }) })] })), !loggingEnabled ? (_jsxs("div", { className: "text-neutral-grey-50 mt-3 flex items-center gap-2 text-xs", children: [_jsx(AlertCircle, { className: "h-4 w-4" }), "New entries will not be written until logging is enabled again."] })) : null] })] }));
}
export default PersistentLogsPanel;
//# sourceMappingURL=PersistentLogsPanel.js.map