import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { CodeOutlined, CodeSandboxOutlined, CopyOutlined, DownOutlined, QuestionCircleOutlined, ThunderboltOutlined } from '@ant-design/icons';
import { Dropdown, Menu } from 'antd';
import { getParameters } from 'codesandbox-import-utils/lib/api/define';
import { Component, Suspense } from 'react';
import { Redirect, withRouter } from 'react-router-dom';
import styled from 'styled-components';
import PrismCode from './PrismCode';
import { Button, Card, CubeLoader } from './atoms';
import { SectionRow } from './components';
import { FatalError } from './components/Error/FatalError';
import { playgroundAction } from './events';
import { loadable } from './loadable';
import { GraphQLIcon } from './shared/icons/GraphQLIcon';
import { codeSandboxDefinition, copyToClipboard } from './utils';
const GraphiQLSandbox = loadable(() => import('./components/GraphQL/GraphiQLSandbox'));
const SqlQueryTab = loadable(() => import('./components/SqlQueryTab'));
const CachePane = loadable(() => import('./components/CachePane'));
const frameworkToTemplate = {
    react: 'create-react-app',
    angular: 'angular-cli',
    vue: 'vue-cli',
};
const StyledCard = styled(Card) `
  min-height: 420px;

  .ant-card-head {
    position: sticky;
    top: 0;
    z-index: 1;
    background: white;
  }

  .ant-card-body {
    max-width: 100%;
    overflow: auto;
    position: relative;
  }
`;
const UnsupportedFrameworkPlaceholder = ({ framework, }) => (_jsxs("h2", { style: { padding: 24, textAlign: 'center' }, children: ["We do not support\u00A0 Vanilla JavaScript \u00A0code generation here yet.", _jsx("br", {}), "Please refer to\u00A0", _jsx("a", { href: "https://cube.dev/reference/javascript-sdk/reference/cubejs-client-core", target: "_blank", rel: "noopener noreferrer", onClick: () => playgroundAction('Unsupported Framework Docs', { framework }), children: "Vanilla JavaScript \u00A0docs" }), "\u00A0to see on how to use it with Cube."] }));
const BIPlaceholder = () => (_jsxs("h2", { style: { padding: 24, textAlign: 'center' }, children: ["You can connect Cube to any Business Intelligence tool through the Cube SQL API.", _jsx("br", {}), "Please refer to\u00A0", _jsx("a", { href: "https://cube.dev/reference/core-data-apis/sql-api", target: "_blank", rel: "noopener noreferrer", onClick: () => playgroundAction('BI Docs'), children: "Cube SQL \u00A0docs" }), "\u00A0to learn more."] }));
export const frameworks = [
    {
        id: 'react',
        title: 'React',
        scaffoldingSupported: true,
    },
    {
        id: 'angular',
        title: 'Angular',
        scaffoldingSupported: true,
    },
    {
        id: 'vue',
        title: 'Vue',
        scaffoldingSupported: true,
    },
    {
        id: 'vanilla',
        title: 'Vanilla JavaScript',
        placeholder: UnsupportedFrameworkPlaceholder,
    },
    {
        id: 'bi',
        title: 'BI',
        placeholder: BIPlaceholder,
    },
];
class ChartContainer extends Component {
    static getDerivedStateFromProps(props, state) {
        if (props.isChartRendererReady &&
            props.iframeRef.current != null &&
            props.chartingLibrary) {
            const { __cubejsPlayground } = props.iframeRef.current.contentWindow || {};
            if (!__cubejsPlayground) {
                return {
                    ...state,
                    chartRendererError: 'The chart renderer failed to load',
                };
            }
            const codesandboxFiles = __cubejsPlayground.getCodesandboxFiles(props.chartingLibrary, {
                chartType: props.chartType,
                query: JSON.stringify(props.query, null, 2),
                pivotConfig: JSON.stringify(props.pivotConfig, null, 2),
                apiUrl: props.apiUrl,
                cubejsToken: props.cubejsToken,
            });
            let codeExample = '';
            if (props.framework === 'react') {
                codeExample = codesandboxFiles['index.js'];
            }
            else if (props.framework === 'angular') {
                codeExample =
                    codesandboxFiles['src/app/query-renderer/query-renderer.component.ts'];
            }
            else if (props.framework === 'vue') {
                codeExample = codesandboxFiles['src/components/ChartRenderer.vue'];
            }
            return {
                ...state,
                chartRendererError: null,
                dependencies: __cubejsPlayground.getDependencies(props.chartingLibrary),
                codeExample,
                codesandboxFiles,
            };
        }
        return state;
    }
    constructor(props) {
        super(props);
        this.state = {
            activeTab: 'chart',
            chartRendererError: null,
            sql: {
                loading: false,
            },
        };
    }
    render() {
        const { codeExample, codesandboxFiles, dependencies, redirectToDashboard, activeTab, addingToDashboard, chartRendererError, sql, } = this.state;
        const { isChartRendererReady, resultSet, error, render, hideActions, query, chartingLibrary, setChartLibrary, chartLibraries, framework, setFramework, meta, isFetchingMeta, onChartRendererReadyChange, } = this.props;
        if (redirectToDashboard) {
            return _jsx(Redirect, { to: "/dashboard" });
        }
        if (chartRendererError) {
            return _jsx("div", { children: chartRendererError });
        }
        const parameters = isChartRendererReady
            ? getParameters(codeSandboxDefinition(frameworkToTemplate[framework], codesandboxFiles, dependencies))
            : null;
        const chartLibrariesMenu = (chartLibraries[framework] || []).length > 0 ? (_jsx(Menu, { "data-testid": "charting-library-dropdown", onClick: (e) => {
                playgroundAction('Set Chart Library', { chartingLibrary: e.key });
                setChartLibrary(e.key);
            }, children: (chartLibraries[framework] || []).map((library) => (_jsx(Menu.Item, { children: library.title }, library.value))) })) : null;
        const frameworkMenu = (_jsx(Menu, { "data-testid": "framework-dropdown", onClick: (e) => {
                if (e.key === framework) {
                    return;
                }
                playgroundAction('Set Framework', { framework: e.key });
                setFramework(e.key);
                onChartRendererReadyChange(false);
                setChartLibrary(chartLibraries[e.key]?.[0]?.value || null);
            }, children: frameworks.map((f) => (_jsx(Menu.Item, { children: f.title }, f.id))) }));
        const currentLibraryItem = (chartLibraries[framework] || []).find((m) => m.value === chartingLibrary);
        const frameworkItem = frameworks.find((m) => m.id === framework);
        const extra = (_jsxs("form", { action: "https://codesandbox.io/api/v1/sandboxes/define", method: "POST", target: "_blank", children: [parameters != null ? (_jsx("input", { type: "hidden", name: "parameters", value: parameters })) : null, _jsxs(SectionRow, { children: [_jsxs(Button.Group, { children: [_jsx(Dropdown, { overlay: frameworkMenu, disabled: isFetchingMeta, children: _jsxs(Button, { "data-testid": "framework-btn", size: "small", children: [frameworkItem?.title, _jsx(DownOutlined, {})] }) }), chartLibrariesMenu ? (_jsx(Dropdown, { overlay: chartLibrariesMenu, disabled: !!frameworkItem?.placeholder || isFetchingMeta, children: _jsxs(Button, { "data-testid": "charting-library-btn", size: "small", children: [currentLibraryItem?.title, _jsx(DownOutlined, {})] }) })) : null] }), _jsxs(Button.Group, { children: [_jsx(Button, { "data-testid": "chart-btn", size: "small", type: activeTab === 'chart' ? 'primary' : 'default', disabled: !!frameworkItem?.placeholder || isFetchingMeta, onClick: () => {
                                        playgroundAction('Show Chart');
                                        this.setState({ activeTab: 'chart' });
                                    }, children: "Chart" }), _jsx(Button, { "data-testid": "json-query-btn", size: "small", type: activeTab === 'query' ? 'primary' : 'default', disabled: !!frameworkItem?.placeholder || isFetchingMeta, onClick: () => {
                                        playgroundAction('Show Query');
                                        this.setState({
                                            activeTab: 'query',
                                        });
                                    }, children: "JSON Query" }), _jsx(Button, { "data-testid": "graphiql-btn", icon: _jsx(GraphQLIcon, {}), size: "small", type: activeTab === 'graphiql' ? 'primary' : 'default', disabled: !!frameworkItem?.placeholder || isFetchingMeta, onClick: () => {
                                        playgroundAction('Show GraphiQL');
                                        this.setState({ activeTab: 'graphiql' });
                                    }, children: "GraphiQL" }), _jsx(Button, { "data-testid": "code-btn", icon: _jsx(CodeOutlined, {}), size: "small", type: activeTab === 'code' ? 'primary' : 'default', disabled: !!frameworkItem?.placeholder || isFetchingMeta, onClick: () => {
                                        playgroundAction('Show Code');
                                        this.setState({ activeTab: 'code' });
                                    }, children: "Code" }), _jsx(Button, { "data-testid": "sql-btn", icon: _jsx(QuestionCircleOutlined, {}), size: "small", type: activeTab === 'generated-sql' ? 'primary' : 'default', disabled: !!frameworkItem?.placeholder || isFetchingMeta, onClick: () => {
                                        playgroundAction('Show SQL');
                                        this.setState({ activeTab: 'generated-sql' });
                                    }, children: "Generated SQL" }), _jsx(Button, { "data-testid": "cache-btn", icon: _jsx(ThunderboltOutlined, {}), size: "small", type: activeTab === 'cache' ? 'primary' : 'default', disabled: !!frameworkItem?.placeholder || isFetchingMeta, onClick: () => {
                                        playgroundAction('Show Cache');
                                        this.setState({
                                            activeTab: 'cache',
                                        });
                                    }, children: "Cache" })] }), _jsx(Button, { "data-testid": "edit-btn", icon: _jsx(CodeSandboxOutlined, {}), size: "small", htmlType: "submit", disabled: !!frameworkItem?.placeholder || isFetchingMeta, onClick: () => playgroundAction('Open Code Sandbox'), children: "Edit" })] })] }));
        const queryText = JSON.stringify(query, null, 2);
        const renderChart = () => {
            if (frameworkItem?.placeholder) {
                const Placeholder = frameworkItem.placeholder;
                return _jsx(Placeholder, { framework: framework });
            }
            else if (activeTab === 'code') {
                if (error) {
                    return _jsx(FatalError, { error: error });
                }
                return _jsx(PrismCode, { code: codeExample });
            }
            else if (activeTab === 'query') {
                return _jsx(PrismCode, { code: queryText });
            }
            else if (activeTab === 'generated-sql') {
                return (_jsx(Suspense, { fallback: _jsx("div", { style: { height: 363 }, children: _jsx(CubeLoader, {}) }), children: _jsx(SqlQueryTab, { query: query, onChange: (sql) => {
                            this.setState({ sql });
                        } }) }));
            }
            else if (activeTab === 'cache') {
                return (_jsx(Suspense, { fallback: _jsx("div", { style: { height: 363 }, children: _jsx(CubeLoader, {}) }), children: _jsx(CachePane, { query: query }) }));
            }
            else if (activeTab === 'graphiql' && meta) {
                if (!this.props.isGraphQLSupported) {
                    return _jsx("div", { children: "GraphQL API is supported since version 0.29.0" });
                }
                return (_jsx(Suspense, { fallback: _jsx("div", { style: { height: 363 }, children: _jsx(CubeLoader, {}) }), children: _jsx(GraphiQLSandbox, { apiUrl: this.props.apiUrl, query: query, meta: meta }) }));
            }
            return null;
        };
        let title;
        if (activeTab === 'code') {
            title = (_jsxs(SectionRow, { style: { alignItems: 'center' }, children: [_jsx("div", { children: "Code" }), _jsx(Button, { "data-testid": "copy-code-btn", icon: _jsx(CopyOutlined, {}), size: "small", disabled: Boolean(error), onClick: async () => {
                            await copyToClipboard(codeExample);
                            playgroundAction('Copy Code to Clipboard');
                        }, type: "primary", children: "Copy to Clipboard" })] }));
        }
        else if (activeTab === 'query') {
            title = (_jsxs(SectionRow, { children: [_jsx("div", { children: "Query" }), _jsx(Button, { "data-testid": "copy-cube-query-btn", icon: _jsx(CopyOutlined, {}), size: "small", onClick: async () => {
                            await copyToClipboard(JSON.stringify(query, null, 2));
                            playgroundAction('Copy Query to Clipboard');
                        }, type: "primary", children: "Copy to Clipboard" })] }));
        }
        else if (activeTab === 'generated-sql') {
            title = (_jsxs(SectionRow, { children: [_jsx("div", { children: "SQL" }), !sql.loading && sql.value ? (_jsx(Button, { "data-testid": "copy-sql-btn", icon: _jsx(CopyOutlined, {}), size: "small", onClick: async () => {
                            await copyToClipboard(sql.value, 'The SQL has been copied');
                            playgroundAction('Copy SQL to Clipboard');
                        }, type: "primary", children: "Copy to Clipboard" })) : null] }));
        }
        else if (activeTab === 'cache') {
            title = 'Cache';
        }
        else if (activeTab === 'graphiql') {
            title = 'GraphQL API';
        }
        else {
            title = 'Chart';
        }
        return hideActions ? (render({ resultSet, error })) : (_jsxs(StyledCard, { title: title, extra: extra, children: [renderChart(), activeTab === 'chart' ? (render({ framework, error })) : (_jsx("div", { style: { display: 'none' }, children: render({ framework, error }) }))] }));
    }
}
ChartContainer.defaultProps = {
    query: {},
    hideActions: false,
};
export default withRouter(ChartContainer);
//# sourceMappingURL=ChartContainer.js.map