import { App, Form, Skeleton, Spin } from "antd";
import { observer } from "mobx-react";
import { useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";

import type { EServiceTemplateDataProcessingInCountriesSpecialTreatment } from "@devowl-wp/api-real-cookie-banner";
import {
    FormServiceLayout,
    FormTcfVendor,
    useFormTcfVendorHandler,
    useFormTcfVendorProvider,
} from "@devowl-wp/react-cookie-banner-admin";
import type { FormTcfVendorValueProps } from "@devowl-wp/react-cookie-banner-admin";
import { scrollTo } from "@devowl-wp/react-utils";

import { useRouteTcfVendorConfiguration } from "../../../../hooks/useRouteTcfVendorConfiguration.js";
import { TcfVendorConfigurationModel } from "../../../../models/tcfVendorConfigurationModel.js";
import { useStores } from "../../../../store/stores.js";
import { ConfigContent } from "../../content.js";

import type { TcfVendor } from "../../../../models/tcfVendor.js";
import type { FC } from "react";

const TcfVendorConfigurationForm: FC<{
    vendor?: TcfVendor;
    navigateAfterCreation?: boolean;
    scrollToTop?: boolean;
    onCreated?: (model: TcfVendorConfigurationModel) => void;
}> = observer(({ vendor, navigateAfterCreation = true, scrollToTop = true, onCreated }) => {
    const { message } = App.useApp();
    const { vendorConfiguration, id, queried, fetched, link } = useRouteTcfVendorConfiguration();
    const navigate = useNavigate();
    const {
        tcfStore,
        optionStore: {
            territorialLegalBasis,
            others: {
                iso3166OneAlpha2,
                frontend: { predefinedDataProcessingInSafeCountriesLists },
            },
        },
    } = useStores();
    const { vendorConfigurations, declarations } = tcfStore;
    const [useVendor, setUseVendor] = useState(vendor);

    const {
        prompt,
        form,
        isBusy,
        defaultValues,
        overrideValues,
        onFinish,
        onFinishFailed,
        onValuesChange,
        contextValue,
    } = useFormTcfVendorHandler({
        isEdit: fetched,
        handleSave: async (values) => {
            const {
                status,
                restrictivePurposes = { normal: {} },
                dataProcessingInCountries,
                dataProcessingInCountriesSpecialTreatments,
                ...meta
            } = values;

            try {
                const newMeta = {
                    ...meta,
                    vendorId: useVendor.data.id,
                    restrictivePurposes: JSON.stringify(restrictivePurposes),
                    dataProcessingInCountries: JSON.stringify(dataProcessingInCountries),
                    dataProcessingInCountriesSpecialTreatments: JSON.stringify(
                        dataProcessingInCountriesSpecialTreatments,
                    ),
                };

                delete newMeta.templateCheck;

                if (queried) {
                    vendorConfiguration.setStatus(status);
                    vendorConfiguration.setMeta(newMeta);
                    await vendorConfiguration.patch();
                } else {
                    const draft = new TcfVendorConfigurationModel(vendorConfigurations, {
                        status,
                        meta: {
                            ...newMeta,
                        },
                    });
                    await draft.persist();
                    onCreated?.(draft);
                }

                return () => navigateAfterCreation && navigate(link.slice(1));
            } catch (e) {
                message.error(e.responseJSON.message);
                throw e;
            }
        },
        declarations,
        vendor: useVendor?.data,
    });

    const initialValues: FormTcfVendorValueProps = overrideValues(
        fetched
            ? {
                  status: vendorConfiguration.data.status as FormTcfVendorValueProps["status"],
                  restrictivePurposes: JSON.parse(
                      JSON.stringify(vendorConfiguration.restrictivePurposes),
                  ) as typeof vendorConfiguration.restrictivePurposes,
                  dataProcessingInCountries: JSON.parse(
                      JSON.stringify(vendorConfiguration.dataProcessingInCountries),
                  ) as string[],
                  dataProcessingInCountriesSpecialTreatments: JSON.parse(
                      JSON.stringify(vendorConfiguration.dataProcessingInCountriesSpecialTreatments),
                  ) as EServiceTemplateDataProcessingInCountriesSpecialTreatment[],
                  templateCheck: true,
              }
            : defaultValues,
    );

    useEffect(() => {
        if (vendorConfiguration.vendorModel) {
            setUseVendor(vendorConfiguration.vendorModel);
        }
    }, [vendorConfiguration]);

    // Initially load the vendor configuration if not yet done
    useEffect(() => {
        if (queried && !fetched) {
            vendorConfigurations.getSingle({
                params: {
                    id,
                    context: "edit",
                },
            });
        }
    }, [queried, fetched]);

    // Scroll to top when opening the form
    useEffect(() => {
        if (scrollToTop) {
            scrollTo(0);
        }
    }, []);

    const notReady = (queried && !fetched) || !useVendor || !declarations;
    const [FormTcfVendorContextProvider, formTcfVendorContextValue] = useFormTcfVendorProvider(
        {
            ...contextValue,
            territorialLegalBasis,
            iso3166OneAlpha2,
            predefinedDataProcessingInSafeCountriesLists,
        },
        {},
        { inherit: ["vendor"], deps: [notReady] },
    );

    if (notReady) {
        return (
            <ConfigContent maxWidth="fixed">
                <Skeleton active paragraph={{ rows: 8 }} />
            </ConfigContent>
        );
    }

    return (
        <ConfigContent maxWidth="fixed">
            <FormTcfVendorContextProvider value={formTcfVendorContextValue}>
                <Spin spinning={isBusy}>
                    {prompt}
                    <Form
                        name={`tcf-vendor-${id}`}
                        form={form}
                        {...FormServiceLayout}
                        initialValues={initialValues}
                        onFinish={onFinish}
                        onFinishFailed={onFinishFailed}
                        onValuesChange={onValuesChange}
                        scrollToFirstError={{ behavior: "smooth", block: "center" }}
                        labelWrap
                    >
                        <FormTcfVendor />
                    </Form>
                </Spin>
            </FormTcfVendorContextProvider>
        </ConfigContent>
    );
});

export { TcfVendorConfigurationForm };
