import { useEffect, useState, type FC } from "react";
import Button from "@/components/Button";
import { Add, TickSquare } from "iconsax-react";
import { toast } from "@/shared/toast";
import { useNavigate, useParams } from "react-router-dom";
import { Paths } from "@/config/Paths";
import { extractErrorMessage } from "@/config/func";
import { useFormik } from "formik";
import type { CreatePreInvoiceItemType, UpdatePreInvoiceType } 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 { useGetInvoiceDetail, useUpdateInvoice } from "./hooks/useInvoiceData";
import { useMultiUpload } from "../uploader/hooks/useUploader";
import moment from "moment-jalaali";
import { getItemLineTotal } from "./utils/invoiceItem";

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

const UpdateInvoice: FC = () => {
  const { id } = useParams<{ id: string }>();
  const navigate = useNavigate();

  const { data: invoiceData, isLoading: isLoadingInvoice } =
    useGetInvoiceDetail(id);
  const { mutate: submitUpdate, isPending } = useUpdateInvoice();
  const multiUpload = useMultiUpload();

  const invoice = invoiceData?.data;

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

  const formik = useFormik<
    Pick<
      UpdatePreInvoiceType,
      "enableTax" | "approvalDeadline" | "paymentMethod" | "description"
    >
  >({
    initialValues: {
      enableTax: false,
      approvalDeadline: "",
      paymentMethod: "",
      description: "",
    },
    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 }[] =
        invoice?.attachments?.map((a) => ({ type: a.type, url: a.url })) ?? [];

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

      const params: UpdatePreInvoiceType = {
        items: validItems.map((i) => ({
          ...(i.id ? { id: i.id } : {}),
          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 } : {}),
      };

      if (!id) return;

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

  useEffect(() => {
    if (invoice) {
      formik.setValues({
        enableTax: invoice.enableTax ?? false,
        approvalDeadline: invoice.approvalDeadline
          ? moment(invoice.approvalDeadline).format("jYYYY/jMM/jDD")
          : "",
        paymentMethod: invoice.paymentMethod ?? "",
        description: invoice.description ?? "",
      });

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

      setItems(mappedItems);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [invoice]);

  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);

  if (isLoadingInvoice || !invoice) {
    return (
      <div className="mt-5 flex items-center justify-center min-h-[200px]">
        <div className="text-[#888888]">در حال بارگذاری...</div>
      </div>
    );
  }

  return (
    <div className="mt-5">
      <div className="justify-between items-center flex">
        <h1 className="text-lg font-light">
          ویرایش پیش فاکتور #{invoice.invoiceNumber}
        </h1>
        <Button
          className="w-fit px-5"
          onClick={() => formik.handleSubmit()}
          isLoading={isPending || multiUpload.isPending}
        >
          <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>

        <div className="mt-6 rowTwoInput">
          <div className="opacity-70">
            <div className="text-[13px] text-[#888888] mb-1.5">مشتری</div>
            <div className="text-[15px]">
              {invoice.user?.firstName && invoice.user?.lastName
                ? `${invoice.user.firstName} ${invoice.user.lastName}`
                : invoice.user?.phone ?? "-"}
            </div>
          </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 flex justify-center">
            <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 UpdateInvoice;
