import { App } from "antd";
import { runInAction } from "mobx";
import { observer } from "mobx-react";
import { useEffect, useState } from "react";

import { createCopy } from "@devowl-wp/multilingual";
import type { ListTcfVendorRowAttributes } from "@devowl-wp/react-cookie-banner-admin";
import { ListTcfVendor, useListTcfVendorProvider } from "@devowl-wp/react-cookie-banner-admin";

import { useTcfVendorAdNetworks } from "./vendorSelector.js";
import { useConfigHintText } from "../../../../hooks/useConfigHintText.js";
import { useRouteBlocker } from "../../../../hooks/useRouteBlocker.js";
import { useRouteTcfVendorConfiguration } from "../../../../hooks/useRouteTcfVendorConfiguration.js";
import { BlockerModel } from "../../../../models/blockerModel.js";
import { useStores } from "../../../../store/stores.js";
import { ConfigContent } from "../../content.js";

import type { FC } from "react";

const TcfVendorConfigurationList: FC = observer(() => {
    const { message } = App.useApp();
    const [fetched, setFetched] = useState(false);
    const { addLink, editLink } = useRouteTcfVendorConfiguration();
    const { addLink: addBlockerLink, editLink: editBlockerLink } = useRouteBlocker();
    const { tcfStore, optionStore } = useStores();
    const { vendorConfigurations, vendorConfigurationCount } = tcfStore;
    const { busy, entries } = vendorConfigurations;
    const hintText = useConfigHintText("tcf-vendor");
    const adNetworks = useTcfVendorAdNetworks();

    useEffect(() => {
        if (vendorConfigurationCount > 0 && !fetched) {
            tcfStore.fetchVendorConfigurations();
            setFetched(true);
        }
    }, [vendorConfigurationCount, fetched]);

    const [ListTcfVendorContextProvider, listTcfVendorContextValue] = useListTcfVendorProvider(
        {
            busy: busy,
            vendorCount: vendorConfigurationCount,
            adNetworks,
            rows: Array.from(entries.values()).map((vendorConfiguration) => {
                const {
                    key: id,
                    restrictivePurposes,
                    data: {
                        status,
                        meta: { vendorId },
                        blocker,
                        multilingual,
                    },
                } = vendorConfiguration;

                return {
                    busy: false,
                    configuration: {
                        id,
                        vendorId,
                        blocker,
                        restrictivePurposes,
                        status: status as ListTcfVendorRowAttributes["status"],
                    },
                    vendor: vendorConfiguration.vendorModel?.data,
                    languages: multilingual,
                    languageOnClick: async (recordId, { code, id }) => {
                        try {
                            const forwardId =
                                id === false ? (await createCopy("rcb-tcf-vendor-conf", recordId, code)).id : id;

                            // Open the newly created blocker
                            const url = new URL(window.location.href);
                            url.hash = `#/cookies/tcf-vendors/edit/${forwardId}`;
                            url.searchParams.set("lang", code);
                            window.location.href = url.toString();
                        } catch (e) {
                            if (e.responseJSON?.message) {
                                message.error(e.responseJSON.message);
                            } else {
                                throw e;
                            }
                        }
                    },
                };
            }),
            view: "vendor-configurations",
            onSwitchToVendorView: () => (window.location.hash = addLink),
            onEdit: (configuration) => (window.location.hash = editLink(entries.get(configuration.id))),
            onDelete: async (configuration) => {
                try {
                    await entries.get(configuration.id).delete({ force: true });
                } catch (e) {
                    message.error(e.responseJSON.message);
                }
            },
            onCreateOrEditContentBlocker: ({ id, blocker }, { name }) =>
                (window.location.hash = blocker
                    ? editBlockerLink(
                          new BlockerModel(undefined, {
                              id: blocker,
                          }),
                      )
                    : `${addBlockerLink}?force=scratch&attributes=${JSON.stringify({
                          name,
                          tcfVendors: [id],
                          criteria: "tcfVendors",
                      })}`),
            onBulkDelete: async (configurations, handleItemDone, signal, bulkDone) => {
                // Each TCF vendor deletion leads to fetching the current revision, suspend
                // this to avoid thousands of requests and do this after all vendors got deleted.
                for (const { id } of configurations) {
                    entries
                        .get(id)
                        .delete(
                            { force: true },
                            {
                                allowBatchRequest: {
                                    onQueueItemFinished: handleItemDone,
                                    waitForPromise: bulkDone,
                                },
                                settings: { signal },
                            },
                        )
                        .catch((e) => message.error(e.responseJSON.message));
                }

                await bulkDone;
                runInAction(() => {
                    for (const { id } of configurations) {
                        entries.delete(id);
                    }
                });
                optionStore.fetchCurrentRevision();
            },
        },
        {},
        {
            inherit: ["busy", "vendorCount", "rows"],
        },
    );

    return (
        <ConfigContent>
            <ListTcfVendorContextProvider value={listTcfVendorContextValue}>
                <ListTcfVendor />
            </ListTcfVendorContextProvider>
            <p className="description" style={{ maxWidth: 800, margin: "30px auto 0", textAlign: "center" }}>
                {hintText}
            </p>
        </ConfigContent>
    );
});

export { TcfVendorConfigurationList };
