import { useCallback } from "react";
import { UseFormReturn } from "react-hook-form";
import { toast } from "sonner";
import { useTranslation } from "react-i18next";
import type { CreateOrEditLetter } from "./formSchema";
import type { TreeViewItem } from "@/shared/common/ui/treeSelect";
import { handleTreeViewChange } from "./treeUtils";

interface RecordFormHandlersParams {
  form: UseFormReturn<CreateOrEditLetter>;
  receivingOptions: TreeViewItem[];
  setReceivingOptions: React.Dispatch<React.SetStateAction<TreeViewItem[]>>;
  ccReceivingOptions: TreeViewItem[];
  setCcReceivingOptions: React.Dispatch<React.SetStateAction<TreeViewItem[]>>;
  nonSmartOfficeUnits: string[];
  setNonSmartOfficeUnits: React.Dispatch<React.SetStateAction<string[]>>;
  nonSmartOfficeCCUnits: string[];
  setNonSmartOfficeCCUnits: React.Dispatch<React.SetStateAction<string[]>>;
  setHasSubmitted: React.Dispatch<React.SetStateAction<boolean>>;
  setShouldScrollToError: React.Dispatch<React.SetStateAction<boolean>>;
  onSubmit: (values: CreateOrEditLetter) => void | Promise<void>;
}

export function useRecordFormHandlers({
  form,
  receivingOptions,
  setReceivingOptions,
  ccReceivingOptions,
  setCcReceivingOptions,
  nonSmartOfficeUnits,
  setNonSmartOfficeUnits,
  nonSmartOfficeCCUnits,
  setNonSmartOfficeCCUnits,
  setHasSubmitted,
  setShouldScrollToError,
  onSubmit,
}: RecordFormHandlersParams) {
  const { t } = useTranslation();

  const handleCheckChange = useCallback(
    (items: TreeViewItem | TreeViewItem[], checked: boolean) =>
      handleTreeViewChange(
        items,
        checked,
        "receivingUnitIds",
        receivingOptions,
        setReceivingOptions,
        form,
      ),
    [receivingOptions, setReceivingOptions, form],
  );

  const handleCcCheckChange = useCallback(
    (items: TreeViewItem | TreeViewItem[], checked: boolean) =>
      handleTreeViewChange(
        items,
        checked,
        "externalCC",
        ccReceivingOptions,
        setCcReceivingOptions,
        form,
      ),
    [ccReceivingOptions, setCcReceivingOptions, form],
  );

  const handleDeleteUnit = useCallback(
    (field: "nonSmartOfficeReceivers" | "nonSmartOfficeReceiverCCs") =>
      (_value: string, index: number) => {
        const current =
          field === "nonSmartOfficeReceivers"
            ? nonSmartOfficeUnits
            : nonSmartOfficeCCUnits;
        const updated = current.filter((_, i) => i !== index);

        if (field === "nonSmartOfficeReceivers") {
          setNonSmartOfficeUnits(updated);
        } else {
          setNonSmartOfficeCCUnits(updated);
        }

        form.setValue(field, updated);
      },
    [nonSmartOfficeUnits, nonSmartOfficeCCUnits, setNonSmartOfficeUnits, setNonSmartOfficeCCUnits, form],
  );

  const handleAdd = useCallback(
    (field: "nonSmartOfficeReceivers" | "nonSmartOfficeReceiverCCs") =>
      (value: string) => {
        const current =
          field === "nonSmartOfficeReceivers"
            ? nonSmartOfficeUnits
            : nonSmartOfficeCCUnits;
        if (!current.includes(value)) {
          const updated = [...current, value];

          if (field === "nonSmartOfficeReceivers") {
            setNonSmartOfficeUnits(updated);
          } else {
            setNonSmartOfficeCCUnits(updated);
          }

          form.setValue(field, updated);
        }
      },
    [nonSmartOfficeUnits, nonSmartOfficeCCUnits, setNonSmartOfficeUnits, setNonSmartOfficeCCUnits, form],
  );

  const handleRemoveItem = useCallback(
    (field: "receivingUnitIds" | "externalCC", value: string) => {
      const findNode = (tree: TreeViewItem[]): TreeViewItem | null => {
        for (const node of tree) {
          if (node.id === value) return node;
          if (node.children?.length) {
            const found = findNode(node.children);
            if (found) return found;
          }
        }
        return null;
      };

      const targetNode =
        field === "receivingUnitIds"
          ? findNode(receivingOptions)
          : findNode(ccReceivingOptions);

      if (!targetNode) return;
      if (field === "receivingUnitIds") {
        handleCheckChange(targetNode, false);
      } else {
        handleCcCheckChange(targetNode, false);
      }
    },
    [receivingOptions, ccReceivingOptions, handleCheckChange, handleCcCheckChange],
  );

  const handleSubmit = async (values: CreateOrEditLetter) => {
    try {
      await onSubmit(values);
      setHasSubmitted(true);
    } catch {
      window.scrollTo({ top: 0, behavior: "smooth" });
    }
  };

  const handleInvalidSubmit = () => {
    setHasSubmitted(true);
    setShouldScrollToError(true);
    toast.error(t("addRecord.formHasErrors"));
  };

  return {
    handleCheckChange,
    handleCcCheckChange,
    handleDeleteUnit,
    handleAdd,
    handleRemoveItem,
    handleSubmit,
    handleInvalidSubmit,
  };
}
