import Button from "@/components/Button";
import DatePicker from "@/components/DatePicker";
import Error from "@/components/Error";
import Input from "@/components/Input";
import Textarea from "@/components/Textarea";
import { toast } from "@/components/Toast";
import UploadBoxDraggble from "@/components/UploadBoxDraggble";
import { Paths } from "@/config/Paths";
import { formatPrice } from "@/helpers/func";
import { extractErrorMessage } from "@/helpers/utils";
import { designerRequestInitialValues, designerRequestValidationSchema, getPricePerPage, getTotalPrice, toDesignRequestParams } from "@/pages/designer/designerRequestForm";
import { useInitiateDesignRequest } from "@/pages/designer/hooks/useDesignerData";
import type { DesignerRequestFormValues } from "@/pages/designer/types/Types";
import { useMultipleUpload } from "@/pages/uploader/hooks/useUploaderData";
import { Form, Formik, useFormikContext, type FormikHelpers } from "formik";
import { type FC } from "react";
import { useNavigate } from "react-router-dom";

const DesignerRequestFormFields: FC = () => {
  const { values, errors, touched, isSubmitting, setFieldValue, setFieldTouched, handleChange, handleBlur } = useFormikContext<DesignerRequestFormValues>();

  const pageCount = values.count === "" ? 0 : values.count;
  const pricePerPage = pageCount > 0 ? getPricePerPage(pageCount) : 0;
  const totalPrice = getTotalPrice(values.count);

  const handleAttachmentChange = (files: File[]) => {
    setFieldValue("attachments", files);
    setFieldTouched("attachments", true);
  };

  return (
    <Form className="mt-6 space-y-5">
      <Input label="عنوان کاتالوگ" name="title" value={values.title} onChange={handleChange} onBlur={handleBlur} error_text={touched.title ? errors.title : undefined} />

      <div className="grid grid-cols-1 gap-4 lg:grid-cols-2">
        <DatePicker
          label="زمان تحویل موردنظر"
          placeholder="تاریخ را انتخاب کنید"
          defaulValue={values.expectedDate}
          onChange={(date) => {
            setFieldValue("expectedDate", date);
            setFieldTouched("expectedDate", true);
          }}
          error_text={touched.expectedDate ? errors.expectedDate : undefined}
        />
        <Input
          label="تعداد صفحات"
          name="count"
          type="number"
          isNotRequired
          value={values.count}
          onChange={(event) => {
            const value = event.target.value;
            setFieldValue("count", value === "" ? "" : Number(value));
          }}
          onBlur={handleBlur}
          error_text={touched.count ? errors.count : undefined}
        />
      </div>

      <Textarea label="توضیحات" name="desc" value={values.desc} onChange={handleChange} onBlur={handleBlur} className="min-h-[96px]" error_text={touched.desc ? errors.desc : undefined} />

      <div>
        <div className="mb-2 text-sm">فایل های ضمیمه</div>
        <UploadBoxDraggble label="فایل مورد نظر را آپلود کنید" onChange={handleAttachmentChange} isMultiple isFile isLoading={isSubmitting} loadingLabel="در حال ثبت درخواست..." />
        {touched.attachments && errors.attachments ? <Error errorText={String(errors.attachments)} /> : null}
      </div>

      <div className="flex">
        <div className="flex-1" />
        <div className="flex flex-1 gap-4">
          <div className="w-[250px]">
            <Input label="قیمت به ازای هر صفحه" value={pageCount > 0 ? `${formatPrice(pricePerPage)} تومان` : "—"} readOnly />
          </div>
          <Input label="مبلغ قابل پرداخت برای شما" value={`${formatPrice(totalPrice)} تومان`} readOnly />
        </div>
      </div>

      <div className="mt-5 flex justify-end">
        <Button type="submit" className="w-fit px-6" disabled={isSubmitting}>
          ثبت درخواست
        </Button>
      </div>
    </Form>
  );
};

const DesignerRequestForm: FC = () => {
  const navigate = useNavigate();
  const { mutateAsync: uploadFiles } = useMultipleUpload();
  const { mutateAsync: initiateDesignRequest } = useInitiateDesignRequest();

  const handleSubmit = async (values: DesignerRequestFormValues, { setSubmitting, resetForm }: FormikHelpers<DesignerRequestFormValues>) => {
    let attachmentUrls: string[] = [];

    if (values.attachments.length > 0) {
      const uploadResponse = await uploadFiles(values.attachments);
      attachmentUrls = uploadResponse.data.map((item) => item.url);
    }

    await initiateDesignRequest(toDesignRequestParams(values, attachmentUrls), {
      onSuccess: (data) => {
        toast("صورت حساب با موفقیت ثبت شد", "success");
        window.open(`${import.meta.env.VITE_INVOICE_URL}${data?.data?.invoiceId}`, "_blank");
        setSubmitting(false);
        resetForm();
        navigate(Paths.designer.list);
      },
      onError: (error) => {
        toast(extractErrorMessage(error), "error");
        setSubmitting(false);
      },
    });
  };

  return (
    <Formik initialValues={designerRequestInitialValues} validationSchema={designerRequestValidationSchema} onSubmit={handleSubmit}>
      <DesignerRequestFormFields />
    </Formik>
  );
};

export default DesignerRequestForm;
