import { Fragment, jsx, jsxs } from "react/jsx-runtime";
import { useLingui } from "@lingui/react";
import CheckCircle from "@mui/icons-material/CheckCircle";
import Error from "@mui/icons-material/Error";
import KeyboardArrowDown from "@mui/icons-material/KeyboardArrowDown";
import KeyboardArrowRight from "@mui/icons-material/KeyboardArrowRight";
import { CircularProgress, styled } from "@mui/material";
import apollo_core from "@uipath/apollo-core";
import react, { useCallback, useEffect, useMemo, useState } from "react";
import { ConversationalDisplayModeTypes } from "./ApToolCall.types.js";
import { ToolCallSection } from "./components/ToolCallSection.js";
import { getSpanIconSvg } from "./utils/traceIconUtils.js";
const Container = styled('div')({
    fontSize: apollo_core.FontFamily.FontMSize,
    padding: apollo_core.Spacing.SpacingS,
    color: 'var(--color-foreground-de-emp)',
    maxWidth: '100%',
    boxSizing: 'border-box'
});
const Header = styled('div')({
    display: 'flex',
    alignItems: 'center',
    padding: apollo_core.Spacing.SpacingMicro,
    borderRadius: apollo_core.Spacing.SpacingMicro,
    marginBottom: apollo_core.Spacing.SpacingXs,
    cursor: 'pointer',
    '&:hover': {
        backgroundColor: 'var(--color-background-hover)'
    },
    '&:focus-visible': {
        outline: `${apollo_core.Border.BorderThickS} solid var(--color-focus-indicator)`,
        outlineOffset: '-1px'
    }
});
const LoadingSpinner = styled(CircularProgress)({
    width: `${apollo_core.Spacing.SpacingM} !important`,
    height: `${apollo_core.Spacing.SpacingM} !important`,
    marginRight: apollo_core.Spacing.SpacingXs
});
const ErrorIconStyled = styled(Error)({
    width: apollo_core.Spacing.SpacingM,
    marginRight: apollo_core.Spacing.SpacingXs,
    color: 'var(--color-error-icon)',
    fill: 'var(--color-error-icon)'
});
const SuccessIconStyled = styled(CheckCircle)({
    width: apollo_core.Spacing.SpacingM,
    marginRight: apollo_core.Spacing.SpacingXs,
    color: 'var(--color-success-icon)',
    fill: 'var(--color-success-icon)'
});
const ArrowIcon = styled(KeyboardArrowDown, {
    shouldForwardProp: (prop)=>'expanded' !== prop
})(({ expanded })=>({
        marginLeft: apollo_core.Spacing.SpacingXs,
        transform: expanded ? 'rotate(180deg)' : 'none'
    }));
const TraceArrowIcon = styled(KeyboardArrowRight, {
    shouldForwardProp: (prop)=>'expanded' !== prop
})(({ expanded })=>({
        transition: 'transform 0.2s ease',
        transform: expanded ? 'rotate(90deg)' : 'none',
        flexShrink: 0
    }));
const SectionsContainer = styled('div', {
    shouldForwardProp: (prop)=>'expanded' !== prop
})(({ expanded })=>({
        marginLeft: apollo_core.Spacing.SpacingS,
        paddingLeft: apollo_core.Spacing.SpacingS,
        borderLeft: `${apollo_core.Border.BorderThickS} solid var(--color-border)`,
        maxHeight: expanded ? 'fit-content' : '0',
        overflow: 'hidden',
        transition: 'max-height 0.2s ease',
        maxWidth: `calc(100% - ${apollo_core.Spacing.SpacingBase})`,
        boxSizing: 'border-box',
        '&:focus-visible': {
            outline: `${apollo_core.Border.BorderThickS} solid var(--color-focus-indicator)`,
            outlineOffset: '-1px'
        }
    }));
const TraceItemsContainer = styled('div')({
    marginTop: apollo_core.Spacing.SpacingMicro,
    paddingLeft: apollo_core.Spacing.SpacingMicro
});
const TraceItemContainer = styled('div', {
    shouldForwardProp: (prop)=>'clickable' !== prop
})(({ clickable })=>({
        display: 'flex',
        alignItems: 'center',
        gap: apollo_core.Spacing.SpacingXs,
        marginBottom: apollo_core.Spacing.SpacingS,
        ...clickable && {
            cursor: 'pointer',
            borderRadius: apollo_core.Spacing.SpacingMicro,
            '&:hover': {
                backgroundColor: 'var(--color-background-hover)'
            }
        }
    }));
const TraceName = styled('span')({
    display: 'inline-block',
    flex: 1
});
const ArrowPlaceholder = styled('span')({
    width: '20px',
    flexShrink: 0,
    display: 'inline-block'
});
const TraceIcon = styled('span')({
    display: 'inline-flex',
    alignItems: 'center',
    flexShrink: 0,
    width: '16px',
    height: '16px',
    '& svg': {
        width: '100%',
        height: '100%'
    }
});
function getVisibleChildren(node) {
    const result = [];
    for (const child of node.children ?? [])if ('llmCall' !== child.data.type && 'agentOutput' !== child.data.type) result.push(child);
    return result;
}
const TraceItem = ({ child, depth = 0 })=>{
    const visibleChildren = useMemo(()=>getVisibleChildren(child), [
        child
    ]);
    const hasChildren = visibleChildren.length > 0;
    const [itemExpanded, setItemExpanded] = useState(false);
    const iconSvg = useMemo(()=>getSpanIconSvg(child.data), [
        child.data
    ]);
    const handleKeyDown = (event)=>{
        if ('Enter' === event.key || ' ' === event.key) {
            event.preventDefault();
            setItemExpanded((prev)=>!prev);
        }
    };
    return /*#__PURE__*/ jsxs(Fragment, {
        children: [
            /*#__PURE__*/ jsxs(TraceItemContainer, {
                clickable: hasChildren,
                style: {
                    paddingLeft: depth > 0 ? `calc(${depth} * ${apollo_core.Spacing.SpacingM})` : void 0
                },
                onClick: hasChildren ? ()=>setItemExpanded((prev)=>!prev) : void 0,
                role: hasChildren ? 'button' : void 0,
                tabIndex: hasChildren ? 0 : void 0,
                onKeyDown: hasChildren ? handleKeyDown : void 0,
                "aria-expanded": hasChildren ? itemExpanded : void 0,
                children: [
                    hasChildren ? /*#__PURE__*/ jsx(TraceArrowIcon, {
                        fontSize: "small",
                        expanded: itemExpanded
                    }) : /*#__PURE__*/ jsx(ArrowPlaceholder, {}),
                    iconSvg && /*#__PURE__*/ jsx(TraceIcon, {
                        dangerouslySetInnerHTML: {
                            __html: iconSvg
                        }
                    }),
                    /*#__PURE__*/ jsx(TraceName, {
                        children: child.name.replace('_', ' ')
                    })
                ]
            }),
            hasChildren && itemExpanded && visibleChildren.map((c)=>/*#__PURE__*/ jsx(TraceItemContent, {
                    child: c,
                    depth: depth + 1
                }, c.key))
        ]
    });
};
const TraceItemContent = /*#__PURE__*/ react.memo(TraceItem);
const ApToolCall = /*#__PURE__*/ react.forwardRef((props, ref)=>{
    const { span, toolName, input, output, isError, startTime, endTime, displayMode } = props;
    const { _ } = useLingui();
    const [toolCallExpanded, setToolCallExpanded] = useState(false);
    const [expandedSections, setExpandedSections] = useState({
        input: false,
        traces: false,
        escalation: true,
        output: false,
        errors: false
    });
    const getAttributes = useCallback((data)=>{
        let attrs = data.attributes;
        if ('string' == typeof attrs) try {
            attrs = JSON.parse(attrs);
        } catch  {
            return {};
        }
        return attrs || {};
    }, []);
    const taskUrls = useMemo(()=>{
        if (!span) return [];
        const urls = [];
        let attributes = span.data.attributes;
        if ('string' == typeof attributes) try {
            attributes = JSON.parse(attributes);
        } catch  {
            attributes = {};
        }
        if ('object' == typeof attributes && attributes?.taskUrl) urls.push({
            taskUrl: attributes.taskUrl,
            status: span.data.status || null
        });
        const visitedSpans = new Set();
        const childStack = [
            ...span.children || []
        ];
        while(childStack.length > 0){
            const child = childStack.pop();
            if (!child?.data?.id) continue;
            if (visitedSpans.has(child.data.id)) continue;
            visitedSpans.add(child.data.id);
            let childAttributes = child.data.attributes;
            if ('string' == typeof childAttributes) try {
                childAttributes = JSON.parse(childAttributes);
            } catch  {
                childAttributes = {};
            }
            if ('object' == typeof childAttributes && childAttributes?.taskUrl) urls.push({
                taskUrl: childAttributes.taskUrl,
                status: child.data.status || null
            });
            if (child.children?.length) childStack.push(...child.children);
        }
        return urls;
    }, [
        span
    ]);
    useEffect(()=>{
        if (taskUrls.length > 0) setToolCallExpanded(true);
    }, [
        taskUrls
    ]);
    const hasChildSpanWithError = useMemo(()=>{
        if (!span) return false;
        const visitedSpans = new Set();
        const childStack = [
            ...span.children || []
        ];
        while(childStack.length > 0){
            const child = childStack.pop();
            if (!child?.data?.id) continue;
            if (visitedSpans.has(child.data.id)) continue;
            visitedSpans.add(child.data.id);
            if ('error' === child.data.status) return true;
            if (child.children?.length) childStack.push(...child.children);
        }
        return false;
    }, [
        span
    ]);
    const getStatus = useMemo(()=>{
        if (input && !output && void 0 === isError) return 'loading';
        if (input && (output || void 0 !== isError)) return isError ? 'error' : 'success';
        if (span) {
            if ('unset' === span.data.status) return 'loading';
            if ('error' === span.data.status || hasChildSpanWithError) return 'error';
            if ('ok' === span.data.status) return 'success';
        }
        return null;
    }, [
        input,
        output,
        isError,
        span,
        hasChildSpanWithError
    ]);
    const renderStatusIcon = useMemo(()=>{
        switch(getStatus){
            case 'loading':
                return /*#__PURE__*/ jsx(LoadingSpinner, {});
            case 'error':
                return /*#__PURE__*/ jsx(ErrorIconStyled, {});
            case 'success':
                return /*#__PURE__*/ jsx(SuccessIconStyled, {});
            default:
                return null;
        }
    }, [
        getStatus
    ]);
    const getStatusText = useMemo(()=>{
        const status = getStatus;
        const toolCallName = toolName?.replace(/_/g, ' ') || span?.name?.replace('Tool call - ', '').replace(/_/g, ' ') || 'tool';
        if ('loading' === status) return `Running '${toolCallName}'`;
        const endTimeStamp = endTime || span?.data?.endTime;
        const startTimeStamp = startTime || span?.data?.startTime;
        const duration = endTimeStamp && startTimeStamp ? (new Date(endTimeStamp).getTime() - new Date(startTimeStamp).getTime()) / 1000 : 0;
        return `Ran '${toolCallName}' for ${duration.toFixed(2)} seconds`;
    }, [
        getStatus,
        toolName,
        span,
        startTime,
        endTime
    ]);
    const handleKeyDown = useCallback((event)=>{
        if ('Enter' === event.key || ' ' === event.key) {
            event.preventDefault();
            setToolCallExpanded(!toolCallExpanded);
        }
    }, [
        toolCallExpanded
    ]);
    if (displayMode === ConversationalDisplayModeTypes.ToolNameOnly) return /*#__PURE__*/ jsx(Container, {
        ref: ref,
        children: /*#__PURE__*/ jsxs(Header, {
            children: [
                renderStatusIcon,
                " ",
                getStatusText
            ]
        })
    });
    return /*#__PURE__*/ jsxs(Container, {
        ref: ref,
        children: [
            /*#__PURE__*/ jsxs(Header, {
                onClick: ()=>setToolCallExpanded(!toolCallExpanded),
                onKeyDown: handleKeyDown,
                role: "button",
                tabIndex: 0,
                "aria-expanded": toolCallExpanded,
                children: [
                    renderStatusIcon,
                    " ",
                    getStatusText,
                    /*#__PURE__*/ jsx(ArrowIcon, {
                        fontSize: "small",
                        expanded: toolCallExpanded
                    })
                ]
            }),
            /*#__PURE__*/ jsxs(SectionsContainer, {
                expanded: toolCallExpanded,
                "aria-hidden": !toolCallExpanded,
                ...!toolCallExpanded && {
                    inert: true
                },
                children: [
                    (input || span && getAttributes(span.data).arguments) && /*#__PURE__*/ jsx(ToolCallSection, {
                        type: "input",
                        title: _({
                            id: 'tool-call.input'
                        }),
                        isExpanded: expandedSections['input'],
                        onToggle: ()=>setExpandedSections((prev)=>({
                                    ...prev,
                                    input: !prev['input']
                                })),
                        data: input || (span ? getAttributes(span.data).arguments : void 0)
                    }),
                    displayMode === ConversationalDisplayModeTypes.FullTrace && span?.children?.length ? /*#__PURE__*/ jsx(ToolCallSection, {
                        type: "traces",
                        title: _({
                            id: 'tool-call.traces'
                        }),
                        isExpanded: expandedSections['traces'],
                        onToggle: ()=>setExpandedSections((prev)=>({
                                    ...prev,
                                    traces: !prev['traces']
                                })),
                        children: /*#__PURE__*/ jsx(TraceItemsContainer, {
                            children: getVisibleChildren(span).map((child)=>/*#__PURE__*/ jsx(TraceItemContent, {
                                    child: child,
                                    depth: 0
                                }, child.key))
                        })
                    }) : null,
                    taskUrls.length > 0 ? /*#__PURE__*/ jsx(ToolCallSection, {
                        type: "escalation",
                        title: _({
                            id: 'tool-call.escalation'
                        }),
                        isExpanded: expandedSections['escalation'],
                        onToggle: ()=>setExpandedSections((prev)=>({
                                    ...prev,
                                    escalation: !prev['escalation']
                                })),
                        data: {
                            taskUrls
                        }
                    }) : null,
                    (isError && output || span && getAttributes(span.data).error) && /*#__PURE__*/ jsx(ToolCallSection, {
                        type: "errors",
                        title: _({
                            id: 'tool-call.errors'
                        }),
                        isExpanded: expandedSections['errors'],
                        onToggle: ()=>setExpandedSections((prev)=>({
                                    ...prev,
                                    errors: !prev['errors']
                                })),
                        data: isError && output ? output : span ? getAttributes(span.data).error : {}
                    }),
                    (!isError && output || span && getAttributes(span.data).result) && /*#__PURE__*/ jsx(ToolCallSection, {
                        type: "output",
                        title: _({
                            id: 'tool-call.output'
                        }),
                        isExpanded: expandedSections['output'],
                        onToggle: ()=>setExpandedSections((prev)=>({
                                    ...prev,
                                    output: !prev['output']
                                })),
                        data: output || (span ? getAttributes(span.data).result : {}) || {}
                    })
                ]
            })
        ]
    });
});
ApToolCall.displayName = 'ApToolCall';
export { ApToolCall };
