import StyledWrapper from "@insite/client-framework/Common/StyledWrapper";
import { HasShellContext, withIsInShell } from "@insite/client-framework/Components/IsInShell";
import { getIsShareEntity } from "@insite/client-framework/ServerSideRendering";
import siteMessage from "@insite/client-framework/SiteMessage";
import translate from "@insite/client-framework/Translate";
import WidgetModule from "@insite/client-framework/Types/WidgetModule";
import WidgetProps from "@insite/client-framework/Types/WidgetProps";
import Typography, { TypographyPresentationProps } from "@insite/mobius/Typography";
import InjectableCss from "@insite/mobius/utilities/InjectableCss";
import merge from "lodash/merge";
import React, { useEffect, useRef, useState } from "react";
import { css } from "styled-components";

const enum fields {
    content = "content",
    excludeFromPdf = "excludeFromPdf",
}

interface OwnProps extends WidgetProps {
    fields: {
        [fields.content]: string;
        [fields.excludeFromPdf]: boolean;
    };
    extendedStyles?: CodeSnippetStyles;
}

type Props = OwnProps & HasShellContext;

export interface CodeSnippetStyles {
    wrapper?: InjectableCss;
    titleText?: TypographyPresentationProps;
    instructionText?: TypographyPresentationProps;
}

export const codeSnippetStyles: CodeSnippetStyles = {
    wrapper: {
        css: css`
            background: #e5e5e5;
            padding: 10px;
        `,
    },
    titleText: {
        variant: "h6",
        css: css`
            margin: 0;
        `,
    },
};

const CodeSnippet = ({ fields, shellContext, extendedStyles, id }: Props) => {
    const [styles] = useState(() => merge(codeSnippetStyles, extendedStyles));
    const wrapperRef = useRef<HTMLDivElement>(null);

    if (fields.excludeFromPdf && getIsShareEntity()) {
        return null;
    }

    useEffect(() => {
        if (wrapperRef.current) {
            const fragment = document.createRange().createContextualFragment(fields.content);
            wrapperRef.current.innerHTML = "";
            wrapperRef.current.appendChild(fragment);
        }
    }, []);

    return (
        <>
            {shellContext.isInShell && shellContext.isEditing && (
                <StyledWrapper {...styles.wrapper}>
                    <Typography {...styles.titleText}>{translate("Code Snippet")}</Typography>
                    <Typography {...styles.instructionText}>{siteMessage("CodeSnippet_Instruction")}</Typography>
                </StyledWrapper>
            )}
            {IS_SERVER_SIDE ? (
                // eslint-disable-next-line react/no-danger
                <div dangerouslySetInnerHTML={{ __html: fields.content }}></div>
            ) : (
                <div id={`snippet-wrapper_${id}`} ref={wrapperRef}></div>
            )}
        </>
    );
};

const widgetModule: WidgetModule = {
    component: withIsInShell(CodeSnippet),
    definition: {
        group: "Basic",
        canAdd: context => context.permissions?.canUseAdvancedFeatures || false,
        fieldDefinitions: [
            {
                name: fields.content,
                displayName: "Code",
                tooltip: "",
                editorTemplate: "CodeSnippetField",
                defaultValue: "",
                fieldType: "Contextual",
            },
            {
                name: fields.excludeFromPdf,
                displayName: "Exclude from PDF Generation",
                editorTemplate: "CheckboxField",
                defaultValue: false,
                fieldType: "General",
            },
        ],
    },
};

export default widgetModule;
