<script>
    import BlocksRegion from './BlocksRegion.svelte';
    import FooterInlineBlocksRegion from './FooterInlineBlocksRegion.svelte';
    import Menu from './Menu.svelte';
    import FilterUI from './blocks/FilterUI.svelte';
    import get from '@datawrapper/shared/get.js';
    import purifyHtml from '@datawrapper/shared/purifyHtml.js';

    import {
        aboveFooterStyles,
        belowFooterStyles,
        belowHeaderStyles,
        chartFooterStyles,
        chartHeaderStyles,
        chartStyles
    } from './themeStyles.js';

    export let container;

    export let allBlocks;
    export let allowedAriaDescriptionTags;
    export let ariaDescription;
    export let chart;
    export let chartAfterBodyHTML;
    export let emotion;
    export let filterUI;
    export let isIframe;
    export let renderFlags;
    export let textDirection;
    export let theme;
    export let themeData;
    export let vis;

    $: isStylePlain = renderFlags.plain;
    $: isStyleStatic = renderFlags.static;

    function byPriority(a, b) {
        return (
            (a.priority !== undefined ? a.priority : 999) -
            (b.priority !== undefined ? b.priority : 999)
        );
    }

    // build all the region
    $: regions = {
        header: getBlocks(allBlocks, 'header', { chart, themeData: $themeData, isStyleStatic }),
        headerRight: getBlocks(allBlocks, 'headerRight', {
            chart,
            themeData: $themeData,
            isStyleStatic
        }),
        belowHeader: getBlocks(allBlocks, 'belowHeader', {
            chart,
            themeData: $themeData,
            isStyleStatic
        }),
        aboveFooter: getBlocks(allBlocks, 'aboveFooter', {
            chart,
            themeData: $themeData,
            isStyleStatic
        }),
        plainFooter: getBlocks(allBlocks, 'plainFooter', {
            chart,
            themeData: $themeData,
            flags: renderFlags
        }),
        footerLeft: getBlocks(allBlocks, 'footerLeft', {
            chart,
            themeData: $themeData,
            isStyleStatic
        }),
        footerCenter: getBlocks(allBlocks, 'footerCenter', {
            chart,
            themeData: $themeData,
            isStyleStatic
        }),
        footerRight: getBlocks(allBlocks, 'footerRight', {
            chart,
            themeData: $themeData,
            isStyleStatic
        }),
        belowFooter: getBlocks(allBlocks, 'belowFooter', {
            chart,
            themeData: $themeData,
            isStyleStatic
        }),
        afterBody: getBlocks(allBlocks, 'afterBody', {
            chart,
            themeData: $themeData,
            isStyleStatic
        }),
        menu: getBlocks(allBlocks, 'menu', { chart, themeData: $themeData, isStyleStatic })
    };

    $: menu = get($themeData, 'options.menu', {});

    function getBlocks(allBlocks, region, props) {
        return allBlocks
            .filter(d => d.region === region)
            .filter(d => !d.test || d.test({ ...d.props, ...props }))
            .filter(d => (d.visible !== undefined ? d.visible : true))
            .sort(byPriority);
    }

    export let contentBelowChart;
    $: contentBelowChart = isStylePlain
        ? regions.plainFooter.length
        : regions.aboveFooter.length ||
          regions.footerLeft.length ||
          regions.footerCenter.length ||
          regions.footerRight.length ||
          regions.belowFooter.length ||
          regions.afterBody.length;

    $: footerRegionLayout = {
        Left: get($themeData, 'options.footer.left.layout', 'inline'),
        Center: get($themeData, 'options.footer.center.layout', 'inline'),
        Right: get($themeData, 'options.footer.right.layout', 'inline')
    };
</script>

<style lang="scss">
    :global(.dw-chart-header) {
        min-height: 1px;
        position: relative;
        overflow: auto;

        .header-right {
            position: absolute;
            right: 10px;
            z-index: 20;
        }

        &.has-header-right {
            display: flex;
            justify-content: space-between;

            &.has-menu > :last-child {
                margin-right: 25px;
            }
        }
    }

    :global(.chart.dir-rtl) {
        :global(.dw-chart-header),
        :global(.dw-below-header),
        :global(.dw-above-footer),
        :global(.dw-below-footer),
        .dw-chart-footer {
            direction: rtl;
            unicode-bidi: embed;
        }
    }

    .dw-chart-footer {
        display: flex;
        justify-content: space-between;
    }

    :global(.dw-above-footer),
    :global(.dw-below-footer) {
        position: relative;
    }

    // static style (make links look like normal text)
    .static :global(a) {
        pointer-events: none;
        color: currentColor;
        text-decoration: none;
        font-weight: unset;
        font-style: unset;
    }

    :global(.chart.vis-height-fit) {
        overflow: hidden;
        .dw-chart-styles {
            overflow: hidden;
        }
    }

    .dw-after-body {
        position: absolute;
        left: 0;
        top: 0;
        height: 0 !important;
    }
</style>

<div
    bind:this={container}
    class:static={isStyleStatic}
    class="dw-chart-styles {emotion
        ? chartStyles(emotion, $themeData, isStyleStatic, isIframe)
        : ''}"
>
    {#if !isStylePlain}
        {#if !regions.headerRight.length}
            <BlocksRegion
                name="dw-chart-header"
                blocks={regions.header}
                id="header"
                {emotion}
                styles={chartHeaderStyles}
            />
        {:else}
            <div
                class="dw-chart-header has-header-right {emotion
                    ? chartHeaderStyles(emotion, $themeData)
                    : ''}"
                class:has-menu={!isStyleStatic && regions.menu.length}
            >
                <BlocksRegion
                    name="dw-chart-header-left"
                    {emotion}
                    blocks={regions.header}
                    id="header"
                />
                <BlocksRegion name="dw-chart-header-right" {emotion} blocks={regions.headerRight} />
            </div>
        {/if}

        <BlocksRegion
            name="dw-below-header"
            blocks={regions.belowHeader}
            {emotion}
            styles={belowHeaderStyles}
        />

        {#if !isStyleStatic}
            <Menu name="dw-chart-menu" props={menu} blocks={regions.menu} {emotion} />
        {/if}
    {/if}

    {#if filterUI && !isStyleStatic}
        <div class={emotion ? belowHeaderStyles(emotion, $themeData) : ''}>
            <svelte:component this={FilterUI} {...filterUI} {vis} {textDirection} />
        </div>
    {/if}

    {#if ariaDescription}
        <div class="sr-only">
            {@html purifyHtml(ariaDescription, allowedAriaDescriptionTags)}
        </div>
    {/if}

    <slot {contentBelowChart} />

    {#if isIframe && get(theme, 'data.template.afterChart')}
        <!-- we can only allow this arbitrary HTML injection in iframe embeds -->
        {@html theme.data.template.afterChart}
    {/if}

    {#if !isStylePlain}
        <BlocksRegion
            name="dw-above-footer"
            blocks={regions.aboveFooter}
            {emotion}
            styles={aboveFooterStyles}
        />

        <div
            id="footer"
            class="dw-chart-footer {emotion
                ? chartFooterStyles(emotion, $themeData, isStyleStatic)
                : ''}"
        >
            {#each ['Left', 'Center', 'Right'] as orientation}
                <FooterInlineBlocksRegion
                    alignment={orientation.toLowerCase()}
                    blocks={regions['footer' + orientation]}
                    layout={footerRegionLayout[orientation]}
                    {emotion}
                />
            {/each}
        </div>

        <BlocksRegion
            name="dw-below-footer"
            blocks={regions.belowFooter}
            {emotion}
            styles={belowFooterStyles}
        />
    {:else if regions.plainFooter.length}
        <div
            id="footer"
            class="dw-chart-footer {emotion
                ? chartFooterStyles(emotion, $themeData, isStyleStatic)
                : ''}"
        >
            <FooterInlineBlocksRegion
                alignment="left"
                blocks={regions.plainFooter}
                layout={footerRegionLayout.Left}
                {emotion}
            />
        </div>
    {/if}

    <div class="dw-after-body" style="position:absolute; height:0">
        {#each regions.afterBody as block}
            <svelte:component this={block.component} props={block.props} />
        {/each}
    </div>

    {#if chartAfterBodyHTML}
        {@html chartAfterBodyHTML}
    {/if}
</div>
