import { TCmsSettings, TPageCmsProps } from '@cromwell/core';
import createEmotionServer from '@emotion/server/create-instance';
import Document, { DocumentContext, Head, Html, Main, NextScript } from 'next/document';
import React from 'react';

import { createEmotionCache } from '../helpers/createEmotionCache';
import { getTheme } from '../helpers/theme';

export default class BlogDocument extends Document {

    static async getInitialProps(ctx: DocumentContext) {
        const originalRenderPage = ctx.renderPage;
        const cache = createEmotionCache();
        const { extractCriticalToChunks } = createEmotionServer(cache);
        ctx.renderPage = () =>
            originalRenderPage({
                enhanceApp: (App: any) => (props) => <App emotionCache={cache} {...props} />,
            })

        const initialProps = await Document.getInitialProps(ctx);
        // This is important. It prevents emotion to render invalid HTML.
        // See https://github.com/mui-org/material-ui/issues/26561#issuecomment-855286153
        const emotionStyles = extractCriticalToChunks(initialProps.html);
        const emotionStyleTags = emotionStyles.styles.map((style) => (
            <style
                data-emotion={`${style.key} ${style.ids.join(' ')}`}
                key={style.key}
                dangerouslySetInnerHTML={{ __html: style.css }}
            />
        ));

        return {
            ...initialProps,
            // Styles fragment is rendered after the app and page rendering finish.
            styles: [...React.Children.toArray(initialProps.styles), ...emotionStyleTags],
        }
    }


    render() {
        const pageProps: TPageCmsProps | undefined = this.props.__NEXT_DATA__.props?.pageProps?.cmsProps;
        const theme = getTheme(pageProps?.palette);
        const cmsSettings: TCmsSettings = this.props.__NEXT_DATA__.props?.pageProps?.cmsSettings;
        return (
            <Html lang={cmsSettings?.language ?? 'en'}>
                <Head>
                    <meta name="theme-color" content={theme.palette.primary.main} />
                </Head>
                <body>
                    <Main />
                    <NextScript />
                </body>
            </Html>
        )
    }

}