import { HeartTwoTone } from "@ant-design/icons";
import { App, Button, Checkbox, Divider, Form, Input, Modal, Radio, Spin } from "antd";
import { useCallback, useMemo, useState } from "react";

import { __, _i } from "../../utils/i18n.js";
import { request } from "../../utils/request.js";
import { locationRestPluginFeedbackPost } from "../../wp-api/feedback.post.js";

import type {
    ParamsRoutePluginFeedbackPost,
    RequestRoutePluginFeedbackPost,
    ResponseRoutePluginFeedbackPost,
} from "../../wp-api/feedback.post.js";
import type { CSSProperties, ComponentProps, FC } from "react";

const FEEDBACK_FORM_LAYOUT = {
    labelCol: { span: 24 },
    wrapperCol: { span: 24 },
};

const FEEDBACK_FORM_LAYOUT_MARGIN_BOTTOM: CSSProperties = { marginBottom: 8 };

type InitialValues = {
    reason?: string;
    note?: string;
    email?: string;
    name?: string;
    deactivateLicense?: boolean;
};

const FeedbackModal: FC<{
    initialValues?: InitialValues;
    plugin: string;
    name: string;
    privacyPolicy: string;
    privacyProvider: string;
    hasAtLeastOneActiveLicense: boolean;
    isPluginActiveForNetwork: boolean;
    onClose?: () => void;
    onDeactivate?: () => void;
}> = ({
    initialValues = {},
    plugin,
    name,
    hasAtLeastOneActiveLicense,
    isPluginActiveForNetwork,
    privacyPolicy,
    privacyProvider,
    onClose,
    onDeactivate,
}) => {
    const { message } = App.useApp();
    const reasons = useMemo(
        () => ({
            "upgrade-to-pro": __("Upgrade to PRO Version"),
            "not-working": __("Plugin does not work"),
            "missing-features": __("Not the features I want"),
            incompatible: __("Incompatible with themes/plugins"),
            "missing-doc": __("Lack of documentation"),
            "found-better-plugin": __("Found a better plugin"),
            temp: __("Temporary deactivation"),
            other: __("Other"),
        }),
        [],
    );
    const [form] = Form.useForm<typeof initialValues>();
    const formName = `license-form-${plugin}`;
    const [visible, setVisible] = useState(true);
    const [busy, setBusy] = useState(false);

    const handleClose: ComponentProps<typeof Modal>["onCancel"] = useCallback(() => {
        if (window.confirm(__("Are you sure you want to leave the feedback form?"))) {
            setVisible(false);
        }
    }, []);

    const handleFinish = useCallback(
        async ({
            skip = false,
            reason = "other",
            note = "",
            email = "",
            name = "",
            deactivateLicense = false,
        }: typeof initialValues & {
            skip?: boolean;
        }) => {
            try {
                setBusy(true);
                await request<
                    RequestRoutePluginFeedbackPost,
                    ParamsRoutePluginFeedbackPost,
                    ResponseRoutePluginFeedbackPost
                >({
                    location: locationRestPluginFeedbackPost,
                    params: {
                        slug: plugin,
                    },
                    request: {
                        skip,
                        reason,
                        note,
                        email,
                        name: email ? name : "", // Only send the name when an email got entered, too
                        deactivateLicense,
                    },
                });
                onDeactivate?.();
            } catch (e) {
                const { responseJSON } = e as any;
                const code = responseJSON?.data?.body?.[0]?.code;

                // Ignore some errors
                if (
                    ["DeactivationFeedbackAlreadyGiven", "DeactivationFeedbackMightBeSpam"].indexOf(code) > -1 ||
                    !code
                ) {
                    onDeactivate?.();
                    return;
                } else {
                    message.error(responseJSON?.data?.body?.[0]?.message);
                }
            } finally {
                setBusy(false);
            }
        },
        [form, plugin],
    );

    const handleSkip = useCallback(() => {
        const deactivateLicense = form.getFieldValue("deactivateLicense");

        if (deactivateLicense) {
            handleFinish({
                skip: true,
                deactivateLicense,
            });
        } else {
            onDeactivate?.();
        }
    }, [handleFinish]);

    return (
        <Modal
            afterClose={onClose}
            onCancel={handleClose}
            open={visible}
            footer={[
                <Button key="skip" type="default" onClick={handleSkip} className="alignleft" disabled={busy}>
                    <b>{__("Skip & Deactivate")}</b>
                </Button>,
                <Button key="submit" type="primary" htmlType="submit" form={formName} disabled={busy}>
                    {__("Deactivate")}
                </Button>,
            ]}
            title={
                <>
                    <HeartTwoTone twoToneColor="#eb2f96" /> {__("Too bad you are leaving")}
                </>
            }
        >
            <Spin spinning={busy}>
                <Form
                    name={formName}
                    id={formName}
                    form={form}
                    {...FEEDBACK_FORM_LAYOUT}
                    onFinish={handleFinish}
                    initialValues={initialValues}
                    layout="vertical"
                    labelWrap
                >
                    <Form.Item
                        name="reason"
                        label={<>{__("Please give us feedback why you deactivate %s.", name)}</>}
                        style={FEEDBACK_FORM_LAYOUT_MARGIN_BOTTOM}
                        required
                        rules={[{ required: true, message: __("Please provide a reason!") }]}
                    >
                        <Radio.Group>
                            {Object.keys(reasons).map((choice) => (
                                <Radio key={choice} value={choice} style={{ width: "calc(50% - 8px)", float: "left" }}>
                                    {(reasons as any)[choice]}
                                </Radio>
                            ))}
                        </Radio.Group>
                    </Form.Item>
                    <Form.Item
                        noStyle
                        shouldUpdate={(prevValues, nextValues) => prevValues.reason !== nextValues.reason}
                    >
                        {({ getFieldValue }) =>
                            !!getFieldValue("reason") && (
                                <>
                                    <Form.Item
                                        label={__("What could we do better?")}
                                        name="note"
                                        style={FEEDBACK_FORM_LAYOUT_MARGIN_BOTTOM}
                                    >
                                        <Input.TextArea autoSize={{ minRows: 3 }} />
                                    </Form.Item>
                                    <Form.Item
                                        noStyle
                                        shouldUpdate={(prevValues, nextValues) =>
                                            prevValues.answerTerms !== nextValues.answerTerms
                                        }
                                    >
                                        {({ getFieldValue }) =>
                                            !!getFieldValue("reason") && (
                                                <>
                                                    <Form.Item
                                                        name="email"
                                                        label={__("Email for answer/solution")}
                                                        style={FEEDBACK_FORM_LAYOUT_MARGIN_BOTTOM}
                                                        rules={[
                                                            {
                                                                type: "email",
                                                                required: getFieldValue("answerTerms"),
                                                                message: __("Please provide a valid e-mail address!"),
                                                            },
                                                        ]}
                                                    >
                                                        <Input />
                                                    </Form.Item>
                                                    <Form.Item
                                                        noStyle
                                                        shouldUpdate={(prevValues, nextValues) =>
                                                            prevValues.email !== nextValues.email
                                                        }
                                                    >
                                                        {({ getFieldValue }) => (
                                                            <>
                                                                {!!getFieldValue("email") && (
                                                                    <Form.Item
                                                                        name="name"
                                                                        label={__("Name")}
                                                                        required
                                                                        style={FEEDBACK_FORM_LAYOUT_MARGIN_BOTTOM}
                                                                        rules={[
                                                                            {
                                                                                required: true,
                                                                                message: __("Please provide a name!"),
                                                                            },
                                                                        ]}
                                                                    >
                                                                        <Input />
                                                                    </Form.Item>
                                                                )}
                                                                <Form.Item
                                                                    name="answerTerms"
                                                                    valuePropName="checked"
                                                                    required
                                                                    rules={[
                                                                        {
                                                                            type: "boolean",
                                                                            required: !!getFieldValue("email"),
                                                                            transform: (value) => value || undefined,
                                                                            message: __(
                                                                                "Please confirm that you have checked the privacy policy.",
                                                                            ),
                                                                        },
                                                                    ]}
                                                                    style={FEEDBACK_FORM_LAYOUT_MARGIN_BOTTOM}
                                                                >
                                                                    <Checkbox style={{ zoom: 0.8 }}>
                                                                        {_i(
                                                                            __(
                                                                                "I would like to receive a response to my request. For this purpose, I agree to the data processing of my feedback and my e-mail address. I have read and acknowledge the %s {{a}}Privacy Policy{{/a}}.",
                                                                                privacyProvider,
                                                                            ),
                                                                            {
                                                                                a: (
                                                                                    <a
                                                                                        href={privacyPolicy}
                                                                                        target="_blank"
                                                                                        rel="noreferrer"
                                                                                    />
                                                                                ),
                                                                            },
                                                                        )}
                                                                    </Checkbox>
                                                                </Form.Item>
                                                            </>
                                                        )}
                                                    </Form.Item>
                                                </>
                                            )
                                        }
                                    </Form.Item>
                                </>
                            )
                        }
                    </Form.Item>

                    <Form.Item
                        noStyle
                        shouldUpdate={(prevValues, nextValues) =>
                            prevValues.note !== nextValues.note || prevValues.answerTerms !== nextValues.answerTerms
                        }
                    >
                        {({ getFieldValue }) => {
                            const answerTerms = (getFieldValue("answerTerms") || false) as boolean;
                            const note = (getFieldValue("note") || "") as string;

                            if (answerTerms) {
                                return null;
                            }

                            return note.split(" ").length >= 5 ? (
                                <div className="notice notice-info inline below-h2 notice-alt" style={{ margin: 0 }}>
                                    <p>
                                        {__(
                                            "Allow us to reply to you by email and we will get back to you as soon as possible!",
                                        )}
                                    </p>
                                </div>
                            ) : (
                                <p className="description" style={{ marginTop: 5 }}>
                                    {_i(
                                        __(
                                            "Are there any problems with the setup or use of the plugin? Maybe we can help you in the support. {{a}}Contact support{{/a}}.",
                                        ),
                                        {
                                            a: (
                                                <a
                                                    href={__("https://devowl.io/support/")}
                                                    target="_blank"
                                                    rel="noreferrer"
                                                />
                                            ),
                                        },
                                    )}
                                </p>
                            );
                        }}
                    </Form.Item>
                    {hasAtLeastOneActiveLicense && (
                        <>
                            <Divider style={{ margin: "12px 0" }} />
                            <Form.Item
                                style={{ marginBottom: 0 }}
                                name="deactivateLicense"
                                valuePropName="checked"
                                label={__(
                                    "Do you want to deactivate your active license so that you can use it again on another site?",
                                )}
                            >
                                <Checkbox>
                                    {isPluginActiveForNetwork
                                        ? __("Yes, deactivate all active licenses for all sites within this multisite")
                                        : __("Yes, deactivate license")}
                                </Checkbox>
                            </Form.Item>
                        </>
                    )}
                </Form>
            </Spin>
        </Modal>
    );
};

export { FeedbackModal };
