import type { ClientBlockerTemplate, ClientServiceTemplate } from "@devowl-wp/service-cloud-consumer";

import { useFormHandler } from "./useFormHandler.js";
import { useI18n } from "../contexts/i18n.js";

import type { FormContentBlockerContext } from "../contexts/formContentBlocker.js";
import type { FormContentBlockerValueProps } from "../types/formContentBlocker.js";

function formContentBlockerAttributesFromTemplate(template: ClientBlockerTemplate["use"]) {
    const result: Partial<FormContentBlockerValueProps> = {
        name: template?.name,
        description: template?.description,
        rules: template?.consumerData.rules.join("\n"),
        services: template?.consumerData.serviceTemplates.map(({ consumerData: { id } }) => id).filter(Boolean),
        tcfVendors: template?.consumerData.tcfVendorConfigurations
            .map(({ vendorConfigurationId }) => (vendorConfigurationId === false ? undefined : vendorConfigurationId))
            .filter(Boolean),
        isVisual: template?.isVisual,
        visualType: template?.visualType,
        visualContentType: template?.visualContentType,
        isVisualDarkMode: template?.isVisualDarkMode,
        visualBlur: template?.visualBlur,
        visualHeroButtonText: template?.visualHeroButtonText,
        shouldForceToShowVisual: template?.shouldForceToShowVisual,
    };

    // Remove undefined and nulled values as the result of this function should only contain
    // real values so it can be used e.g. with `Object.assign`.
    for (const key in result) {
        if (result[key] === undefined || result[key] === null) {
            delete result[key];
        }
    }

    return result;
}

type UseFormHandler = typeof useFormHandler<FormContentBlockerValueProps, ClientBlockerTemplate["use"]>;

function useFormContentBlockerHandler(
    opts: {
        isTcf: boolean;
    } & Omit<Parameters<UseFormHandler>[0], "defaultValues" | "i18n">,
): ReturnType<UseFormHandler> & {
    nonExistingServices: ClientServiceTemplate["use"][];
    nonExistingTcfVendors: ClientBlockerTemplate["use"]["consumerData"]["tcfVendorConfigurations"];
    contextValue: Partial<FormContentBlockerContext["contextValue"]>;
} {
    const { __ } = useI18n();
    const { isTcf, isEdit, template, attributes } = opts;
    const defaultValues: FormContentBlockerValueProps = {
        name: "",
        status: "publish",
        description: "",
        rules: "",
        criteria: isTcf && template?.tcfVendorIds.length ? "tcfVendors" : "services",
        tcfVendors: attributes?.tcfVendors?.filter(Number) || [],
        // Always add "Store and/or access information on a device" as this is the most-friendly option
        // to the website operator, which covers not to load the embedded content without consent
        tcfPurposes: attributes?.tcfPurposes?.filter(Number) || [1],
        services: [],
        isVisual: true,
        visualType: "default",
        visualMediaThumbnail: 0,
        visualContentType: "generic",
        isVisualDarkMode: false,
        visualBlur: 0,
        visualDownloadThumbnail: undefined,
        visualHeroButtonText: "",
        shouldForceToShowVisual: false,
        templateCheck: !template,
        succeessorDeletionCheck: template?.consumerData.successorOf.length > 0 && !isEdit,
        ...formContentBlockerAttributesFromTemplate(template),
        ...(attributes || {}),
    };

    const handlers = useFormHandler<FormContentBlockerValueProps, ClientBlockerTemplate["use"]>({
        ...opts,
        defaultValues,
        i18n: {
            successMessage: __("You have successfully saved the content blocker."),
            validationError: __("The content blocker could not be saved due to missing/invalid form values."),
            unloadConfirm: __("You have unsaved changes. If you leave this page, your changes will be discarded."),
            unloadConfirmInitialActive: __(
                "You have already created a service. Are you sure that you don't want to create the corresponding content blocker?",
            ),
        },
    });
    const { isTemplateUpdate, templateCheck } = handlers;

    // Find non-existing services and show a warning
    const nonExistingServices =
        template?.consumerData.serviceTemplates.filter(({ consumerData: { isCreated } }) => !isCreated) || [];

    // Find non-existing TCF vendors and show a warning
    const nonExistingTcfVendors =
        template?.consumerData.tcfVendorConfigurations.filter(
            ({ vendorConfigurationId }) => vendorConfigurationId === false,
        ) || [];

    return {
        ...handlers,
        template,
        nonExistingServices,
        nonExistingTcfVendors,
        contextValue: {
            isTcf,
            isEdit,
            template,
            isTemplateUpdate,
            templateCheck,
            defaultTemplateValues: template ? defaultValues : {},
        },
    };
}

export { useFormContentBlockerHandler, formContentBlockerAttributesFromTemplate };
