"use client";
import {useAppDispatch} from "@/lib/redux/hooks";
import {useTranslations} from "use-intl";
import {z} from "zod";
import {useEffect, useState} from "react";
import {useForm} from "react-hook-form";
import {zodResolver} from "@hookform/resolvers/zod";
import {FormItem, FormWrapper} from "@/components/ui/form";
import AppInput from "@/components/ui/input";
import AppButton from "@/components/ui/button";
import {useRouter} from "@/i18n/routing";
import {doCreateCoupon} from "@/lib/redux/features/coupon";
import {PlusOutlined} from "@ant-design/icons";
import {DatePicker, Modal, Select} from "antd";
import AppSelect from "../ui/select";
import AppCheckbox from "../ui/checkbox";
import dayjs from "dayjs";
import {UserType} from "@/types/user";
import AppInputNumber from "../ui/input-number";
import {ProductAppIdQueryParams, ProductOption, ProductResponse,} from "@/types/product";
import {onGetProductAppId} from "@/services/apis/product";
import {ResponseStatus, SortDirection, SortField} from "@/types/common";
import {CreateCouponRequest} from "@/types/coupon";

export default function CreateCouponModal({
                                              fetchCouponPaging,
                                              appsId,
                                              authInfo,
                                              isAppActive,
                                          }) {
    const dispatch = useAppDispatch();
    const router = useRouter();
    const t = useTranslations("AppPage.coupon");
    const [isOpen, setIsOpen] = useState(false);
    const [isLoading, setIsLoading] = useState(false);
    const [isUnlimited, setIsUnlimited] = useState<string>("NO");
    const [couponTypeValue, setCouponTypeValue] = useState<string>("PERCENTAGE");

    const [loading, setLoading] = useState<boolean>(false);
    const [products, setProducts] = useState<ProductOption[]>([]);
    // const [selectedProducts, setSelectedProducts] = useState<string[]>([]);
    const [productPaging, setProductPaging] = useState({
        numberOfElements: 0,
        pageNumber: 1,
        pageSize: 10,
        totalElements: 0,
        totalPages: 0,
    });

    const handleRenderPurchaseType = () => {
        return [
            {
                label: t("purchase_type_options.ONE_TIME_PURCHASE"),
                value: "ONE_TIME_PURCHASE",
            },
            {
                label: t("purchase_type_options.SUBSCRIPTION"),
                value: "SUBSCRIPTION",
            },
            {
                label: t("purchase_type_options.BOTH"),
                value: "BOTH",
            },
        ]
    }

    const handleUnlimitedChange = (checked: boolean) => {
        setIsUnlimited(checked ? "YES" : "NO");
    };

    const openModal = () => setIsOpen(true);
    const closeModal = () => {
        setIsOpen(false);
        createCouponForm.reset();
    };

    const formSchema = z
        .object({
            couponName: z
                .string()
                .trim()
                .min(1, {message: t("validate.required")})
                .min(6, {message: t("validate.min_length_6")})
                .max(6, {message: t("validate.max_length_6")})
                .refine((val) => /^[A-Z]{6}$/.test(val), {
                    message: t("validate.uppercase_only"),
                })
                .transform((val) => val.toUpperCase()),

            couponType: z
                .string({
                    required_error: t("validate.required"),
                })
                .default("PERCENTAGE"),

            isUnlimited: z
                .string({
                    required_error: t("validate.required"),
                })
                .default("NO"),

            currency: z.coerce
                .number({
                    required_error: t("validate.required"),
                    invalid_type_error: t("validate.currency_must_be_number"),
                })
                .min(1, {message: t("validate.required")})
                .refine(
                    (val) => {
                        if (couponTypeValue === "PERCENTAGE" && val > 100) {
                            return false;
                        }
                        return true;
                    },
                    {message: t("validate.percent_max")}
                ),

            numberOfUsages: z.coerce
                .number({
                    invalid_type_error: t("validate.required"),
                })
                .refine(
                    (val) => {
                        if (!isUnlimited) {
                            return val >= 1;
                        }
                        return true;
                    },
                    {message: t("validate.min_number_of_usages")}
                ),

            startsAt: z
                .string({
                    required_error: t("validate.required"),
                })
                .min(1, {message: t("validate.required")}),

            endsAt: z
                .string({
                    required_error: t("validate.required"),
                })
                .min(1, {message: t("validate.required")}),

            productIds: z.array(z.string()).min(1, {message: t("validate.required")}),

            oncePerCustomer: z.boolean().default(false),
            purchaseType: z
                .string().min(1, {message: t("validate.required")}),
        })
        .superRefine((data, ctx) => {
            if (
                data.isUnlimited !== "YES" &&
                (!data.numberOfUsages || data.numberOfUsages < 1)
            ) {
                ctx.addIssue({
                    code: z.ZodIssueCode.custom,
                    message: t("validate.number_of_usages_required"),
                    path: ["numberOfUsages"],
                });
            }
        });

    type CreateCouponFormSchema = z.infer<typeof formSchema>;

    const createCouponForm = useForm<CreateCouponFormSchema>({
        resolver: zodResolver(formSchema),
        defaultValues: {
            couponName: "",
            couponType: "PERCENTAGE",
            isUnlimited: "NO",
            currency: 0,
            numberOfUsages: 0,
            startsAt: "",
            endsAt: "",
            productIds: [],
            oncePerCustomer: false,
            purchaseType: "",
        },
    });

    const getListProduct = async (query: ProductAppIdQueryParams) => {
        setLoading(true);
        try {
            if (!query?.appsId) {
                console.error("App ID not found.")
                return;
            }
            const result = await onGetProductAppId(query);
            if (result && result?.status === ResponseStatus.SUCCESS) {
                const products = result.data.content || [];
                const pageNumber = result.data.pageNumber || 1;
                const newProducts = products.map(
                    (product: ProductResponse) => {
                        return {
                            label: product.name,
                            value: product.id,
                        };
                    }
                );
                setProductPaging({
                    numberOfElements: result.data.totalElements,
                    pageNumber: pageNumber,
                    pageSize: result.data.pageSize,
                    totalElements: result.data.totalElements,
                    totalPages: result.data.totalPages,
                })
                if (pageNumber === 1) {
                    setProducts(newProducts);
                } else {
                    setProducts((prevProduct) => [...prevProduct, ...newProducts]);
                }
            }
        } catch (error) {
            console.error("Error fetching products", error);
        } finally {
            setLoading(false);
        }
    };

    useEffect(() => {
        if (!isOpen) {
            return
        }
        getListProduct({
            appsId: appsId,
            pageNumber: 1,
            pageSize: 10,
            sortField: SortField.createdTime,
            sortDirection: SortDirection.DESC,
        });
    }, [appsId, isOpen]);

    const handlePopupScroll = (e: React.UIEvent<HTMLDivElement>) => {
        const target = e.target as HTMLDivElement;
        if (target.scrollTop + target.offsetHeight >= target.scrollHeight - 20 && !loading && productPaging.totalPages > productPaging.pageNumber) {
            getListProduct({
                appsId: appsId,
                pageNumber: productPaging.pageNumber + 1,
                pageSize: 10,
                sortField: SortField.createdTime,
                sortDirection: SortDirection.DESC,
            })
        }
    };

    async function onSubmit(values: CreateCouponFormSchema) {
        console.log("values", values)
        setIsLoading(true);
        const request: CreateCouponRequest = {
            name: values.couponName,
            appsId: appsId,
            couponType: values.couponType,
            isUnlimited: values.isUnlimited,
            currency: values.currency,
            startsAt: dayjs(values.startsAt).toISOString(),
            endsAt: dayjs(values.endsAt).toISOString(),
            productIds: values.productIds.map((id) => Number(id)),
            oncePerCustomer: values.oncePerCustomer,
            purchaseType: values.purchaseType,
        };
        if (values.isUnlimited === "NO") {
            request.numberOfUsages = values.numberOfUsages;
        }

        const result = await dispatch(doCreateCoupon(request));
        if (result.payload.status === "success") {
            await new Promise((resolve) => setTimeout(resolve, 500));
            fetchCouponPaging({appsId: appsId});
            setIsUnlimited("NO");
        }

        createCouponForm.reset();
        setIsLoading(false);
        closeModal();
        router.refresh();
    }

    useEffect(() => {
        console.log("Create coupon Form errors:", createCouponForm.formState.errors);
    }, [createCouponForm.formState.errors]);

    return (
        <>
            <div className="flex justify-between items-center mb-4">
                <h1 className="text-2xl font-semibold">{t("title")}</h1>
                <div className="flex items-center gap-2">
                    <AppButton
                        icon={<PlusOutlined/>}
                        type="primary"
                        htmlType="submit"
                        loading={isLoading}
                        onClick={openModal}
                        className=""
                        disabled={authInfo?.userType !== UserType.ADMIN || isAppActive}
                    >
                        {t("createCoupon")}
                    </AppButton>
                </div>
            </div>

            {isOpen && (
                <Modal
                    title={t("createCoupon")}
                    open={isOpen}
                    onOk={closeModal}
                    onCancel={closeModal}
                    footer={null}
                    maskClosable={false}
                    destroyOnClose={true}
                >
                    <FormWrapper<CreateCouponFormSchema>
                        form={createCouponForm}
                        onSubmit={onSubmit}
                        layout="vertical"
                        className="space-y-4"
                    >
                        <FormItem name="couponName" label={t("couponName")}>
                            {({value, ref, ...field}) => (
                                <AppInput
                                    ref={ref}
                                    {...field}
                                    value={value?.toUpperCase()}
                                    placeholder={t("couponName_placeholder")}
                                    onChange={(e) => {
                                        const upperValue = e.target.value.toUpperCase().slice(0, 6);
                                        field.onChange(upperValue);
                                    }}
                                />
                            )}
                        </FormItem>

                        <div className="flex gap-2">
                            <FormItem
                                name="currency"
                                label={t("currency")}
                                className="flex-1"
                            >
                                {({value, ref, ...field}) => (
                                    <AppInputNumber
                                        ref={ref}
                                        value={value}
                                        {...field}
                                        placeholder={t("currency_placeholder")}
                                        disabled={value === false}
                                        min={0}
                                        controls={true}
                                        parser={(value) =>
                                            value ? value.replace(/[^\d]/g, "") : ""
                                        }
                                        formatter={(value) =>
                                            `${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ",")
                                        }
                                    />
                                )}
                            </FormItem>

                            <FormItem
                                name="couponType"
                                label={t("couponType")}
                                className="flex"
                            >
                                {({value, ref, ...field}) => {
                                    return (
                                        <AppSelect
                                            ref={ref}
                                            {...field}
                                            value={value === "PERCENTAGE" ? "percent" : "jpy"}
                                            onChange={(selectedValue: string) => {
                                                const stringValue =
                                                    selectedValue === "jpy"
                                                        ? "FIXED_AMOUNT"
                                                        : "PERCENTAGE";
                                                field.onChange(stringValue);
                                                setCouponTypeValue(stringValue);
                                                if (selectedValue) {
                                                    createCouponForm.clearErrors("currency");
                                                }
                                            }}
                                            options={[
                                                {value: "jpy", label: "¥"},
                                                {value: "percent", label: "%"},
                                            ]}
                                        />
                                    );
                                }}
                            </FormItem>
                        </div>
                        
                            <FormItem name="purchaseType" label={t("purchase_type")}>
                                {({value, ref, ...field}) => (
                                    <div className="flex items-center gap-2">
                                        <AppSelect
                                            style={{width: "100%"}}
                                            placeholder={t("purchase_type_placeholder")}
                                            onChange={(value) => {
                                                field.onChange(value);
                                            }}
                                            options={handleRenderPurchaseType()}
                                            {...field}
                                        />
                                    </div>
                                )}
                            </FormItem>
                        
                        <FormItem name="startsAt" label={t("starts_at")}>
                            {({value, ref, ...field}) => {
                                return (
                                    <DatePicker
                                        ref={ref}
                                        {...field}
                                        value={value ? dayjs(value) : null}
                                        placeholder={t("startsAt_placeholder")}
                                        style={{width: "100%"}}
                                        format="YYYY-MM-DD"
                                        onChange={(date) => {
                                            if (date) {
                                                const startOfDay = date.startOf("day");
                                                field.onChange(startOfDay.toISOString());
                                            } else {
                                                field.onChange(null);
                                            }
                                        }}
                                        disabledDate={(current) => {
                                            return current && current.isBefore(dayjs(), "day");
                                        }}
                                    />
                                );
                            }}
                        </FormItem>

                        <FormItem name="endsAt" label={t("ends_at")}>
                            {({value, ref, ...field}) => {
                                return (
                                    <DatePicker
                                        ref={ref}
                                        {...field}
                                        value={value ? dayjs(value) : null}
                                        placeholder={t("endsAt_placeholder")}
                                        style={{width: "100%"}}
                                        format="YYYY-MM-DD"
                                        onChange={(date) => {
                                            if (date) {
                                                const endOfDay = date.endOf("day");
                                                field.onChange(endOfDay.toISOString());
                                            } else {
                                                field.onChange(null);
                                            }
                                        }}
                                        disabledDate={(current) => {
                                            return current && current.isBefore(dayjs(), "day");
                                        }}
                                    />
                                );
                            }}
                        </FormItem>
                        <FormItem name="productIds" label={t("products")}>
                            {({value, ref, ...field}) => (
                                <AppSelect
                                    ref={ref}
                                    {...field}
                                    mode="multiple"
                                    allowClear
                                    style={{width: "100%"}}
                                    placeholder={t("product_placeholder")}
                                    value={value}
                                    onChange={(value) => {
                                        field.onChange(value);
                                    }}
                                    options={products}
                                    loading={loading}
                                    filterOption={(input, option) =>
                                        (option?.label?.toString() ?? "")
                                            .toLowerCase()
                                            .includes(input.toLowerCase())
                                    }
                                    onPopupScroll={handlePopupScroll}
                                />
                            )}
                        </FormItem>

                        <FormItem name="oncePerCustomer">
                            {({value, ref, ...field}) => (
                                <AppCheckbox
                                    checked={value}
                                    onChange={(checked) => {
                                        field.onChange(checked);
                                    }}
                                >
                                    {t("limit_one_use_per_customer")}
                                </AppCheckbox>
                            )}
                        </FormItem>

                        <FormItem name="numberOfUsages" label={t("numberOfUsages")}>
                            {({value, ref, ...field}) => (
                                <div className="flex items-center gap-2">
                                    <AppInput
                                        ref={ref}
                                        {...field}
                                        placeholder={t("numberOfUsages_placeholder")}
                                        disabled={isUnlimited === "YES"}
                                    />
                                    <AppCheckbox
                                        checked={isUnlimited === "YES"}
                                        onChange={(value: boolean | string[]) => {
                                            if (typeof value === "boolean") {
                                                const newValue = value ? "YES" : "NO";
                                                handleUnlimitedChange(value);
                                                createCouponForm.setValue("isUnlimited", newValue);
                                                if (value) {
                                                    createCouponForm.setValue("numberOfUsages", 0);
                                                    createCouponForm.clearErrors("numberOfUsages");
                                                }
                                            }
                                        }}
                                    >
                                        {t("unlimited")}
                                    </AppCheckbox>
                                </div>
                            )}
                        </FormItem>

                        <div className="flex justify-end items-center gap-2">
                            <AppButton type="default" loading={isLoading} onClick={closeModal}>
                                {t("button.cancel")}
                            </AppButton>
                            <AppButton
                                type="primary"
                                htmlType="submit"
                                loading={isLoading}
                                onClick={async () => await createCouponForm.handleSubmit(onSubmit)}
                            >
                                {t("button.save")}
                            </AppButton>
                        </div>
                    </FormWrapper>
                </Modal>
            )}
        </>
    );
}