import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
/*
This file is part of the Notesnook project (https://notesnook.com/)

Copyright (C) 2023 Streetwriters (Private) Limited

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
import { Flex, Input, Text } from "@theme-ui/components";
import { useRef, useState } from "react";
import { Button } from "../../components/button";
import { ResponsivePresenter } from "../../components/responsive";
import { useTimer } from "../../hooks/use-timer";
import { Icon } from "@notesnook/ui";
import { Popup } from "../../toolbar/components/popup";
import { Icons } from "../../toolbar/icons";
import Languages from "./languages.json";
import { useThemeEngineStore } from "@notesnook/theme";
export function CodeblockComponent(props) {
    var _a;
    const { editor, updateAttributes, node, forwardRef } = props;
    const { language, indentLength, indentType, caretPosition } = node.attrs;
    // const [caretPosition, setCaretPosition] = useState<CaretPosition>();
    const elementRef = useRef();
    const [isOpen, setIsOpen] = useState(false);
    const toolbarRef = useRef(null);
    const theme = useThemeEngineStore((store) => store.theme);
    const { enabled, start } = useTimer(1000);
    const languageDefinition = Languages.find((l) => { var _a; return l.filename === language || ((_a = l.alias) === null || _a === void 0 ? void 0 : _a.some((a) => a === language)); });
    return (_jsxs(_Fragment, { children: [_jsxs(Flex, { sx: {
                    flexDirection: "column",
                    borderRadius: "default",
                    overflow: "hidden"
                }, children: [_jsx(Text, { ref: (ref) => {
                            elementRef.current = ref !== null && ref !== void 0 ? ref : undefined;
                            forwardRef === null || forwardRef === void 0 ? void 0 : forwardRef(ref);
                        }, autoCorrect: "off", autoCapitalize: "none", css: theme.codeBlockCSS, sx: {
                            pre: {
                                fontFamily: "inherit !important",
                                tabSize: "inherit !important",
                                // background: "transparent !important",
                                padding: "10px !important",
                                margin: "0px !important",
                                width: "100%",
                                borderRadius: `0px !important`,
                                "::selection,*::selection": {
                                    bg: "background-selected",
                                    color: "inherit"
                                },
                                "::-moz-selection,*::-moz-selection": {
                                    bg: "background-selected",
                                    color: "inherit"
                                }
                            },
                            fontFamily: "monospace",
                            whiteSpace: "pre", // TODO !important
                            tabSize: 1,
                            position: "relative",
                            lineHeight: "20px",
                            // bg: "var(--background-secondary)",
                            // color: "white",
                            overflowX: "hidden",
                            display: "flex"
                        }, spellCheck: false }), _jsxs(Flex, { ref: toolbarRef, contentEditable: false, sx: {
                            bg: "var(--background-secondary)",
                            alignItems: "center",
                            justifyContent: "flex-end",
                            borderTop: "1px solid var(--border-secondary)"
                        }, children: [caretPosition ? (_jsxs(Text, { variant: "subBody", sx: { mr: 1, mt: "2px" }, children: ["Line ", caretPosition.line, ", Column ", caretPosition.column, " ", caretPosition.selected
                                        ? `(${caretPosition.selected} selected)`
                                        : ""] })) : null, _jsx(Button, { variant: "icon", sx: {
                                    p: 1,
                                    opacity: "1 !important"
                                }, title: "Toggle indentation mode", disabled: !editor.isEditable, onClick: () => {
                                    if (!editor.isEditable)
                                        return;
                                    editor.commands.changeCodeBlockIndentation({
                                        type: indentType === "space" ? "tab" : "space",
                                        amount: indentLength
                                    });
                                }, children: _jsxs(Text, { variant: "subBody", children: [indentType === "space" ? "Spaces" : "Tabs", ": ", indentLength] }) }), _jsx(Button, { variant: "icon", sx: {
                                    opacity: "1 !important",
                                    p: 1,
                                    mr: 1,
                                    bg: isOpen ? "background-selected" : "transparent"
                                }, disabled: !editor.isEditable, onClick: () => {
                                    if (!editor.isEditable)
                                        return;
                                    setIsOpen(true);
                                }, title: "Change language", children: _jsx(Text, { variant: "subBody", spellCheck: false, children: (languageDefinition === null || languageDefinition === void 0 ? void 0 : languageDefinition.title) || "Plaintext" }) }), ((_a = node.textContent) === null || _a === void 0 ? void 0 : _a.length) > 0 ? (_jsx(Button, { variant: "icon", sx: {
                                    opacity: "1 !important",
                                    p: 1,
                                    mr: 1,
                                    bg: "transparent"
                                }, onClick: () => {
                                    var _a, _b, _c;
                                    (_b = (_a = editor.storage).copyToClipboard) === null || _b === void 0 ? void 0 : _b.call(_a, node.textContent, (_c = elementRef === null || elementRef === void 0 ? void 0 : elementRef.current) === null || _c === void 0 ? void 0 : _c.innerHTML);
                                    start();
                                }, title: "Copy to clipboard", children: _jsx(Text, { variant: "subBody", spellCheck: false, sx: { color: "codeFg" }, children: enabled ? "Copied!" : "Copy" }) })) : null] })] }), _jsx(ResponsivePresenter, { isOpen: isOpen, onClose: () => {
                    setIsOpen(false);
                    // NOTE: for some reason the language selection action sheet
                    // does not return focus to the last focused position after
                    // closing. We have to set focusOnRender=false & manually
                    // restore focus. I think this has something to do with custom
                    // node views.
                    // TRY: perhaps use SelectionBasedReactNodeView?
                    editor.commands.focus();
                }, focusOnRender: false, mobile: "sheet", desktop: "popup", position: {
                    target: toolbarRef.current || undefined,
                    align: "end",
                    isTargetAbsolute: true,
                    location: "top",
                    yOffset: 5
                }, title: "Select language", children: _jsx(LanguageSelector, { selectedLanguage: (languageDefinition === null || languageDefinition === void 0 ? void 0 : languageDefinition.filename) || "Plaintext", onLanguageSelected: (language) => {
                        updateAttributes({ language }, { addToHistory: true, preventUpdate: false });
                        setIsOpen(false);
                    }, onClose: () => setIsOpen(false) }) })] }));
}
function LanguageSelector(props) {
    const { onLanguageSelected, selectedLanguage, onClose } = props;
    const [languages, setLanguages] = useState(Languages);
    return (_jsx(Popup, { onClose: onClose, children: _jsxs(Flex, { sx: {
                flexDirection: "column",
                height: 200,
                width: ["auto", 300],
                bg: "background"
            }, children: [_jsx(Input, { autoFocus: true, placeholder: "Search languages", sx: {
                        width: "auto",
                        bg: "background",
                        mx: 2,
                        p: "7px",
                        zIndex: 999,
                        mt: 1
                    }, onChange: (e) => {
                        if (!e.target.value)
                            return setLanguages(Languages);
                        const query = e.target.value.toLowerCase();
                        setLanguages(Languages.filter((lang) => {
                            var _a;
                            return (lang.title.toLowerCase().indexOf(query) > -1 ||
                                ((_a = lang.alias) === null || _a === void 0 ? void 0 : _a.some((alias) => alias.toLowerCase().indexOf(query) > -1)));
                        }));
                    } }), _jsx(Flex, { sx: {
                        flexDirection: "column",
                        pt: 1,
                        mt: 1,
                        overflowY: "auto"
                    }, children: languages.map((lang) => (_jsxs(Button, { variant: "menuitem", sx: {
                            textAlign: "left",
                            py: 1,
                            display: "flex",
                            justifyContent: "space-between",
                            alignItems: "center"
                        }, onClick: () => onLanguageSelected(lang.filename), children: [_jsx(Text, { variant: "body", children: lang.title }), selectedLanguage === lang.filename ? (_jsx(Icon, { path: Icons.check, size: "small" })) : lang.alias ? (_jsx(Text, { variant: "subBody", sx: { fontSize: "10px" }, children: lang.alias.slice(0, 3).join(", ").toUpperCase() })) : null] }, lang.title))) })] }) }));
}
