"use client";
import getData, { postData, putData } from "@/utils/fetch";
import { useParseError, useParseFloat } from "@/utils/lib/helpers";
import { zodResolver } from "@hookform/resolvers/zod";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { Label, Spinner } from "flowbite-react";
import dynamic from "next/dynamic";
import { FC, useEffect, useRef, useState } from "react";
import { FormProvider, useForm } from "react-hook-form";
import { toast } from "react-toastify";
import { InputField, Select, Textarea } from "../forms/Inputs";
import { TSsalarySchema, salarySchema } from "../forms/schema/salary";
import PageHeader from "../PageHeder";
import ActionButton from "../action-button";
import { useRouter } from "next/navigation";
import SalaryItemsRow from "../staffs/salary-items";
import SalaryDeductionsRow from "../staffs/salary-deductions";
import MoneyFormat from "../common/money";

const DropdownList = dynamic(() => import("../common/Dropdown"));

type Props = {
  salary?: TSsalarySchema;
  mode?: string;
};

const SalaryForm: FC<Props> = ({
  salary,
  mode = "create",
}) => {
  const queryClient = useQueryClient();
  const [salaryType, setSalaryType] = useState("monthly");
  const [totalSalary, setTotalSalary] = useState(0);
  const [staffId, setStaffId] = useState(null);
  const route = useRouter();

  const salaryForm = useForm<TSsalarySchema>({
    resolver: zodResolver(salarySchema),
    defaultValues: (salary as TSsalarySchema) || {
      staff_id: 0,
      date: "",
      amount: 0,
      salary_items: {},
      salary_deductions: {},
      salary_type: "monthly",
      fund_id: undefined,
      note: "",
      status: "pending",
    },
  });

  const getSalaryStructure = async () => {
    const data = await getData(`/api/v1/salary-deduction/${staffId}`);
    setValue("salary_items", data?.salary_items);
    setValue("salary_deductions", data?.salary_deductions);
    setValue("amount", data?.total_salary)
    return data;
  };

  const inputRef = useRef<HTMLInputElement>(null);

  const { data: staffSalary, isLoading } = useQuery({
    queryKey: ["staff", { staffId }],
    queryFn: getSalaryStructure,
    retry: 0,
    enabled: !!staffId,
  });

  const {
    handleSubmit,
    reset,
    formState: { errors },
    watch,
    setValue,
  } = salaryForm;


  const { mutate: submitSalary, isPending } = useMutation({
    mutationFn: async (salaryData: TSsalarySchema) => {
      if (mode === "create") {
        const api_url = `/api/v1/salaries`;
        const data = await postData(api_url, salaryData);
        if (!data?.success) {
          throw data;
        }
        return data?.data;
      }
      if (mode === "edit") {
        const api_url = `/api/v1/salaries/${salary?.id}`;
        const data = await putData(api_url, salaryData);
        if (!data?.success) {
          throw data;
        }
        return data?.data;
      }
    },
    onSuccess: (data) => {
      toast.success(`Salary ${mode} successfully!`);
      queryClient.invalidateQueries({ queryKey: ["salaries"] });
      reset();
      route.push("/salaries");
    },
    onError: (error: any) => {
      toast.error(useParseError(error));
    },
  });

  const onSubmit = async (data: TSsalarySchema) => {
    console.log(data);
    if (data?.salary_deductions?.length > 0) {
      const advanceRepay = data?.salary_deductions?.filter((deductions) => deductions?.deductions_label === 'Advance repay');
      const advanceAmount = useParseFloat(staffSalary?.advance);
      const advanceRepayAmount = useParseFloat(advanceRepay[0]?.deductions_value);
      if (advanceRepayAmount > advanceAmount) {
        return toast.error(`Advance repay amount cannot be grater then advance amount`);
      }
    }
    submitSalary(data);
  };

  const onError = async (data: any) => {
    console.log(data);
  };


  useEffect(() => {
    const { unsubscribe } = watch((value) => {
      let totalSalary = 0;
      let totalDeduction = 0;
      if (value?.salary_items?.length > 0) {
        totalSalary = value.salary_items?.reduce((acc: number, item) => acc + useParseFloat(item?.items_value), 0);
      }
      if (value?.salary_deductions?.length > 0) {
        totalDeduction = value.salary_deductions?.reduce((acc: number, item) => acc + useParseFloat(item?.deductions_value), 0);
      }
      let total = useParseFloat(totalSalary) - useParseFloat(totalDeduction);
      setTotalSalary(total);
    });
    return () => unsubscribe();
  }, [watch]);

  useEffect(() => {
    if (!salary && totalSalary) {
      setValue("amount", totalSalary);
    }
    if (salary) {
      setSalaryType(salary?.salary_type);
      setValue("amount", salary?.amount);
    }
    if (!salary && salaryType === "advance") {
      setValue("amount", 0);
    }
  }, [totalSalary, salary, salaryType]);


  return (
    <>
      <PageHeader>
        <div className="flex justify-between !p-0">
          <h2 className="text-xl font-semibold">Salaries</h2>
          <ActionButton title="Back" type="back" href="/salaries" />
        </div>
      </PageHeader>
      <FormProvider {...salaryForm}>
        <form onSubmit={handleSubmit(onSubmit, onError)}>
          <div className="grid grid-cols-1 gap-x-6 sm:grid-cols-2">
            <div className="mt-1">
              <Select
                defaultValue={"monthly"}
                options={[
                  { value: "monthly", label: "Monthly" },
                  { value: "advance", label: "Advance" },
                ]}
                labelText="Salary Type"
                onChange={(event: any) => setSalaryType(event.target?.value)}
                name="salary_type"
                errors={errors}
              />
            </div>
            <div className="mt-1">
              <div className="mb-2">
                <Label>Fund</Label>
              </div>
              <DropdownList
                name="fund"
                idName="fund_id"
                getLabel={(option: any) => option.name}
                defaultItems={salary?.fund?.name}
                placeholder="Select Fund"
                isMulti={false}
                key={salary?.fund?.id}
              />
            </div>
            <div className="mt-1">
              <div className="mb-2">
                <Label>Staff</Label>
              </div>
              <DropdownList
                name="staff"
                idName="staff_id"
                getLabel={(option: any) => option.name}
                defaultItems={salary?.staff?.name}
                placeholder="Select Staff"
                isMulti={false}
                key={salary?.staff?.id}
                onChange={(option) => setStaffId(option.value)}
              />
            </div>

            <div className="mt-1">
              <Select
                defaultValue={"pending"}
                options={[
                  { value: "pending", label: "Pending" },
                  { value: "paid", label: "Paid" },
                  { value: "approved", label: "Approved" },
                  { value: "cancelled", label: "Cancelled" },
                  { value: "repay", label: "Repay" },
                ]}
                labelText="Status"
                name="status"
                errors={errors}
              />
            </div>
            {salaryType === "advance" && (
              <div className="mt-1">
                <InputField
                  labelText="Amount"
                  name="amount"
                  inputType="number"
                  placeholder="Enter Amount"
                  errors={errors}
                />
              </div>
            )}
          </div>
          {(isLoading) && (
            <div className="relative">
              <div className="grid fixed left-2/4 top-1/2 z-50">
                <Spinner size="sm" color="purple" />
              </div>
            </div>
          )}
          {salaryType === "monthly" && (
            <>
              <div className="flex gap-10  mt-2 mb-2">
                <div className="flex-1">
                  <div className="mb-2 flex">
                    <Label className="font-bold text-gray-500">
                      Salary Items:
                    </Label>
                  </div>
                  <SalaryItemsRow />
                </div>
                <div className="flex-1">
                  <div className="">
                    <div className="mb-2">
                      <Label className="font-bold text-gray-500">
                        Deductions Items:
                      </Label>
                    </div>
                    <SalaryDeductionsRow advanceSalary={staffSalary?.advance} />

                  </div>
                </div>
              </div>
              <div className="flex justify-center border-t py-3 font-bold text-gray-500">
                Total Salary:<MoneyFormat amount={totalSalary} iconClass="mt-0.5" />
              </div>
            </>
          )}
          <div className="mt-2">
            <Textarea
              rows={1}
              labelText="Note"
              name="note"
              placeholder="Optional note"
              errors={errors}
            />
          </div>
          <input className="opacity-0" type="submit" ref={inputRef} />
        </form>
      </FormProvider>
      <ActionButton
        isLoading={isPending}
        type="submit"
        onClick={() => inputRef.current?.click()}
      />
    </>
  );
};

export default SalaryForm;
