import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { areQueriesEqual, validateQuery, getQueryMembers, } from '@cubejs-client/core';
import { QueryBuilder, } from '@cubejs-client/react';
import { Alert, Col, Row, Space } from 'antd';
import { SyncOutlined } from '@ant-design/icons';
import { useEffect, useRef, useState } from 'react';
import styled from 'styled-components';
import { Button, Card } from '../../../atoms';
import { FatalError } from '../../../components/Error/FatalError';
import ChartContainer from '../../../ChartContainer';
import { SectionHeader, SectionRow } from '../../../components';
import ChartRenderer from '../../../components/ChartRenderer/ChartRenderer';
import Settings from '../../../components/Settings/Settings';
import { playgroundAction } from '../../../events';
import { useDeepEffect, useIsMounted, useSecurityContext, useServerCoreVersionGte, } from '../../../hooks';
import FilterGroup from '../../../QueryBuilder/FilterGroup';
import MemberGroup from '../../../QueryBuilder/MemberGroup';
import SelectChartType from '../../../QueryBuilder/SelectChartType';
import TimeGroup from '../../../QueryBuilder/TimeGroup';
import { containsPrivateFields, dispatchPlaygroundEvent } from '../../../utils';
import { useChartRendererState, useChartRendererStateMethods, } from '../../QueryTabs/ChartRendererStateProvider';
import { PreAggregationStatus } from './PreAggregationStatus';
const Section = styled.div `
  display: flex;
  flex-flow: column;
  margin-right: 24px;
  margin-bottom: 16px;

  > *:first-child {
    margin-bottom: 8px;
  }
`;
const Wrapper = styled.div `
  background-color: var(--layout-body-background);
  padding-bottom: 16px;
`;
export const frameworkChartLibraries = {
    react: [
        {
            value: 'chartjs',
            title: 'Chart.js',
        },
        {
            value: 'bizcharts',
            title: 'Bizcharts',
        },
        {
            value: 'recharts',
            title: 'Recharts',
        },
        {
            value: 'd3',
            title: 'D3',
        },
    ],
    angular: [
        {
            value: 'angular-ng2-charts',
            title: 'ng2',
        },
    ],
    vue: [
        {
            value: 'chartkick',
            title: 'Chartkick',
        },
    ],
};
const playgroundActionUpdateMethods = (updateMethods, memberName) => Object.keys(updateMethods)
    .map((method) => ({
    [method]: (member, values, ...rest) => {
        let actionName = `${method
            .split('')
            .map((c, i) => (i === 0 ? c.toUpperCase() : c))
            .join('')} Member`;
        if (values?.values) {
            actionName = 'Update Filter Values';
        }
        if (values?.dateRange) {
            actionName = 'Update Date Range';
        }
        if (values?.granularity) {
            actionName = 'Update Granularity';
        }
        playgroundAction(actionName, { memberName });
        return updateMethods[method].apply(null, [member, values, ...rest]);
    },
}))
    .reduce((a, b) => ({ ...a, ...b }), {});
function PivotChangeEmitter({ iframeRef, pivotConfig, chartType, }) {
    useDeepEffect(() => {
        if (iframeRef?.current && ['table', 'bar'].includes(chartType)) {
            dispatchPlaygroundEvent(iframeRef.current.contentDocument, 'chart', {
                pivotConfig,
            });
        }
    }, [iframeRef, pivotConfig]);
    return null;
}
function QueryChangeEmitter({ query1, query2, onChange, }) {
    useDeepEffect(() => {
        if (!areQueriesEqual(validateQuery(query1), validateQuery(query2))) {
            onChange();
        }
    }, [query1, query2]);
    return null;
}
export function PlaygroundQueryBuilder({ apiUrl, cubejsToken, defaultQuery, queryId, schemaVersion = 0, initialVizState, extra: Extra, onSchemaChange, onVizStateChanged, }) {
    const isMounted = useIsMounted();
    const isGraphQLSupported = useServerCoreVersionGte('0.29.0');
    const { isChartRendererReady, queryStatus, queryError, queryRequestId, resultSetExists, } = useChartRendererState(queryId);
    const { setQueryStatus, setQueryLoading, setChartRendererReady, setQueryError, } = useChartRendererStateMethods();
    const { refreshToken } = useSecurityContext();
    const iframeRef = useRef(null);
    const queryRef = useRef(null);
    const [tokenRefreshed, setTokenRefreshed] = useState(false);
    const [framework, setFramework] = useState('react');
    const [chartingLibrary, setChartingLibrary] = useState('chartjs');
    useEffect(() => {
        (async () => {
            await refreshToken();
            if (isMounted()) {
                setTokenRefreshed(true);
            }
        })();
    }, [isMounted]);
    useEffect(() => {
        if (isChartRendererReady && iframeRef.current) {
            dispatchPlaygroundEvent(iframeRef.current.contentDocument, 'credentials', {
                token: cubejsToken,
                apiUrl,
            });
        }
    }, [iframeRef, cubejsToken, apiUrl, isChartRendererReady]);
    function handleRunButtonClick({ query, pivotConfig, chartType, }) {
        if (iframeRef.current) {
            if (areQueriesEqual(query, queryRef.current)) {
                dispatchPlaygroundEvent(iframeRef.current.contentDocument, 'chart', {
                    pivotConfig,
                    query,
                    chartType,
                    chartingLibrary,
                });
                dispatchPlaygroundEvent(iframeRef.current.contentDocument, 'refetch');
            }
            else {
                dispatchPlaygroundEvent(iframeRef.current.contentDocument, 'chart', {
                    pivotConfig,
                    query,
                    chartType,
                    chartingLibrary,
                });
            }
        }
        setQueryError(queryId, null);
        queryRef.current = query;
    }
    if (!tokenRefreshed) {
        return null;
    }
    return (_jsx(QueryBuilder, { defaultQuery: defaultQuery, initialVizState: initialVizState, wrapWithQueryRenderer: false, schemaVersion: schemaVersion, onSchemaChange: onSchemaChange, onVizStateChanged: onVizStateChanged, render: ({ query, error, metaError, richMetaError, metaErrorStack, meta, isQueryPresent, chartType, updateChartType, measures, updateMeasures, dimensions, updateDimensions, segments, updateSegments, filters, updateFilters, timeDimensions, updateTimeDimensions, orderMembers, updateOrder, pivotConfig, updatePivotConfig, missingMembers, isFetchingMeta, dryRunResponse, availableMembers, availableFilterMembers, }) => {
            let parsedDateRange;
            if (dryRunResponse) {
                const { timeDimensions = [] } = dryRunResponse.pivotQuery || {};
                parsedDateRange = timeDimensions[0]?.dateRange;
            }
            else if (Array.isArray(query.timeDimensions?.[0]?.dateRange)) {
                // @ts-ignore
                parsedDateRange = query.timeDimensions[0].dateRange;
            }
            const hasPrivateFields = containsPrivateFields(getQueryMembers(query), meta);
            const queriesEqual = areQueriesEqual(validateQuery(query), validateQuery(queryRef.current));
            return (_jsxs(Wrapper, { "data-testid": `query-builder-${queryId}`, children: [_jsx(Row, { justify: "space-around", align: "top", gutter: 24, style: { marginBottom: 12 }, children: _jsxs(Col, { span: 24, children: [_jsxs(Card, { bordered: false, style: { borderRadius: 0 }, children: [_jsxs(Row, { align: "top", gutter: 0, style: { marginBottom: -12 }, children: [_jsxs(Section, { children: [_jsx(SectionHeader, { children: "Measures" }), _jsx(MemberGroup, { disabled: isFetchingMeta, members: measures, availableMembers: availableMembers?.measures || [], missingMembers: missingMembers, addMemberName: "Measure", updateMethods: playgroundActionUpdateMethods(updateMeasures, 'Measure') })] }), _jsxs(Section, { children: [_jsx(SectionHeader, { children: "Dimensions" }), _jsx(MemberGroup, { disabled: isFetchingMeta, members: dimensions, availableMembers: availableMembers?.dimensions || [], missingMembers: missingMembers, addMemberName: "Dimension", updateMethods: playgroundActionUpdateMethods(updateDimensions, 'Dimension') })] }), _jsxs(Section, { children: [_jsx(SectionHeader, { children: "Segment" }), _jsx(MemberGroup, { disabled: isFetchingMeta, members: segments, availableMembers: availableMembers?.segments || [], missingMembers: missingMembers, addMemberName: "Segment", updateMethods: playgroundActionUpdateMethods(updateSegments, 'Segment') })] }), _jsxs(Section, { children: [_jsx(SectionHeader, { children: "Time" }), _jsx(TimeGroup, { disabled: isFetchingMeta, members: timeDimensions, availableMembers: availableMembers?.timeDimensions || [], missingMembers: missingMembers, addMemberName: "Time", updateMethods: playgroundActionUpdateMethods(updateTimeDimensions, 'Time'), parsedDateRange: parsedDateRange })] }), _jsxs(Section, { children: [_jsx(SectionHeader, { children: "Filters" }), _jsx(FilterGroup, { disabled: isFetchingMeta, members: filters, availableMembers: availableFilterMembers, missingMembers: missingMembers, addMemberName: "Filter", updateMethods: playgroundActionUpdateMethods(updateFilters, 'Filter') })] })] }), hasPrivateFields ? (_jsx(Alert, { type: "warning", message: "Some of the fields you have selected are private and will not be available for querying in production.", style: { marginTop: 16 } })) : null] }), _jsxs(SectionRow, { style: {
                                        margin: 16,
                                        marginBottom: 0,
                                    }, children: [_jsx(SelectChartType, { chartType: chartType || 'line', updateChartType: (type) => {
                                                playgroundAction('Change Chart Type');
                                                updateChartType(type);
                                                if (iframeRef.current) {
                                                    dispatchPlaygroundEvent(iframeRef.current.contentDocument, 'chart', {
                                                        chartType: type,
                                                        chartingLibrary,
                                                    });
                                                }
                                            } }), _jsx(Settings, { isQueryPresent: isQueryPresent, limit: query.limit || 5000, pivotConfig: pivotConfig, disabled: isFetchingMeta, orderMembers: orderMembers, onReorder: updateOrder.reorder, onOrderChange: updateOrder.set, onMove: updatePivotConfig.moveItem, onUpdate: updatePivotConfig.update }), _jsxs(Space, { style: { marginLeft: 'auto' }, children: [Extra ? (_jsx(Extra, { queryRequestId: queryRequestId || queryError?.response?.requestId, queryStatus: queryStatus, error: queryError })) : null, queryStatus ? (_jsx(PreAggregationStatus, { ...queryStatus })) : null, resultSetExists && queriesEqual ? (_jsx(Button, { icon: _jsx(SyncOutlined, {}), onClick: async () => {
                                                        await refreshToken();
                                                        handleRunButtonClick({
                                                            query: validateQuery(query),
                                                            pivotConfig,
                                                            chartType: chartType || 'line',
                                                        });
                                                    }, children: "Rerun query" })) : null] })] })] }) }), _jsx(Row, { justify: "space-around", align: "top", gutter: 32, style: { margin: 0 }, children: _jsxs(Col, { span: 24, children: [!isQueryPresent && richMetaError ? (_jsx(Card, { children: _jsx(FatalError, { error: richMetaError, stack: metaErrorStack }) })) : null, !isQueryPresent && !metaError && (_jsx("h2", { style: { textAlign: 'center' }, children: "Choose a measure or dimension to get started" })), isQueryPresent && (_jsx(ChartContainer, { apiUrl: apiUrl, cubejsToken: cubejsToken, meta: meta, isGraphQLSupported: isGraphQLSupported, iframeRef: iframeRef, isChartRendererReady: isChartRendererReady, query: query, error: error, chartType: chartType || 'line', pivotConfig: pivotConfig, framework: framework, chartingLibrary: chartingLibrary, setFramework: (currentFramework) => {
                                        if (currentFramework !== framework) {
                                            setQueryLoading(queryId, false);
                                            setFramework(currentFramework);
                                        }
                                    }, setChartLibrary: (value) => {
                                        if (iframeRef.current) {
                                            dispatchPlaygroundEvent(iframeRef.current.contentDocument, 'chart', {
                                                chartingLibrary: value,
                                            });
                                        }
                                        setChartingLibrary(value);
                                    }, chartLibraries: frameworkChartLibraries, isFetchingMeta: isFetchingMeta, render: ({ framework }) => {
                                        if (richMetaError) {
                                            return (_jsx(FatalError, { error: richMetaError, stack: metaErrorStack }));
                                        }
                                        return (_jsx(ChartRenderer, { queryId: queryId, areQueriesEqual: queriesEqual, isFetchingMeta: isFetchingMeta, queryError: queryError, framework: framework, chartType: chartType || 'line', query: query, pivotConfig: pivotConfig, iframeRef: iframeRef, queryHasMissingMembers: missingMembers.length > 0, onRunButtonClick: async () => {
                                                if (isChartRendererReady &&
                                                    iframeRef.current &&
                                                    missingMembers.length === 0) {
                                                    await refreshToken();
                                                    handleRunButtonClick({
                                                        query: validateQuery(query),
                                                        pivotConfig,
                                                        chartType: chartType || 'line',
                                                    });
                                                }
                                            } }));
                                    }, onChartRendererReadyChange: (isReady) => setChartRendererReady(queryId, isReady) }))] }) }), _jsx(PivotChangeEmitter, { iframeRef: iframeRef, chartType: chartType || 'line', pivotConfig: pivotConfig }), _jsx(QueryChangeEmitter, { query1: query, query2: queryRef.current, onChange: () => {
                            setQueryLoading(queryId, false);
                            setQueryStatus(queryId, null);
                        } })] }));
        } }));
}
//# sourceMappingURL=PlaygroundQueryBuilder.js.map