import { useEffect, useRef, useState, type FC } from "react";
import Button from "@/components/Button";
import { Add, TickSquare } from "iconsax-react";
import { toast } from "@/shared/toast";
import { useNavigate, useSearchParams } from "react-router-dom";
import { Paths } from "@/config/Paths";
import { extractErrorMessage } from "@/config/func";
import { useFormik } from "formik";
import * as Yup from "yup";
import type { CreatePreInvoiceType, CreatePreInvoiceItemType } from "./types/Types";
import InvoiceItemRow from "./components/InvoiceItemRow";
import { Checkbox } from "@/components/ui/checkbox";
import UploadBox from "@/components/UploadBox";
import Textarea from "@/components/Textarea";
import DatePickerComponent from "@/components/DatePicker";
import { useCreateInvoice } from "./hooks/useInvoiceData";
import { useGetRequestDetail } from "@/pages/requests/hooks/useRequestData";
import { useMultiUpload } from "../uploader/hooks/useUploader";
import moment from "moment-jalaali";
import { getItemLineTotal } from "./utils/invoiceItem";
import UserSearch from "../user/UserSearch";

const createEmptyItem = (): CreatePreInvoiceItemType => ({
    productId: "",
    quantity: 1,
    unitPrice: 0,
    discount: 0,
    discountPercent: null,
    description: "",
});

const CreateInvoice: FC = () => {

    const navigate = useNavigate();
    const [searchParams] = useSearchParams();
    const requestId = searchParams.get("requestId") ?? undefined;

    const { mutate: submitInvoice, isPending } = useCreateInvoice();
    const { data: requestData, isLoading: isLoadingRequest } = useGetRequestDetail(requestId ?? "");
    const hydratedRequestId = useRef<string | null>(null);
    const multiUpload = useMultiUpload()

    const [items, setItems] = useState<CreatePreInvoiceItemType[]>([createEmptyItem()]);
    const [attachmentFiles, setAttachmentFiles] = useState<File[]>([]);

    const formik = useFormik<Pick<CreatePreInvoiceType, "userId" | "enableTax" | "approvalDeadline" | "paymentMethod" | "description">>({
        initialValues: {
            userId: "",
            enableTax: false,
            approvalDeadline: "",
            paymentMethod: "",
            description: "",
        },
        validationSchema: Yup.object({
            userId: !requestId
                ? Yup.string().required("انتخاب مشتری اجباری است.")
                : Yup.string(),
            approvalDeadline: Yup.string().required("مهلت تایید اجباری است."),
        }),
        onSubmit: async (values) => {
            const validItems = items.filter(
                (i) => i.productId && i.quantity > 0 && i.unitPrice >= 0
            );

            if (validItems.length === 0) {
                toast("حداقل یک آیتم با محصول، تعداد و مبلغ واحد معتبر اضافه کنید.", "error");
                return;
            }

            const attachments: { type: string; url: string }[] = [];
            if (attachmentFiles.length) {
                const uploadResult = await multiUpload.mutateAsync(attachmentFiles);
                uploadResult?.data?.forEach((item) => {
                    attachments.push({
                        type: "uploads_attach",
                        url: item.url,
                    });
                });
            }

            const params: CreatePreInvoiceType = {
                ...(requestId ? { requestId } : { userId: values.userId }),
                items: validItems.map((i) => ({
                    productId: i.productId,
                    quantity: i.quantity,
                    unitPrice: i.unitPrice,
                    ...(i.discountPercent != null && i.discountPercent > 0
                        ? { discountPercent: i.discountPercent }
                        : { discount: i.discount || 0 }),
                    description: i.description || "",
                })),
                enableTax: values.enableTax,
                ...(values.approvalDeadline
                    ? { approvalDeadline: moment(values.approvalDeadline, 'jYYYY/jMM/jDD').format('YYYY-MM-DD') }
                    : {}),
                ...(values.paymentMethod?.trim()
                    ? { paymentMethod: values.paymentMethod.trim() }
                    : {}),
                description: values.description,
                ...(attachments.length ? { attachments } : {}),
            };

            submitInvoice(params, {
                onSuccess: () => {
                    toast("پیش فاکتور با موفقیت ثبت شد", "success");
                    navigate(Paths.perfomaInvoice.list);
                },
                onError: (error) => {
                    toast(extractErrorMessage(error), "error");
                },
            });
        },
    });

    useEffect(() => {
        const request = requestData?.data;
        if (!requestId || !request || hydratedRequestId.current === requestId) return;

        const mappedItems: CreatePreInvoiceItemType[] = request.items?.length
            ? request.items.map((item) => ({
                productId: item.product?.id ?? "",
                quantity: 1,
                unitPrice: 0,
                discount: 0,
                discountPercent: null,
                description: item.description ?? "",
            }))
            : [createEmptyItem()];

        setItems(mappedItems);
        hydratedRequestId.current = requestId;
    }, [requestData, requestId]);

    const handleItemChange = (
        index: number,
        field: keyof CreatePreInvoiceItemType,
        value: string | number | null
    ) => {
        setItems((prev) =>
            prev.map((item, itemIndex) =>
                itemIndex === index ? { ...item, [field]: value } : item
            )
        );
    };

    const addItem = () => {
        const current = items[items.length - 1];
        const hasProduct = !!current?.productId;
        const hasQuantity = (current?.quantity ?? 0) > 0;
        const hasUnitPrice = (current?.unitPrice ?? 0) > 0;

        if (!hasProduct || !hasQuantity || !hasUnitPrice) {
            toast("لطفاً محصول، تعداد و مبلغ واحد را وارد کنید.", "error");
            return;
        }
        setItems([...items, createEmptyItem()]);
    };

    const removeItem = (index: number) => {
        if (items.length <= 1) return;
        setItems(items.filter((_, i) => i !== index));
    };

    const totalAmount = items.reduce((sum, i) => sum + getItemLineTotal(i), 0);

    return (
        <div className="mt-5">
            <div className="justify-between items-center flex">
                <h1 className="text-lg font-light">پیش فاکتور جدید</h1>
                <Button
                    className="w-fit px-5"
                    onClick={() => formik.handleSubmit()}
                    isLoading={isPending || multiUpload.isPending || isLoadingRequest}
                >
                    <div className="flex gap-2 items-center">
                        <TickSquare size={20} color="black" />
                        <div>ثبت پیش فاکتور</div>
                    </div>
                </Button>
            </div>

            <div className="bg-white rounded-3xl p-6 mt-8">
                <div className="font-light">اطلاعات پیش فاکتور</div>

                {!requestId && (
                    <div className="rowTwoInput mt-6">
                        <div className="w-full">
                            <UserSearch
                                label="مشتری"
                                placeholder="جستجوی مشتری (نام، موبایل، ...)"
                                value={formik.values.userId}
                                onChange={(id) => {
                                    formik.setFieldValue("userId", id);
                                    formik.setFieldTouched("userId", true);
                                }}
                            />
                            {formik.errors.userId && formik.touched.userId ? (
                                <div className="text-xs text-right text-red-600 mt-2 mr-2 font-medium">
                                    {formik.errors.userId}
                                </div>
                            ) : null}
                        </div>
                    </div>
                )}

                <div className="mt-6">
                    {items.map((item, index) => (
                        <InvoiceItemRow
                            key={index}
                            item={item}
                            index={index}
                            onChange={handleItemChange}
                            onRemove={() => removeItem(index)}
                            canRemove={items.length > 1}
                        />
                    ))}
                    <div className="mt-4  ">
                        <button
                            type="button"
                            onClick={addItem}
                            className="h-10 px-4 rounded-xl bg-primary flex items-center gap-2 hover:opacity-90 transition-opacity"
                            aria-label="افزودن آیتم"
                        >
                            <Add size={18} color="black" />
                            <span className="text-[13px] font-light">افزودن آیتم</span>
                        </button>
                    </div>
                </div>

                <div className="mt-6 flex gap-2 items-center">
                    <Checkbox
                        id="enableTax"
                        checked={formik.values.enableTax}
                        onCheckedChange={(checked) =>
                            formik.setFieldValue("enableTax", !!checked)
                        }
                    />
                    <label
                        htmlFor="enableTax"
                        className="text-[13px] cursor-pointer select-none"
                    >
                        مالیات بر ارزش افزوده (۱۰ درصد)
                    </label>
                </div>

                <div className="rowTwoInput mt-6">
                    <DatePickerComponent
                        label="مهلت تایید"
                        placeholder="انتخاب تاریخ"
                        defaultValue={formik.values.approvalDeadline || undefined}
                        onChange={(date) => {
                            formik.setFieldValue("approvalDeadline", date);
                            formik.setFieldTouched("approvalDeadline", true);
                        }}
                        error_text={
                            formik.errors.approvalDeadline && formik.touched.approvalDeadline
                                ? formik.errors.approvalDeadline
                                : ""
                        }
                    />
                </div>

                <div className="mt-6">
                    <Textarea
                        label="روش پرداخت"
                        name="paymentMethod"
                        placeholder="روش پرداخت"
                        value={formik.values.paymentMethod}
                        onChange={(e) => formik.setFieldValue("paymentMethod", e.target.value)}
                        onBlur={formik.handleBlur}
                    />
                </div>

                <div className="mt-6">
                    <Textarea
                        label="توضیحات"
                        placeholder="توضیحات پیش فاکتور را وارد کنید..."
                        value={formik.values.description}
                        onChange={(e) => formik.setFieldValue("description", e.target.value)}
                        onBlur={formik.handleBlur}
                        name="description"
                    />
                </div>

                <div className="mt-6">
                    <UploadBox isMultiple label="فایل ضمیمه" onChange={setAttachmentFiles} />
                </div>

                <div className="mt-6 bg-[#F5F7FC] h-12 px-4 flex justify-between items-center rounded-xl">
                    <div className="text-[#888888] text-[13px]">مبلغ کل:</div>
                    <div className="font-semibold text-[13px]">
                        {totalAmount.toLocaleString("fa-IR")} ریال
                    </div>
                </div>
            </div>
        </div>
    );
};

export default CreateInvoice;
