import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { useTranslation } from "react-i18next";
import { useErrorHandler } from "@/shared/hooks/useErrorHandler";
import { useAuth } from "@/shared/context/AuthContext";

import {
  getUnitList,
  getMyAdminUnits,
  getUnitById,
  getUnitHierarchy,
  getCurrentUnitEmployees,
  createUnit,
  updateUnit,
  softDeleteUnit,
  relateUnitToUnit,
  getChildUnits,
  RelateUnitToUnitPayload,
  UnitPayload,
  UnitQueryParams,
} from "@/user-management/services/api/unitService";

export const useUnit = () => {
  const queryClient = useQueryClient();
  const { t } = useTranslation();
  const { handleError } = useErrorHandler(t);
  const { user } = useAuth();
  const isOrganizationAdmin =
    user?.roles?.some((role) => role.key === "organization_admin") ?? false;

  const getList = (
    organizationId: string,
    params?: UnitQueryParams,
    enabled: boolean = true,
  ) => {
    return useQuery({
      queryKey: ["unitList", organizationId, params ?? {}],
      queryFn: () => getUnitList(organizationId, params ?? {}),
      enabled: enabled && !!organizationId,
      staleTime: 0,
      refetchOnMount: "always",
      refetchOnWindowFocus: false,
    });
  };

  const getAccessibleList = (
    organizationId: string,
    params?: UnitQueryParams,
    enabled: boolean = true,
  ) => {
    return useQuery({
      queryKey: [
        "accessibleUnitList",
        organizationId,
        params ?? {},
        isOrganizationAdmin ? "all" : "my-admin-units",
      ],
      queryFn: async () => {
        const response = isOrganizationAdmin
          ? await getUnitList(organizationId, params ?? {})
          : await getMyAdminUnits(organizationId);
        const responseData = response.data;
        const items = Array.isArray(responseData)
          ? responseData
          : (responseData?.items ?? []);

        return {
          ...response,
          data: {
            ...(Array.isArray(responseData) ? {} : responseData),
            count: responseData?.count ?? items.length,
            items,
          },
        };
      },
      enabled: enabled && !!organizationId,
      staleTime: 0,
      refetchOnMount: "always",
      refetchOnWindowFocus: false,
    });
  };

  const getById = (id: string) => {
    return useQuery({
      queryKey: ["unit", id],
      queryFn: () => getUnitById(id),
      enabled: !!id,
    });
  };

  const getHierarchy = (id: string) => {
    return useQuery({
      queryKey: ["unitHierarchy", id],
      queryFn: () => getUnitHierarchy(id),
      enabled: !!id,
    });
  };

  const getEmployees = (id: string) => {
    return useQuery({
      queryKey: ["unitEmployees", id],
      queryFn: () => getCurrentUnitEmployees(id),
      enabled: !!id,
    });
  };

  const getChildren = (parentUnitId: string) => {
    return useQuery({
      queryKey: ["unitChildren", parentUnitId],
      queryFn: () => getChildUnits(parentUnitId),
      enabled: !!parentUnitId,
      staleTime: 0,
      refetchOnMount: "always",
      refetchOnWindowFocus: false,
    });
  };

  const create = useMutation({
    mutationFn: ({
      payload,
      successCallback,
    }: {
      payload: UnitPayload;
      successCallback: () => void;
    }) => createUnit(payload),
    onSuccess: (_data, variables) => {
      queryClient.invalidateQueries({ queryKey: ["unitList"] });
      queryClient.invalidateQueries({ queryKey: ["unitChildren"] });
      variables.successCallback();
    },
    onError: (error) => {
      handleError(error);
    },
  });

  const update = useMutation({
    mutationFn: ({
      id,
      payload,
      successCallback,
    }: {
      id: string;
      payload: UnitPayload;
      successCallback: () => void;
    }) => updateUnit(id, payload),
    onSuccess: (_data, variables) => {
      queryClient.invalidateQueries({ queryKey: ["unitList"] });
      queryClient.invalidateQueries({ queryKey: ["unitChildren"] });
      variables.successCallback();
    },
    onError: (error) => {
      handleError(error);
    },
  });

  const remove = useMutation({
    mutationFn: (id: string) => softDeleteUnit(id),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["unitList"] });
      queryClient.invalidateQueries({ queryKey: ["unitChildren"] });
    },
    onError: (error) => {
      handleError(error);
    },
  });

  const relate = useMutation({
    mutationFn: ({
      payload,
    }: {
      payload: RelateUnitToUnitPayload;
      successCallback?: () => void;
    }) => relateUnitToUnit(payload),
    onSuccess: (_data, variables) => {
      queryClient.invalidateQueries({ queryKey: ["unitList"] });
      queryClient.invalidateQueries({ queryKey: ["unitChildren"] });
      variables.successCallback?.();
    },
    onError: (error) => {
      handleError(error);
    },
  });
  return {
    getList,
    getAccessibleList,
    getById,
    getHierarchy,
    getEmployees,
    getChildren,
    createUnit: create.mutateAsync,
    isCreating: create.isPending,
    updateUnit: update.mutateAsync,
    isUpdating: update.isPending,
    removeUnit: remove.mutateAsync,
    isDeleting: remove.isPending,
    relateUnit: relate.mutateAsync,
    isRelating: relate.isPending,
  };
};
