'use client';
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { useState, useCallback, useEffect, useMemo, useRef } from 'react';
import { PaperPlaneRight, X, ArrowCounterClockwise, ShieldCheck, ShieldWarning } from '@phosphor-icons/react';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';
import { MethodSelector } from './method-selector';
import { RequestTabs } from './request-tabs';
import { ResponseViewer } from './response-viewer';
import { createCancelableRequest, createCancelableStreamingRequest } from '@/lib/api-docs/playground/request-runner';
import { useAuth, getAuthTypeLabel } from '@/lib/api-docs/auth';
import { usePlaygroundPrefill, useCurrentRequestPayload, useSendTrigger } from '@/lib/api-docs/playground/context';
// LocalStorage key prefix for playground state
const PLAYGROUND_STORAGE_KEY = 'brainfish-playground-';
// Helper to get storage key for a request
function getStorageKey(request) {
    const id = request.name || request.endpoint;
    return `${PLAYGROUND_STORAGE_KEY}${btoa(id).replace(/[^a-zA-Z0-9]/g, '')}`;
}
// Load stored state from localStorage
function loadStoredState(request) {
    if (typeof window === 'undefined') return null;
    try {
        const key = getStorageKey(request);
        const stored = localStorage.getItem(key);
        if (stored) {
            return JSON.parse(stored);
        }
    } catch (e) {
        console.warn('[Playground] Failed to load stored state:', e);
    }
    return null;
}
// Save state to localStorage
function saveStoredState(request, state) {
    if (typeof window === 'undefined') return;
    try {
        const key = getStorageKey(request);
        localStorage.setItem(key, JSON.stringify(state));
    } catch (e) {
        console.warn('[Playground] Failed to save state:', e);
    }
}
// Clear stored state
function clearStoredState(request) {
    if (typeof window === 'undefined') return;
    try {
        const key = getStorageKey(request);
        localStorage.removeItem(key);
    } catch (e) {
        console.warn('[Playground] Failed to clear state:', e);
    }
}
export function ApiPlayground({ request, onDebugRequest, onExplainRequest }) {
    // Global auth - takes priority over endpoint-specific auth
    const { globalAuth } = useAuth();
    // Agent prefill context
    const { pendingPrefill, clearPrefill } = usePlaygroundPrefill();
    // Current request payload context - share with agent
    const { setCurrentRequestPayload } = useCurrentRequestPayload();
    // Send trigger from agent
    const { triggerSend, clearSendTrigger } = useSendTrigger();
    // Track if we've loaded from localStorage
    const hasLoadedRef = useRef(false);
    // Request state - initialize with defaults, will load from localStorage in useEffect
    const [method, setMethod] = useState(request.method);
    const [endpoint, setEndpoint] = useState(request.endpoint);
    // Path variables (for URL path params like {id} or <<id>>)
    const [pathVariables, setPathVariables] = useState(request.requestVariables.map((v, i)=>({
            id: `pathvar_${i}`,
            key: v.key,
            value: v.value,
            active: true,
            description: ''
        })));
    // Store the original endpoint template for path variable substitution
    const endpointTemplateRef = useRef(request.endpoint);
    const [params, setParams] = useState(request.params.map((p, i)=>({
            id: `param_${i}`,
            key: p.key,
            value: p.value,
            active: p.active,
            description: p.description
        })));
    const [headers, setHeaders] = useState(request.headers.map((h, i)=>({
            id: `header_${i}`,
            key: h.key,
            value: h.value,
            active: h.active,
            description: h.description
        })));
    const [body, setBody] = useState(typeof request.body.body === 'string' ? request.body.body : null);
    const [bodyContentType, setBodyContentType] = useState(request.body.contentType);
    // Track if user has overridden global auth for this endpoint
    const [authOverride, setAuthOverride] = useState(null);
    // Update endpoint URL when path variables change
    useEffect(()=>{
        let newEndpoint = endpointTemplateRef.current;
        pathVariables.forEach((variable)=>{
            if (variable.value) {
                // Replace <<variable>> pattern
                newEndpoint = newEndpoint.replace(new RegExp(`<<${variable.key}>>`, 'g'), variable.value);
                // Replace {variable} pattern
                newEndpoint = newEndpoint.replace(new RegExp(`\\{${variable.key}\\}`, 'g'), variable.value);
                // Replace URL-encoded patterns
                newEndpoint = newEndpoint.replace(new RegExp(`%3C%3C${variable.key}%3E%3E`, 'gi'), variable.value);
            }
        });
        setEndpoint(newEndpoint);
    }, [
        pathVariables
    ]);
    // Response state
    const [responseState, setResponseState] = useState({
        type: 'idle'
    });
    const [cancelFunc, setCancelFunc] = useState(null);
    // Save state to localStorage when values change (debounced)
    useEffect(()=>{
        if (!hasLoadedRef.current) return; // Don't save before initial load
        const timeoutId = setTimeout(()=>{
            saveStoredState(request, {
                body,
                headers,
                params
            });
        }, 500) // Debounce 500ms
        ;
        return ()=>clearTimeout(timeoutId);
    }, [
        request,
        body,
        headers,
        params
    ]);
    // Update current request payload context for agent access
    useEffect(()=>{
        setCurrentRequestPayload({
            method,
            endpoint,
            params: params.filter((p)=>p.key).map((p)=>({
                    key: p.key,
                    value: p.value,
                    active: p.active
                })),
            headers: headers.filter((h)=>h.key).map((h)=>({
                    key: h.key,
                    value: h.value,
                    active: h.active
                })),
            body,
            bodyContentType
        });
        // Cleanup on unmount
        return ()=>setCurrentRequestPayload(null);
    }, [
        method,
        endpoint,
        params,
        headers,
        body,
        bodyContentType,
        setCurrentRequestPayload
    ]);
    // Determine effective auth: override > global > endpoint default
    // Global auth takes priority when available, unless user explicitly overrides
    const effectiveAuth = useMemo(()=>{
        if (authOverride) {
            return authOverride;
        }
        // If global auth is configured, use it by default
        if (globalAuth && globalAuth.authType !== 'none') {
            return globalAuth;
        }
        // Fall back to endpoint's own auth
        return request.auth;
    }, [
        authOverride,
        globalAuth,
        request.auth
    ]);
    // Check if currently using global auth (global is set and no override)
    const usingGlobalAuth = !authOverride && globalAuth !== null && globalAuth.authType !== 'none';
    // Reset state when request changes - but load from localStorage if available
    useEffect(()=>{
        // Load stored state from localStorage
        const stored = loadStoredState(request);
        setMethod(request.method);
        setEndpoint(request.endpoint);
        // Update endpoint template reference
        endpointTemplateRef.current = request.endpoint;
        // Reset path variables from request
        setPathVariables(request.requestVariables.map((v, i)=>({
                id: `pathvar_${i}`,
                key: v.key,
                value: v.value,
                active: true,
                description: ''
            })));
        // Use stored params if available, otherwise use request defaults
        if (stored?.params && stored.params.length > 0) {
            setParams(stored.params);
        } else {
            setParams(request.params.map((p, i)=>({
                    id: `param_${i}`,
                    key: p.key,
                    value: p.value,
                    active: p.active,
                    description: p.description
                })));
        }
        // Use stored headers if available, otherwise use request defaults
        if (stored?.headers && stored.headers.length > 0) {
            setHeaders(stored.headers);
        } else {
            setHeaders(request.headers.map((h, i)=>({
                    id: `header_${i}`,
                    key: h.key,
                    value: h.value,
                    active: h.active,
                    description: h.description
                })));
        }
        // Use stored body if available, otherwise use request default
        if (stored?.body !== undefined) {
            setBody(stored.body);
        } else {
            setBody(typeof request.body.body === 'string' ? request.body.body : null);
        }
        setBodyContentType(request.body.contentType);
        setAuthOverride(null); // Reset override when changing endpoints
        setResponseState({
            type: 'idle'
        });
        // Mark as loaded so saving can start
        hasLoadedRef.current = true;
    }, [
        request
    ]);
    // Apply prefill data from agent
    useEffect(()=>{
        if (!pendingPrefill) return;
        console.log('[Playground] Applying prefill:', pendingPrefill);
        // Apply params
        if (pendingPrefill.params && pendingPrefill.params.length > 0) {
            setParams((prev)=>{
                const updated = [
                    ...prev
                ];
                pendingPrefill.params.forEach((prefillParam)=>{
                    const existing = updated.find((p)=>p.key === prefillParam.key);
                    if (existing) {
                        existing.value = prefillParam.value;
                        existing.active = true;
                    } else {
                        updated.push({
                            id: `param_${Date.now()}_${Math.random().toString(36).slice(2)}`,
                            key: prefillParam.key,
                            value: prefillParam.value,
                            active: true,
                            description: ''
                        });
                    }
                });
                return updated;
            });
        }
        // Apply headers
        if (pendingPrefill.headers && pendingPrefill.headers.length > 0) {
            setHeaders((prev)=>{
                const updated = [
                    ...prev
                ];
                pendingPrefill.headers.forEach((prefillHeader)=>{
                    const existing = updated.find((h)=>h.key === prefillHeader.key);
                    if (existing) {
                        existing.value = prefillHeader.value;
                        existing.active = true;
                    } else {
                        updated.push({
                            id: `header_${Date.now()}_${Math.random().toString(36).slice(2)}`,
                            key: prefillHeader.key,
                            value: prefillHeader.value,
                            active: true,
                            description: ''
                        });
                    }
                });
                return updated;
            });
        }
        // Apply body
        if (pendingPrefill.body) {
            setBody(pendingPrefill.body);
        }
        // Apply path variables (for URL path params like {id})
        if (pendingPrefill.pathVariables && pendingPrefill.pathVariables.length > 0) {
            setPathVariables((prev)=>{
                const updated = [
                    ...prev
                ];
                pendingPrefill.pathVariables.forEach((prefillVar)=>{
                    const existing = updated.find((v)=>v.key === prefillVar.key);
                    if (existing) {
                        existing.value = prefillVar.value;
                    } else {
                        updated.push({
                            id: `pathvar_${Date.now()}_${Math.random().toString(36).slice(2)}`,
                            key: prefillVar.key,
                            value: prefillVar.value,
                            active: true,
                            description: ''
                        });
                    }
                });
                return updated;
            });
        }
        // Clear the prefill after applying
        clearPrefill();
    }, [
        pendingPrefill,
        clearPrefill
    ]);
    // Handle send trigger from agent
    useEffect(()=>{
        if (triggerSend) {
            // Clear the trigger immediately
            clearSendTrigger();
            // Trigger the send (handleSend is called below)
            // We need to call it after this effect, so we use a timeout
            setTimeout(()=>{
                const sendButton = document.querySelector('[data-send-button]');
                if (sendButton) {
                    sendButton.click();
                }
            }, 0);
        }
    }, [
        triggerSend,
        clearSendTrigger
    ]);
    const handleSend = useCallback(async ()=>{
        if (!endpoint.trim()) {
            return;
        }
        setResponseState({
            type: 'loading'
        });
        // Always use streaming proxy - it auto-detects SSE from response content-type
        // and falls back to regular JSON handling for non-streaming responses
        const shouldStream = true;
        // Build request object - use effectiveAuth for authentication
        const requestToSend = {
            ...request,
            method,
            endpoint,
            params: params.filter((p)=>p.key).map((p)=>({
                    key: p.key,
                    value: p.value,
                    active: p.active,
                    description: p.description || ''
                })),
            headers: headers.filter((h)=>h.key).map((h)=>({
                    key: h.key,
                    value: h.value,
                    active: h.active,
                    description: h.description || ''
                })),
            body: bodyContentType ? {
                contentType: bodyContentType,
                body: body || ''
            } : {
                contentType: null,
                body: null
            },
            auth: effectiveAuth
        };
        const requestOptions = {
            params: params.filter((p)=>p.key).map((p)=>({
                    key: p.key,
                    value: p.value,
                    active: p.active
                })),
            headers: headers.filter((h)=>h.key).map((h)=>({
                    key: h.key,
                    value: h.value,
                    active: h.active
                })),
            body,
            variables: [],
            // Streaming callbacks
            onChunk: shouldStream ? (chunk, accumulated)=>{
                setResponseState((prev)=>{
                    if (prev.type === 'streaming' || prev.type === 'loading') {
                        return {
                            type: 'streaming',
                            response: {
                                ...prev.type === 'streaming' ? prev.response : {
                                    status: 0,
                                    statusText: 'Streaming...',
                                    headers: {},
                                    responseTime: 0,
                                    size: 0
                                },
                                body: accumulated,
                                size: new Blob([
                                    accumulated
                                ]).size,
                                isStreaming: true
                            }
                        };
                    }
                    return prev;
                });
            } : undefined,
            onStreamStart: shouldStream ? (metadata)=>{
                setResponseState({
                    type: 'streaming',
                    response: {
                        status: metadata.status,
                        statusText: metadata.statusText,
                        headers: metadata.headers,
                        body: '',
                        responseTime: 0,
                        size: 0,
                        isStreaming: true
                    }
                });
            } : undefined
        };
        const createRequest = shouldStream ? createCancelableStreamingRequest : createCancelableRequest;
        const { execute, cancel } = createRequest(requestToSend, requestOptions);
        setCancelFunc(()=>cancel);
        try {
            const response = await execute();
            if (response.error) {
                setResponseState({
                    type: 'error',
                    response,
                    error: response.error
                });
            } else {
                setResponseState({
                    type: 'success',
                    response
                });
            }
        } catch (error) {
            setResponseState({
                type: 'error',
                error: error instanceof Error ? error.message : 'Request failed'
            });
        } finally{
            setCancelFunc(null);
        }
    }, [
        request,
        method,
        endpoint,
        params,
        headers,
        body,
        bodyContentType,
        effectiveAuth
    ]);
    const handleCancel = useCallback(()=>{
        if (cancelFunc) {
            cancelFunc();
            setCancelFunc(null);
            setResponseState({
                type: 'idle'
            });
        }
    }, [
        cancelFunc
    ]);
    const handleClear = useCallback(()=>{
        // Reset to original request values
        setEndpoint(request.endpoint);
        setParams(request.params.map((p, i)=>({
                id: `param_${i}`,
                key: p.key,
                value: p.value,
                active: p.active,
                description: p.description
            })));
        setHeaders(request.headers.map((h, i)=>({
                id: `header_${i}`,
                key: h.key,
                value: h.value,
                active: h.active,
                description: h.description
            })));
        setBody(typeof request.body.body === 'string' ? request.body.body : null);
        setBodyContentType(request.body.contentType);
        setAuthOverride(null); // Clear override, will use global auth
        setResponseState({
            type: 'idle'
        });
        // Clear stored state from localStorage
        clearStoredState(request);
    }, [
        request
    ]);
    const isLoading = responseState.type === 'loading' || responseState.type === 'streaming';
    return /*#__PURE__*/ _jsx(TooltipProvider, {
        children: /*#__PURE__*/ _jsxs("div", {
            className: "flex flex-col h-full bg-background",
            children: [
                /*#__PURE__*/ _jsxs("div", {
                    className: "sticky top-0 z-20 flex flex-shrink-0 flex-wrap items-center gap-2 bg-muted/50 p-2 sm:p-4 border-b border-border",
                    children: [
                        /*#__PURE__*/ _jsxs("div", {
                            className: "flex flex-1 min-w-0 items-center rounded-sm border border-border bg-background overflow-hidden",
                            children: [
                                /*#__PURE__*/ _jsx(MethodSelector, {
                                    value: method,
                                    onChange: setMethod,
                                    disabled: isLoading
                                }),
                                /*#__PURE__*/ _jsx(Input, {
                                    type: "text",
                                    value: endpoint,
                                    onChange: (e)=>setEndpoint(e.target.value),
                                    onKeyDown: (e)=>{
                                        if (e.key === 'Enter' && !isLoading) {
                                            handleSend();
                                        }
                                    },
                                    placeholder: "Enter URL",
                                    className: "flex-1 border-0 rounded-none focus-visible:ring-0 focus-visible:ring-offset-0 text-sm",
                                    disabled: isLoading
                                }),
                                /*#__PURE__*/ _jsxs(Tooltip, {
                                    children: [
                                        /*#__PURE__*/ _jsx(TooltipTrigger, {
                                            asChild: true,
                                            children: /*#__PURE__*/ _jsxs("div", {
                                                className: `hidden xs:flex items-center gap-1.5 px-2 sm:px-3 h-full border-l border-border text-xs font-medium cursor-default ${effectiveAuth.authType !== 'none' ? 'text-green-600 dark:text-green-400' : 'text-muted-foreground'}`,
                                                children: [
                                                    effectiveAuth.authType !== 'none' ? /*#__PURE__*/ _jsx(ShieldCheck, {
                                                        className: "h-3.5 w-3.5",
                                                        weight: "fill"
                                                    }) : /*#__PURE__*/ _jsx(ShieldWarning, {
                                                        className: "h-3.5 w-3.5"
                                                    }),
                                                    /*#__PURE__*/ _jsx("span", {
                                                        className: "hidden sm:inline",
                                                        children: effectiveAuth.authType !== 'none' ? usingGlobalAuth ? 'Global' : 'Custom' : 'No Auth'
                                                    })
                                                ]
                                            })
                                        }),
                                        /*#__PURE__*/ _jsx(TooltipContent, {
                                            side: "bottom",
                                            children: effectiveAuth.authType !== 'none' ? /*#__PURE__*/ _jsxs("div", {
                                                className: "text-xs",
                                                children: [
                                                    /*#__PURE__*/ _jsx("p", {
                                                        className: "font-medium",
                                                        children: getAuthTypeLabel(effectiveAuth)
                                                    }),
                                                    /*#__PURE__*/ _jsx("p", {
                                                        className: "text-muted-foreground",
                                                        children: usingGlobalAuth ? 'Using global auth' : 'Custom for this endpoint'
                                                    })
                                                ]
                                            }) : /*#__PURE__*/ _jsx("p", {
                                                className: "text-xs",
                                                children: "No authentication configured"
                                            })
                                        })
                                    ]
                                })
                            ]
                        }),
                        /*#__PURE__*/ _jsx(Button, {
                            onClick: isLoading ? handleCancel : handleSend,
                            variant: isLoading ? 'destructive' : 'default',
                            className: "px-3 sm:px-6",
                            "data-send-button": true,
                            children: isLoading ? /*#__PURE__*/ _jsxs(_Fragment, {
                                children: [
                                    /*#__PURE__*/ _jsx(X, {
                                        className: "h-4 w-4 sm:mr-2",
                                        weight: "bold"
                                    }),
                                    /*#__PURE__*/ _jsx("span", {
                                        className: "hidden sm:inline",
                                        children: "Cancel"
                                    })
                                ]
                            }) : /*#__PURE__*/ _jsxs(_Fragment, {
                                children: [
                                    /*#__PURE__*/ _jsx(PaperPlaneRight, {
                                        className: "h-4 w-4 sm:mr-2",
                                        weight: "fill"
                                    }),
                                    /*#__PURE__*/ _jsx("span", {
                                        className: "hidden sm:inline",
                                        children: "Send"
                                    })
                                ]
                            })
                        }),
                        /*#__PURE__*/ _jsxs(Tooltip, {
                            children: [
                                /*#__PURE__*/ _jsx(TooltipTrigger, {
                                    asChild: true,
                                    children: /*#__PURE__*/ _jsx(Button, {
                                        variant: "outline",
                                        size: "icon",
                                        onClick: handleClear,
                                        className: "shrink-0",
                                        children: /*#__PURE__*/ _jsx(ArrowCounterClockwise, {
                                            className: "h-4 w-4",
                                            weight: "bold"
                                        })
                                    })
                                }),
                                /*#__PURE__*/ _jsx(TooltipContent, {
                                    children: "Clear all"
                                })
                            ]
                        })
                    ]
                }),
                /*#__PURE__*/ _jsxs("div", {
                    className: "flex-1 flex flex-col lg:flex-row overflow-hidden",
                    children: [
                        /*#__PURE__*/ _jsx("div", {
                            className: "flex-1 flex flex-col border-b lg:border-b-0 lg:border-r border-border min-h-[200px] sm:min-h-[300px] lg:min-h-0",
                            children: /*#__PURE__*/ _jsx(RequestTabs, {
                                params: params,
                                headers: headers,
                                body: body,
                                bodyContentType: bodyContentType,
                                auth: effectiveAuth,
                                usingGlobalAuth: usingGlobalAuth,
                                globalAuth: globalAuth,
                                onParamsChange: setParams,
                                onHeadersChange: setHeaders,
                                onBodyChange: setBody,
                                onBodyContentTypeChange: setBodyContentType,
                                onAuthChange: setAuthOverride,
                                onUseGlobalAuth: ()=>setAuthOverride(null)
                            }, request.id)
                        }),
                        /*#__PURE__*/ _jsx("div", {
                            className: "flex-1 flex flex-col min-h-[200px] sm:min-h-[300px] lg:min-h-0 overflow-hidden",
                            children: /*#__PURE__*/ _jsx(ResponseViewer, {
                                responseState: responseState,
                                onDebugRequest: onDebugRequest ? (context)=>{
                                    // Enrich context with endpoint info
                                    onDebugRequest({
                                        ...context,
                                        endpointName: request.name,
                                        endpointMethod: method,
                                        endpointPath: endpoint,
                                        requestBody: body || undefined
                                    });
                                } : undefined,
                                onExplainRequest: onExplainRequest ? (context)=>{
                                    // Enrich context with endpoint info
                                    onExplainRequest({
                                        ...context,
                                        endpointName: request.name,
                                        endpointMethod: method,
                                        endpointPath: endpoint,
                                        requestBody: body || undefined
                                    });
                                } : undefined
                            })
                        })
                    ]
                })
            ]
        })
    });
}
