import { EyeOutlined, ReloadOutlined } from "@ant-design/icons";
import { Empty, Table, Tag, Tooltip } from "antd";
import { useCallback, useMemo } from "react";

import type { ITcfGvlDisclosure } from "@devowl-wp/api-real-cookie-banner";
import { ETcfGvlDisclosureType } from "@devowl-wp/api-real-cookie-banner";
import { getTcfCookieTypeLocalization } from "@devowl-wp/react-cookie-banner";
import { jsxJoin } from "@devowl-wp/react-utils";

import { FORM_TCF_VENDOR_FIELD_PURPOSES_COLUMN_NAME_WIDTH } from "./purposes.js";
import { useFormTcfVendor } from "../../../../contexts/formTcfVendor.js";
import { useI18n } from "../../../../contexts/i18n.js";
import { FormHeadline } from "../../headline.js";
import { FormLayoutTcfVendor } from "../../layout.js";

import type { FC } from "react";

const { Column } = Table;

const FormTcfVendorFieldDeviceStorage: FC = () => {
    const { __, _i, _n } = useI18n();

    const {
        vendor: {
            usesCookies,
            usesNonCookieAccess,
            cookieMaxAgeSeconds,
            cookieRefresh,
            deviceStorageDisclosureUrl,
            deviceStorageDisclosureViolation,
            deviceStorageDisclosure,
        },
        declarations: { purposes: allPurposes, specialPurposes: allSpecialPurposes },
    } = useFormTcfVendor();

    const useDeviceStorageDisclosure = useMemo(() => {
        const result = deviceStorageDisclosure?.disclosures.length ? [...deviceStorageDisclosure.disclosures] : [];

        // Include implicit device storage into table
        if (usesNonCookieAccess) {
            result.unshift({
                type: ETcfGvlDisclosureType.Web,
                identifier: "*",
                purposes: undefined,
                cookieRefresh: undefined,
                domain: "*",
                maxAgeSeconds: null,
            });
        }

        if (usesCookies) {
            result.unshift({
                type: ETcfGvlDisclosureType.Cookie,
                identifier: "*",
                purposes: undefined,
                cookieRefresh,
                domain: "*",
                maxAgeSeconds: cookieMaxAgeSeconds,
            });
        }

        return result;
    }, [usesNonCookieAccess, usesCookies, cookieMaxAgeSeconds, cookieRefresh, deviceStorageDisclosure]);

    const deviceStorageViolationMessage = useMemo(() => {
        switch (deviceStorageDisclosureViolation) {
            case "no-disclosures":
                return __("The vendor does not provide any device storage disclosures (cookie definitions).");
            case "disclosure-no-domains":
                return __("The vendor does not specify for one or multiple cookies for which domains they are valid.");
            case "disclosure-no-purposes":
                return __("The vendor does not specify the purpose for one or multiple cookies.");
            case "disclosure-no-cookie-refresh":
                return __("The vendor does not specify for one or multiple cookies if the cookie does refresh.");
            case "disclosure-no-max-age-seconds":
                return __("The vendor does not specify the age in seconds for one or multiple cookies.");
            case "disclosure-too-big":
                return __(
                    "The vendor provides device storage disclosures (cookie definitions) that are too large (> 256 kB), which would significantly slow down the loading of your website. Therefore, the device storage disclosures have been discarded. Please contact the vendor to resolve the issue!",
                );
            default:
                return __(
                    "The vendor provides a technically non-machine-readable variant of the device storage disclosures (cookie definitions), which differs significantly from the defined standard.",
                );
        }
    }, [deviceStorageDisclosureViolation]);

    const calculatePurposes = useCallback(
        (
            selectedPurposes: number[],
            purposes: typeof allPurposes | typeof allSpecialPurposes,
            renderText: (amount: number) => string,
        ) =>
            selectedPurposes.length ? (
                <Tooltip
                    title={
                        <ul style={{ margin: 0, padding: 0 }}>
                            {selectedPurposes.map((purposeId) => (
                                <li key={purposeId}>{purposes[purposeId].name}</li>
                            ))}
                        </ul>
                    }
                >
                    {renderText(selectedPurposes.length)}
                </Tooltip>
            ) : undefined,
        [allPurposes, allSpecialPurposes],
    );

    return (
        <>
            <FormHeadline
                offset={FormLayoutTcfVendor.labelCol.span}
                description={_i(
                    __(
                        "It should be specified all cookies, which are used by using a service of a TCF vendor. There are several types of cookies and that the {{aEprivacy}}ePrivacy Directive (Directive 2009/136/EC) Rectial 66{{/aEprivacy}} requires that you inform your visitors not only about (HTTP) cookies, but also about cookie-like information. This data, if specified, is given by the TCF Vendor and is not mutable. If the information is incomplete, you will need to contact the TCF vendor to request the information be completed.",
                    ),
                    {
                        aEprivacy: (
                            <a
                                href={__("https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=celex:32009L0136")}
                                target="_blank"
                                rel="noreferrer"
                            />
                        ),
                    },
                )}
            >
                {__("Device Storage Disclosure")} ({__("Technical cookie information")})
            </FormHeadline>
            {deviceStorageDisclosureViolation ? (
                <div className="notice notice-error inline below-h2 notice-alt" style={{ margin: "10px 0" }}>
                    <p>
                        {_i(
                            __(
                                'TCF vendors must disclose their cookies, among other things, in accordance with the {{a}}"Vendor Device Storage & Operational Disclosures"{{/a}} specification. However, this vendor fails to comply with the specification, so that the mandatory information for obtaining informed consent as defined by the GDPR cannot be read. You as a website operator can therefore not obtain valid consent for this vendor.',
                            ),
                            {
                                a: (
                                    <a
                                        href="https://github.com/InteractiveAdvertisingBureau/GDPR-Transparency-and-Consent-Framework/blob/7c79f48b033f783d98da922152430657097f5ab2/TCFv2/Vendor%20Device%20Storage%20&%20Operational%20Disclosures.md"
                                        target="_blank"
                                        rel="noreferrer"
                                    />
                                ),
                            },
                        )}
                    </p>
                    <p>
                        {_i(
                            __(
                                "You can find the vendor's faulty device storage disclosure at {{a}}%s{{/a}}. Please contact the vendor and ask for a standard compliant device disclosures!",
                                deviceStorageDisclosureUrl,
                            ),
                            {
                                a: <a href={deviceStorageDisclosureUrl} target="_blank" rel="noreferrer" />,
                            },
                        )}
                    </p>
                    <p>
                        <strong>{__("Problem:")}</strong> {deviceStorageViolationMessage}
                    </p>
                </div>
            ) : (
                <Table<ITcfGvlDisclosure>
                    locale={{
                        emptyText: (
                            <Empty description={__("This vendor does not provide any device storage disclosure.")} />
                        ),
                    }}
                    dataSource={useDeviceStorageDisclosure}
                    pagination={{
                        pageSize: 15,
                        showTotal: (total, range) => `${range[0]}-${range[1]} / ${total}`,
                        showSizeChanger: false,
                    }}
                    rowKey={({ identifier, type }) => `${type}${identifier}`}
                    size="small"
                    bordered
                >
                    <Column<ITcfGvlDisclosure>
                        width={FORM_TCF_VENDOR_FIELD_PURPOSES_COLUMN_NAME_WIDTH}
                        title={__("Cookie type")}
                        dataIndex="cookieType"
                        key="cookieType"
                        render={(_, { type }) => getTcfCookieTypeLocalization(type)}
                    />
                    <Column<ITcfGvlDisclosure>
                        title={`${__("Identifier")} / ${__("Description")}`}
                        dataIndex="identifier"
                        key="identifier"
                        render={(_, { identifier, description }) =>
                            identifier ? (
                                <>
                                    <code>{identifier}</code>
                                    {description && (
                                        <>
                                            <br />
                                            {description}
                                        </>
                                    )}
                                </>
                            ) : (
                                __("Not defined")
                            )
                        }
                    />
                    <Column<ITcfGvlDisclosure>
                        title={__("Domain")}
                        dataIndex="domain"
                        key="domain"
                        render={(_, { domains, domain }) =>
                            domains ? (
                                <code>{domains.join(",")}</code>
                            ) : domain ? (
                                <code>{domain}</code>
                            ) : (
                                __("Not defined")
                            )
                        }
                    />
                    <Column<ITcfGvlDisclosure>
                        title={__("Duration")}
                        dataIndex="duration"
                        key="duration"
                        render={(_, { maxAgeSeconds, cookieRefresh, optOut }) =>
                            maxAgeSeconds !== null ? (
                                <>
                                    {maxAgeSeconds <= 0 ? (
                                        <Tooltip title={__("This cookie is active as long as the session is active")}>
                                            <span>{__("Session")}</span>
                                        </Tooltip>
                                    ) : (
                                        <span>
                                            {maxAgeSeconds} {__("second(s)")}
                                        </span>
                                    )}
                                    {cookieRefresh && (
                                        <Tag icon={<ReloadOutlined />} style={{ marginLeft: 10 }}>
                                            {__("Refresh")}
                                        </Tag>
                                    )}
                                    {optOut && (
                                        <Tooltip
                                            title={__("Cookie can be set to store opt-out of the described behaviour.")}
                                        >
                                            <Tag icon={<EyeOutlined />} style={{ marginLeft: 10 }}>
                                                {__("Opt-out")}
                                            </Tag>
                                        </Tooltip>
                                    )}
                                </>
                            ) : (
                                __("Not defined")
                            )
                        }
                    />
                    <Column<ITcfGvlDisclosure>
                        title={__("Purposes")}
                        dataIndex="purposes"
                        key="purposes"
                        render={(_, { purposes = [], specialPurposes = [] }) => {
                            const calculatedPurposes = calculatePurposes(purposes, allPurposes, (amount) =>
                                _n("%d purpose", "%d purposes", amount, amount),
                            );
                            const calculatedSpecialPurposes = calculatePurposes(
                                specialPurposes,
                                allSpecialPurposes,
                                (amount) => _n("%d special purpose", "%d special purposes", amount, amount),
                            );

                            return calculatedPurposes || calculatedSpecialPurposes
                                ? jsxJoin([calculatedPurposes, calculatedSpecialPurposes], <span>, </span>)
                                : __("None");
                        }}
                    />
                </Table>
            )}
        </>
    );
};

export { FormTcfVendorFieldDeviceStorage };
