import { CheckCircleFilled, DeleteOutlined, EditOutlined, PlusOutlined, WarningOutlined } from "@ant-design/icons";
import { App, Checkbox, Form, Input, Select, Tooltip } from "antd";
import { useEffect, useState } from "react";

import { copyToClipboard, yieldMainThread } from "@devowl-wp/react-utils";

import { FormSettingsGeneralCreateCookiePolicyPageButton } from "./general.js";
import { useFormSettings } from "../../../contexts/formSettings.js";
import { useI18n } from "../../../contexts/i18n.js";
import { useDndSortable } from "../../../hooks/useDndSortable.js";
import { useNavLinksPageTypes } from "../../../hooks/useNavLinksPageTypes.js";
import { ListMultilingualLanguages } from "../../common/listMultilingualLanguages.js";

import type { FormSettingsGeneralPagePrivacyPolicyMentionUsageStatus } from "./general.js";
import type { FormSettingsValueProps, FormSettingsValuePropsNavItem } from "../../../types/formSettings.js";
import type { FC } from "react";

const FormSettingsFieldNavLinkLayout = {
    labelCol: { span: 0 },
    wrapperCol: { span: 24 },
    style: { margin: 0 },
};

const FormSettingsGeneralNavTable: FC = () => {
    const { message } = App.useApp();
    const { _i, __, _x } = useI18n();
    const {
        renderPageSelector: RenderPageSelector,
        onHasPrivacyPolicyRCBSentenceChanged,
        onPageEditClick,
    } = useFormSettings();

    const { DragHandle, SortableContext, SortableRow } = useDndSortable();

    const [hasPrivacyPolicyRCBSentence, setHasPrivacyPolicyRCBSentence] =
        useState<FormSettingsGeneralPagePrivacyPolicyMentionUsageStatus>("unset");
    const [fullyLeakPrivacyPolicyText, setFullyLeakPrivacyPolicyText] = useState(false);

    useEffect(() => {
        if (hasPrivacyPolicyRCBSentence !== "unset") {
            onHasPrivacyPolicyRCBSentenceChanged?.(hasPrivacyPolicyRCBSentence === "in-text");
        }
    }, [hasPrivacyPolicyRCBSentence]);

    const availablePageTypes = useNavLinksPageTypes();

    return (
        <Form.Item<FormSettingsValueProps>
            noStyle
            shouldUpdate={(prevValues, nextValues) =>
                prevValues.navLinks.length !== nextValues.navLinks.length ||
                prevValues.isBannerLessConsent !== nextValues.isBannerLessConsent
            }
        >
            {({ getFieldValue }) => (
                <Form.List name="navLinks">
                    {(fields, { add, remove, move }) => (
                        <table className="wp-list-table widefat fixed striped table-view-list">
                            <thead>
                                <tr>
                                    <td width={45} align="right">
                                        &nbsp;
                                    </td>
                                    <td width={200}>{__("Type")}</td>
                                    <td width={300}>{__("Link")}</td>
                                    <td width={200}>{__("Link text")}</td>
                                    <td width={70} align="right">
                                        &nbsp;
                                    </td>
                                </tr>
                            </thead>
                            <tbody>
                                <SortableContext
                                    items={fields.map(({ key }) => `${key}`)}
                                    onDragEnd={({ active, over }) => {
                                        const from = fields.findIndex((field) => field.key === +active.id);
                                        const to = fields.findIndex((field) => field.key === +over?.id);
                                        move(from, to);
                                    }}
                                >
                                    {fields.length === 0 && (
                                        <td colSpan={5} style={{ textAlign: "center" }}>
                                            {__("No links are displayed in the footer.")}
                                        </td>
                                    )}
                                    {fields.map((field) => (
                                        <SortableRow key={field.key} data-row-key={`${field.key}`}>
                                            <td>{fields.length > 1 && <DragHandle />}</td>
                                            <td>
                                                <Form.Item<FormSettingsValueProps["navLinks"]>
                                                    name={[field.name, "id"]}
                                                    noStyle
                                                >
                                                    <Input type="hidden" />
                                                </Form.Item>
                                                <Form.Item<FormSettingsValueProps>
                                                    noStyle
                                                    shouldUpdate={(
                                                        { navLinks: prevValues },
                                                        { navLinks: nextValues },
                                                    ) =>
                                                        prevValues.map(({ pageType }) => pageType).join(",") !==
                                                        nextValues.map(({ pageType }) => pageType).join(",")
                                                    }
                                                >
                                                    {({ getFieldValue }) => {
                                                        const pageTypes = (
                                                            getFieldValue("navLinks") as FormSettingsValuePropsNavItem[]
                                                        )
                                                            .map(
                                                                ({ pageType }, index) =>
                                                                    index !== field.name && pageType,
                                                            )
                                                            .filter(Boolean);

                                                        return (
                                                            <Form.Item<FormSettingsValueProps["navLinks"]>
                                                                name={[field.name, "pageType"]}
                                                                noStyle
                                                            >
                                                                <Select>
                                                                    {availablePageTypes.map(
                                                                        ({ label, multiple, name }) => (
                                                                            <Select.Option
                                                                                value={name}
                                                                                key={name}
                                                                                disabled={
                                                                                    multiple
                                                                                        ? false
                                                                                        : pageTypes.indexOf(
                                                                                              name as any,
                                                                                          ) > -1
                                                                                }
                                                                            >
                                                                                {label}
                                                                            </Select.Option>
                                                                        ),
                                                                    )}
                                                                </Select>
                                                            </Form.Item>
                                                        );
                                                    }}
                                                </Form.Item>
                                                <div>
                                                    <Form.Item<FormSettingsValueProps["navLinks"]>
                                                        name={[field.name, "isExternalUrl"]}
                                                        noStyle
                                                        valuePropName="checked"
                                                    >
                                                        <Checkbox>{__("Use external URL")}</Checkbox>
                                                    </Form.Item>
                                                </div>
                                            </td>
                                            <td>
                                                <Form.Item<FormSettingsValueProps>
                                                    noStyle
                                                    shouldUpdate={(
                                                        {
                                                            navLinks: { [field.name]: prevValues },
                                                            cookiePolicyId: cookiePolicyIdA,
                                                        },
                                                        {
                                                            navLinks: { [field.name]: nextValues },
                                                            cookiePolicyId: cookiePolicyIdB,
                                                        },
                                                    ) =>
                                                        prevValues?.isExternalUrl !== nextValues?.isExternalUrl ||
                                                        prevValues?.pageType !== nextValues?.pageType ||
                                                        prevValues?.pageId !== nextValues?.pageId ||
                                                        prevValues?.isTargetBlank !== nextValues?.isTargetBlank ||
                                                        cookiePolicyIdA !== cookiePolicyIdB
                                                    }
                                                >
                                                    {({ getFieldValue }) => {
                                                        const row = getFieldValue([
                                                            "navLinks",
                                                            field.name,
                                                        ]) as FormSettingsValueProps["navLinks"][0];

                                                        // For some reason when "Deactivate" the cookie policy page, this gets `undefined`
                                                        if (!row) {
                                                            return null;
                                                        }

                                                        const { isExternalUrl, pageType, pageId, languages } = row;
                                                        const cookiePolicyId = getFieldValue(
                                                            "cookiePolicyId",
                                                        ) as FormSettingsValueProps["cookiePolicyId"];
                                                        const isBannerLessConsent = getFieldValue(
                                                            "isBannerLessConsent",
                                                        ) as FormSettingsValueProps["isBannerLessConsent"];

                                                        return (
                                                            <>
                                                                {isExternalUrl ? (
                                                                    <Form.Item<FormSettingsValueProps["navLinks"]>
                                                                        {...FormSettingsFieldNavLinkLayout}
                                                                        name={[field.name, "externalUrl"]}
                                                                        rules={[
                                                                            {
                                                                                type: "url",
                                                                                message:
                                                                                    __("Please enter a valid URL!"),
                                                                            },
                                                                        ]}
                                                                    >
                                                                        <Input placeholder="https://example.com/..." />
                                                                    </Form.Item>
                                                                ) : (
                                                                    <>
                                                                        <Form.Item<FormSettingsValueProps["navLinks"]>
                                                                            name={[field.name, "pageId"]}
                                                                            noStyle
                                                                        >
                                                                            <RenderPageSelector
                                                                                id="navTablePageId"
                                                                                multiple={false}
                                                                                disabled={false}
                                                                                onlyPages={true}
                                                                                selectedPageContent={
                                                                                    pageType === "privacyPolicy"
                                                                                        ? (content) => {
                                                                                              const newState: typeof hasPrivacyPolicyRCBSentence =
                                                                                                  typeof content ===
                                                                                                  "string"
                                                                                                      ? content
                                                                                                            .toLowerCase()
                                                                                                            .indexOf(
                                                                                                                "real cookie banner",
                                                                                                            ) > -1
                                                                                                          ? "in-text"
                                                                                                          : "not-in-text"
                                                                                                      : "unset";

                                                                                              if (
                                                                                                  newState ===
                                                                                                      hasPrivacyPolicyRCBSentence ||
                                                                                                  hasPrivacyPolicyRCBSentence ===
                                                                                                      "show-suggestion"
                                                                                              ) {
                                                                                                  return;
                                                                                              }

                                                                                              yieldMainThread().then(
                                                                                                  () =>
                                                                                                      setHasPrivacyPolicyRCBSentence(
                                                                                                          newState,
                                                                                                      ),
                                                                                              );
                                                                                          }
                                                                                        : undefined
                                                                                }
                                                                            />
                                                                        </Form.Item>
                                                                        {languages?.length > 0 && (
                                                                            <p
                                                                                className="description"
                                                                                style={{ fontSize: 12 }}
                                                                            >
                                                                                {__(
                                                                                    "You need to select the page in your default language here. The translation will be output automatically.",
                                                                                )}
                                                                            </p>
                                                                        )}
                                                                    </>
                                                                )}
                                                                {!isExternalUrl && (
                                                                    <Tooltip
                                                                        title={
                                                                            isBannerLessConsent
                                                                                ? _i(
                                                                                      __(
                                                                                          "The cookie banner is hidden on all subpages due to the active option {{a}}Consent > Banner-less consent{{/a}}.",
                                                                                      ),
                                                                                      {
                                                                                          a: (
                                                                                              <a
                                                                                                  href="#/settings/consent"
                                                                                                  style={{
                                                                                                      fontStyle:
                                                                                                          "italic",
                                                                                                  }}
                                                                                              />
                                                                                          ),
                                                                                      },
                                                                                  )
                                                                                : undefined
                                                                        }
                                                                    >
                                                                        <div>
                                                                            <Form.Item<
                                                                                FormSettingsValueProps["navLinks"]
                                                                            >
                                                                                name={[field.name, "hideCookieBanner"]}
                                                                                noStyle
                                                                                valuePropName="checked"
                                                                            >
                                                                                <Checkbox
                                                                                    disabled={isBannerLessConsent}
                                                                                >
                                                                                    {__(
                                                                                        "Hide cookie banner on this page",
                                                                                    )}
                                                                                </Checkbox>
                                                                            </Form.Item>
                                                                        </div>
                                                                    </Tooltip>
                                                                )}
                                                                {pageType === "privacyPolicy" &&
                                                                    hasPrivacyPolicyRCBSentence !== "unset" &&
                                                                    (hasPrivacyPolicyRCBSentence === "in-text" &&
                                                                    !isExternalUrl ? (
                                                                        <div style={{ margin: "10px 0" }}>
                                                                            <CheckCircleFilled
                                                                                style={{ color: "#52c41a" }}
                                                                            />
                                                                            &nbsp;
                                                                            {__(
                                                                                "You mentioned Real Cookie Banner in your privacy policy.",
                                                                            )}
                                                                            &nbsp;&bull;&nbsp;
                                                                            <a
                                                                                onClick={() =>
                                                                                    setHasPrivacyPolicyRCBSentence(
                                                                                        "show-suggestion",
                                                                                    )
                                                                                }
                                                                            >
                                                                                {__("Show suggested text")}
                                                                            </a>
                                                                        </div>
                                                                    ) : (
                                                                        <div
                                                                            className="notice notice-info inline below-h2 notice-alt"
                                                                            style={{ margin: "10px 0" }}
                                                                        >
                                                                            <p>
                                                                                {__(
                                                                                    "You must mention in your privacy policy that you use Real Cookie Banner and what data it processes. The following text suggestion can be copied into your privacy policy.",
                                                                                )}
                                                                                <Checkbox
                                                                                    checked={fullyLeakPrivacyPolicyText}
                                                                                    onChange={(e) =>
                                                                                        setFullyLeakPrivacyPolicyText(
                                                                                            e.target.checked,
                                                                                        )
                                                                                    }
                                                                                    style={{
                                                                                        marginTop: 12,
                                                                                        fontSize: "inherit",
                                                                                    }}
                                                                                >
                                                                                    {__(
                                                                                        "I will check the following sample text for a privacy policy regarding the use of Real Cookie Banners myself and adapt it for my specific use case. In doing so, I will particularly consider overlaps with other areas of my privacy policy.",
                                                                                    )}
                                                                                </Checkbox>
                                                                            </p>
                                                                            {fullyLeakPrivacyPolicyText && (
                                                                                <>
                                                                                    <Input.TextArea
                                                                                        rows={6}
                                                                                        readOnly
                                                                                        style={{ marginBottom: 12 }}
                                                                                        onClick={(e) => {
                                                                                            copyToClipboard(
                                                                                                (
                                                                                                    e.target as HTMLTextAreaElement
                                                                                                ).value,
                                                                                            );
                                                                                            message.success(
                                                                                                __(
                                                                                                    "Successfully copied privacy policy text to clipboard!",
                                                                                                ),
                                                                                            );
                                                                                        }}
                                                                                        value={_x(
                                                                                            'To manage the cookies and similar technologies used (tracking pixels, web beacons, etc.) and related consents, we use the consent tool "Real Cookie Banner". Details on how "Real Cookie Banner" works can be found at <a href="https://devowl.io/rcb/data-processing/" rel="noreferrer" target="_blank">https://devowl.io/rcb/data-processing/</a>.\n\nThe legal basis for the processing of personal data in this context are Art. 6 (1) (c) GDPR and Art. 6 (1) (f) GDPR. Our legitimate interest is the management of the cookies and similar technologies used and the related consents.\n\nThe provision of personal data is neither contractually required nor necessary for the conclusion of a contract. You are not obliged to provide the personal data. If you do not provide the personal data, we will not be able to manage your consents.',
                                                                                            "legal-text",
                                                                                        )}
                                                                                    />
                                                                                    {pageId > 0 && (
                                                                                        <a
                                                                                            onClick={() =>
                                                                                                onPageEditClick(pageId)
                                                                                            }
                                                                                            style={{
                                                                                                marginBottom: 12,
                                                                                            }}
                                                                                            className="button button-small"
                                                                                        >
                                                                                            <EditOutlined />{" "}
                                                                                            {__("Edit privacy policy")}
                                                                                        </a>
                                                                                    )}
                                                                                </>
                                                                            )}
                                                                        </div>
                                                                    ))}
                                                                {pageType === "cookiePolicy" &&
                                                                    cookiePolicyId === 0 && (
                                                                        <div style={{ margin: "10px 0" }}>
                                                                            <WarningOutlined
                                                                                style={{ color: "darkorange" }}
                                                                            />
                                                                            &nbsp;
                                                                            {__(
                                                                                "You have not yet activated the cookie policy feature. Real Cookie Banner offers you the possibility to create your own cookie policy. If you use your own cookie policy, you can ignore this notice.",
                                                                            )}
                                                                            <br />
                                                                            <FormSettingsGeneralCreateCookiePolicyPageButton />
                                                                        </div>
                                                                    )}
                                                                <div>
                                                                    <Form.Item<FormSettingsValueProps["navLinks"]>
                                                                        {...FormSettingsFieldNavLinkLayout}
                                                                        name={[field.name, "isTargetBlank"]}
                                                                        valuePropName="checked"
                                                                        style={{
                                                                            display:
                                                                                getFieldValue([
                                                                                    "navLinks",
                                                                                    field.name,
                                                                                    "isTargetBlank",
                                                                                ]) !== false
                                                                                    ? "none"
                                                                                    : undefined,
                                                                        }}
                                                                    >
                                                                        <Checkbox>{__("Open in new window")}</Checkbox>
                                                                    </Form.Item>
                                                                </div>
                                                            </>
                                                        );
                                                    }}
                                                </Form.Item>
                                            </td>
                                            <td>
                                                <Form.Item<FormSettingsValueProps["navLinks"]>
                                                    noStyle
                                                    name={[field.name, "label"]}
                                                >
                                                    <Input />
                                                </Form.Item>
                                                <ListMultilingualLanguages
                                                    style={{ marginTop: 10, marginLeft: 5 }}
                                                    recordId={getFieldValue(["navLinks", field.name, "id"])}
                                                    languages={getFieldValue(["navLinks", field.name, "languages"])}
                                                    onClick={getFieldValue(["navLinks", field.name, "languageOnClick"])}
                                                />
                                            </td>
                                            <td>
                                                <a
                                                    className="button button-small"
                                                    onClick={() => {
                                                        remove(field.name);
                                                    }}
                                                >
                                                    <DeleteOutlined />
                                                </a>
                                            </td>
                                        </SortableRow>
                                    ))}
                                </SortableContext>
                            </tbody>
                            <tfoot>
                                <tr>
                                    <td colSpan={5} align="right">
                                        <a
                                            className="button button-primary alignright"
                                            onClick={() => {
                                                add({
                                                    pageType: "other",
                                                    hideCookieBanner: true,
                                                    isTargetBlank: true,
                                                } as FormSettingsValueProps["navLinks"][0]);
                                            }}
                                        >
                                            <PlusOutlined /> {__("Add another link")}
                                        </a>
                                    </td>
                                </tr>
                            </tfoot>
                        </table>
                    )}
                </Form.List>
            )}
        </Form.Item>
    );
};

export { FormSettingsGeneralNavTable };
