import { Fragment, useMemo } from "react";

import { findUsedGcmConsentTypes } from "@devowl-wp/cookie-consent-web-client";
import { yieldLazyLoad } from "@devowl-wp/react-utils";
import { extendBannerBodyStylesheet } from "@devowl-wp/web-cookie-banner";

import { BannerButtonList } from "./buttonList.js";
import { useBanner } from "../../../contexts/banner.js";
import { useBannerStylesheet } from "../../../hooks/banner/useBannerStylesheet.js";
import { useGroupItems } from "../../../hooks/common/useGroupItems.js";
import { useCommonTeachings } from "../../../hooks/common/useTeachings.js";
import { BodyDescription } from "../../common/body/description.js";
import { Group } from "../../common/groups/group.js";
import { BannerDottedGroupList } from "../groups/dottedGroupList.js";

import type { CSSProperties, FC, Ref } from "react";

const YieldBodyDescription = yieldLazyLoad(Promise.resolve(BodyDescription), "BodyDescription");

const BannerGroupList = yieldLazyLoad(
    import(/* webpackChunkName: "banner-lazy", webpackMode: "lazy-once" */ "../../banner/groups/list.js").then(
        ({ BannerGroupList }) => BannerGroupList,
    ),
);

const BannerTcfGroupList =
    process.env.IS_TCF === "1" &&
    yieldLazyLoad(
        import(/* webpackChunkName: "banner-lazy", webpackMode: "lazy-once" */ "../../banner/tcf/groups.js").then(
            ({ BannerTcfGroupList }) => BannerTcfGroupList,
        ),
    );

const BannerGcmGroupList =
    process.env.PLUGIN_CTX === "pro" &&
    yieldLazyLoad(
        import(/* webpackChunkName: "banner-lazy", webpackMode: "lazy-once" */ "../../banner/gcm/groups.js").then(
            ({ BannerGcmGroupList }) => BannerGcmGroupList,
        ),
    );

const BannerHistorySelect = yieldLazyLoad(
    import(/* webpackChunkName: "banner-lazy", webpackMode: "lazy-once" */ "../../banner/body/historySelect.js").then(
        ({ BannerHistorySelect }) => BannerHistorySelect,
    ),
);

const BANNER_GROUP_NON_STANDARD_STYLE: CSSProperties = { margin: "20px 0 10px 0" };

const BannerBody: FC<{
    leftSideContainerRef?: Ref<HTMLDivElement>;
    rightSideContainerRef?: Ref<HTMLDivElement>;
}> = ({ leftSideContainerRef, rightSideContainerRef }) => {
    const { a11yIds, Container, RightSide, LeftSide, BeforeFooter } = useBannerStylesheet().extend(
        ...extendBannerBodyStylesheet,
    );

    const banner = useBanner();
    const {
        tcf,
        isGcm,
        individualPrivacyOpen,
        activeAction,
        individualTexts: { postamble },
        i18n: { nonStandard, nonStandardDesc },
        groups,
        designVersion,
    } = banner;

    const services = useGroupItems();
    const teachings = useCommonTeachings({
        services,
        disableListServicesNotice: designVersion > 9 ? individualPrivacyOpen : false,
    });
    const hasUsedGcmConsentTypes = isGcm && findUsedGcmConsentTypes(services).length > 0;

    const hasMoreThanOneStandard = useMemo(
        () => !!((process.env.IS_TCF === "1" && tcf) || (process.env.PLUGIN_CTX === "pro" && hasUsedGcmConsentTypes)),
        [tcf, hasUsedGcmConsentTypes],
    );

    const leftSideContainer = (
        <LeftSide key="leftSide" ref={leftSideContainerRef}>
            <YieldBodyDescription id={a11yIds.description} {...(groups.length > 0 ? teachings : {})}>
                {activeAction === "history" && <BannerHistorySelect />}
            </YieldBodyDescription>
            {groups.length > 0 && (
                <Fragment>
                    {individualPrivacyOpen ? (
                        <Fragment>
                            {hasMoreThanOneStandard && (
                                <Group headline={nonStandard} style={BANNER_GROUP_NON_STANDARD_STYLE} borderless>
                                    {nonStandardDesc}
                                </Group>
                            )}
                            <BannerGroupList />
                            {[
                                process.env.IS_TCF === "1" && tcf && <BannerTcfGroupList key="tcf" />,
                                process.env.PLUGIN_CTX === "pro" && hasUsedGcmConsentTypes && (
                                    <BannerGcmGroupList key="gcm" />
                                ),
                            ]
                                .filter(Boolean)
                                .sort(() => (designVersion < 10 ? 1 : -1))}
                        </Fragment>
                    ) : (
                        <BannerDottedGroupList />
                    )}
                    {!!postamble && individualPrivacyOpen && (
                        <YieldBodyDescription teachings={[postamble]} isPostamble />
                    )}
                </Fragment>
            )}
        </LeftSide>
    );

    const rightSideContainer =
        activeAction === "history" ? (
            <div ref={rightSideContainerRef} />
        ) : (
            <RightSide key="rightSide" ref={rightSideContainerRef}>
                <BannerButtonList />
            </RightSide>
        );

    return (
        <Container>
            <div>
                {individualPrivacyOpen
                    ? [rightSideContainer, leftSideContainer]
                    : [leftSideContainer, rightSideContainer]}
            </div>
            <BeforeFooter />
        </Container>
    );
};

export { BannerBody, BANNER_GROUP_NON_STANDARD_STYLE };
