"use client";
import ValidationError from "@/components/ValidationError";
import { User } from "@/interfaces/User";
import { useParseFloat } from "@/utils/lib/helpers";
import { zodResolver } from "@hookform/resolvers/zod";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import axios from "axios";
import { useRouter } from "next/navigation";
import { FC, useEffect, useRef, useState } from "react";
import { FormProvider, useForm } from "react-hook-form";
import { toast } from "react-toastify";
import ActionButton from "../action-button";
import DropdownList from "../common/Dropdown";
import {
  Datepicker,
  InputField,
  Radio,
  Select,
  Textarea,
} from "../forms/Inputs";
import { TSclientSchema } from "../forms/schema/client";
import { TSinvoiceSchema, invoiceSchema } from "../forms/schema/invoice";
import InvoiceLineForm from "./invoice-lines";
import InvoiceTotal from "./invoice-total";

type Props = {
  invoice?: TSinvoiceSchema;
  client?: TSclientSchema;
  isEdit?: boolean;
};

const InvoiceForm: FC<Props> = ({ invoice, client, isEdit = false }) => {
  const linesItem = {
    description: "",
    amount: 0,
    discount: 0,
    total_amount: 0,
    quantity: 1,
    order: 0,
    uuid: null,
  };
  const initialInvoice = {
    lines: [linesItem],
  };

  const defaultInvoice = isEdit ? invoice : initialInvoice;
  const route = useRouter();
  const queryClient = useQueryClient();
  const [status, setStatus] = useState("due");
  const [total_discount, setDiscount] = useState(0);
  const invoiceForm = useForm<TSinvoiceSchema>({
    resolver: zodResolver(invoiceSchema),
    mode: "onChange",
    defaultValues: defaultInvoice,
  });

  const inputRef = useRef<HTMLInputElement>(null);

  const {
    handleSubmit,
    reset,
    setError,
    watch,
    control,
    formState: { errors },
  } = invoiceForm;
  const {
    mutate: submitInvoice,
    isPending,
    error,
    isError,
    isSuccess,
  } = useMutation({
    mutationFn: async (invoiceData: TSinvoiceSchema) => {
      const api_url = isEdit ? `/api/invoices/${invoice?.id}` : `/api/invoices`;
      const method = isEdit ? "put" : "post";
      const { data } = await axios({
        method: method,
        url: api_url,
        data: invoiceData,
      });
      return data.data as User;
    },
    onSuccess: (data) => {
      toast.success(`Invoice ${isEdit ? "edit" : "create"} successfully!`);
      route.push("/invoices");
      queryClient.invalidateQueries({ queryKey: ["invoices"] });
      reset();
    },
    onError: (error: any) => {
      console.log(error);
    },
  });
  const onSubmit = async (data: TSinvoiceSchema) => {
    delete data.id;
    delete data.create_by;
    console.log(data);
    //return;
    if (isEdit) {
      submitInvoice(data);
      return;
    }
    if (data?.status === "paid" || data?.status === "partial_paid") {
      if (!data.fund_id) {
        setError("fund_id", {
          type: "manual",
          message: "Payment method is required!",
        });
        return;
      }
    }
    if (data?.status === "partial_paid" && data?.partial_amount <= 0) {
      setError("partial_amount", {
        type: "manual",
        message: "Amount must be grater then 0",
      });
      return;
    }
    submitInvoice(data);
  };

  const onError = async (data: any) => {
    console.log(data);
  };

  const invoiceStatus = () => {
    if (isEdit) {
      return [
        { value: "due", label: "Due" },
        { value: "paid", label: "Paid" },
      ];
    }
    return [
      { value: "due", label: "Due" },
      { value: "paid", label: "Paid" },
      { value: "partial_paid", label: "Partial Paid" },
    ];
  };

  const watchField = watch(["discount"]);

  useEffect(() => {
    const [discount] = watchField;
    if (discount) {
      setDiscount(useParseFloat(discount));
    }
  }, [watchField]);
  return (
    <>
      {isError && (
        <ValidationError
          message={error?.message}
          data={error?.response?.data?.error?.errors}
        />
      )}
      <div className="p-5 pt-1 bg-white">
        {client && (
          <div className="grid grid-cols-1 gap-6 sm:grid-cols-2 border-b pb-3">
            <div>
              <p>ID : {client?.client_id}</p>
              <p>Name : {client?.name}</p>
            </div>
            <div>
              <p>Phone : {client?.phone}</p>
              <p>Address : {client?.current_address}</p>
            </div>
          </div>
        )}
        <FormProvider {...invoiceForm}>
          <form onSubmit={handleSubmit(onSubmit, onError)}>
            <div className="grid grid-cols-1 gap-2 sm:grid-cols-3">
              <div className="mt-1">
                <Datepicker
                  name="create_date"
                  labelText="Create Date"
                  defaultDate={invoice?.create_date}
                />
              </div>
              <div className="mt-1">
                <Datepicker
                  name="due_date"
                  labelText="Due Date"
                  defaultDate={invoice?.due_date}
                />
              </div>
              <div className="mt-1">
                <label htmlFor="" className="block mb-2">
                  Invoice Type
                </label>
                <DropdownList
                  name="invoice_type"
                  idName="invoice_type_id"
                  getLabel={(invoiceType: any) => invoiceType?.name}
                  placeholder="Invoice Type"
                  isMulti={false}
                  defaultItems={invoice?.invoice_type}
                />
              </div>
              <div>
                <label htmlFor="" className="block mb-2">
                  Client
                </label>
                <DropdownList
                  name="client"
                  placeholder="Client"
                  idName="client_id"
                  isMulti={false}
                  getLabel={(dropdownClient) => dropdownClient.name}
                  defaultItems={invoice?.client}
                />
              </div>
              <div>
                <InputField
                  labelText="Discount"
                  name={`discount`}
                  placeholder="Discount"
                  errors={errors}
                />
              </div>
              {!isEdit && (
                <div className="">
                  <Select
                    defaultValue={invoice?.status ?? "due"}
                    options={invoiceStatus()}
                    labelText="Status"
                    name="status"
                    errors={errors}
                    onChange={(e) => setStatus(e.target.value)}
                  />
                </div>
              )}
              {status === "partial_paid" && (
                <div className="-mt-2">
                  <InputField
                    labelText="Partial Amount"
                    name="partial_amount"
                    placeholder="Partial amount"
                    errors={errors}
                  />
                </div>
              )}
              {(status === "paid" || status === "partial_paid") && (
                <>
                  <div className="">
                    <label htmlFor="">Payment Method</label>
                    <DropdownList
                      name="fund"
                      idName="fund_id"
                      placeholder="Fund"
                      isMulti={false}
                      defaultItems={invoice?.fund}
                      getLabel={(fund) => fund?.name}
                    />
                  </div>
                  <div className="-mt-2">
                    <Datepicker
                      name="payment_date"
                      labelText="Payment Date"
                      defaultDate={invoice?.payment_date}
                    />
                  </div>
                </>
              )}
            </div>
            <InvoiceLineForm defaultInvoice={linesItem} />
            <div className="md:flex justify-between border-b">
              <div className="mt-4">
                <Radio
                  groupLabel="Send SMS : "
                  name="confirmation_sms"
                  labelFlex={true}
                  options={[
                    { label: "Yes", value: 1 },
                    { label: "No", value: 0 },
                  ]}
                  defaultValue={0}
                />
              </div>
              <div className="p-5 mr-14">
                <InvoiceTotal control={control} discount={total_discount} />
              </div>
            </div>
            <div className="grid grid-cols-1 gap-6 sm:grid-cols-2">
              <div className="footer"></div>
            </div>
            <div className="mt-2">
              <Textarea
                labelText="Note"
                name="note"
                rows={2}
                placeholder="Note"
              />
            </div>
            <div className="grid grid-cols-1 gap-6 sm:grid-cols-1"></div>
            <input className="opacity-0" type="submit" ref={inputRef} />
          </form>
        </FormProvider>
        <ActionButton
          isLoading={isPending}
          type="submit"
          onClick={() => inputRef.current?.click()}
        />
      </div>
    </>
  );
};

export default InvoiceForm;
