import { Divider, Spin } from "antd";
import { observer } from "mobx-react";
import { useCallback, useState } from "react";

import type { TemplateCenterCards } from "@devowl-wp/react-cookie-banner-admin";
import { ScannerCards } from "@devowl-wp/react-cookie-banner-admin";
import { yieldMainThread } from "@devowl-wp/react-utils";

import { ScannerTemplateCardActionOpenExternalUrlsTable } from "./templateCardActionOpenExternalUrlsTable.js";
import { useScannerProgress } from "../../../hooks/useScannerProgress.js";
import { useStores } from "../../../store/stores.js";
import { __ } from "../../../utils/i18n.js";
import { ConfigContent } from "../content.js";

import type { BlockerTemplate } from "../../../models/blockerTemplate.js";
import type { ComponentProps, FC } from "react";

const ScannerTemplateCards: FC = observer(() => {
    const [busy, setBusy] = useState(false);
    const {
        scannerStore,
        cookieStore,
        optionStore: { isTcf },
    } = useStores();
    const { sortedTemplates, resultTemplates, busyResultTemplates } = scannerStore;
    const { remaining } = useScannerProgress();
    const { essentialGroup } = cookieStore;
    const [hasModalOpen, setHasModalOpen] = useState(false);

    const handleSelect: ComponentProps<typeof TemplateCenterCards>["onSelect"] = useCallback(
        async (template) => {
            if (hasModalOpen || !template || busy) {
                return;
            }

            setBusy(true);

            const { identifier, isHidden, name } = template;
            const scannerResultModel = scannerStore.resultTemplates.get(identifier);
            const { type, templateModel } = scannerResultModel;

            // Always navigate back to the scanner results
            const navigateAfterCreation = `navigateAfterCreation=${encodeURIComponent("#scanner")}`;

            if (type === "service") {
                yieldMainThread().then(
                    () =>
                        (window.location.href = `#/cookies/${essentialGroup?.key}/new?force=${identifier}&${navigateAfterCreation}`),
                );
            } else {
                const blockerTemplateModel = templateModel as BlockerTemplate;
                await blockerTemplateModel.fetchUse();

                const {
                    use: {
                        consumerData: { serviceTemplates, createAdNetwork },
                    },
                } = blockerTemplateModel;

                const firstTemplate =
                    serviceTemplates.filter(
                        ({ identifier: blockerServiceTemplateIdentifier }) =>
                            blockerServiceTemplateIdentifier === identifier,
                    )[0] || serviceTemplates[0];

                // The blocker template has a services, so we can safely create a service for it
                let navigateTo = "";
                if (firstTemplate) {
                    if (!firstTemplate.consumerData.isCreated || isHidden) {
                        if (isHidden) {
                            // It is a hidden content blocker, so we can only create a service
                            navigateTo = `#/cookies/${essentialGroup?.key}/new?force=${identifier}&${navigateAfterCreation}`;
                        } else if (!firstTemplate.consumerData.isCreated) {
                            // Service does not exist -> directly navigate to the service and force content blocker to be created
                            navigateTo = `#/cookies/${essentialGroup?.key}/new?force=${
                                firstTemplate.identifier
                            }&attributes=${JSON.stringify({
                                createContentBlocker:
                                    firstTemplate.group?.toLowerCase() !== essentialGroup?.data.name.toLowerCase(),
                                createContentBlockerId: identifier,
                            })}&${navigateAfterCreation}`;
                        }
                    } else {
                        // Service already exists -> directly navigate to the content blocker
                        navigateTo = `#/blocker/new?force=${identifier}&${navigateAfterCreation}`;
                    }
                } else if (createAdNetwork) {
                    if (isTcf) {
                        // We need to create a TCF adsense network for this vendor
                        navigateTo = `#/cookies/tcf-vendors/new?adNetwork=${encodeURIComponent(createAdNetwork)}`;
                    } else {
                        // We first need to activate TCF
                        navigateTo = `#/settings/tcf?tcfIntegrationItem=${encodeURIComponent(
                            name,
                        )}&navigateAfterTcfActivation=${encodeURIComponent(
                            `#/cookies/tcf-vendors/new?adNetwork=${encodeURIComponent(createAdNetwork)}`,
                        )}`;
                    }
                }

                if (navigateTo) {
                    yieldMainThread().then(() => (window.location.href = navigateTo));
                }
            }

            setBusy(false);
        },
        [busy, hasModalOpen, essentialGroup],
    );

    return (
        <ConfigContent style={{ textAlign: "center" }}>
            <Divider>{__("Services, for which you should obtain consent")}</Divider>
            <Spin spinning={(busyResultTemplates && !remaining) || busy}>
                <ScannerCards
                    templates={sortedTemplates.map(({ data }) => data)}
                    onSelect={handleSelect}
                    dropdownItems={({ identifier, consumerData: { scan } }) => [
                        scan && {
                            key: "table",
                            label: (
                                <ScannerTemplateCardActionOpenExternalUrlsTable
                                    template={resultTemplates.get(identifier)}
                                    key="table"
                                    onVisibleChange={setHasModalOpen}
                                />
                            ),
                        },
                    ]}
                    onIgnoreToggle={(template, state) =>
                        scannerStore.resultTemplates.get(template.identifier).ignore(state)
                    }
                    isTcf={isTcf}
                />
            </Spin>
        </ConfigContent>
    );
});

export { ScannerTemplateCards };
