import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import {
  createOrganization,
  OrgQueryParams,
  OrganizationPayload,
  getOrganizationById,
  updateOrganization,
  activateOrganization,
  deActivateOrganization,
  getOrganizationsWithAdminFlag,
  softDeleteOrganization,
} from "@/shared/services/organizationsService";
import {
  OrganizationAdminsDto,
  OrganizationDetailDTO,
  OrganizationDto,
} from "@/shared/dto/organization/organizationDto";
import { useNavigate } from "react-router-dom";
import { toast } from "sonner";
import { useTranslation } from "react-i18next";
import { useErrorHandler } from "@/shared/hooks/useErrorHandler";

interface ApiResponse<T> {
  success: boolean;
  data: T;
  message?: string;
}

interface Unit {
  id: string;
  name: string;
  departments: any[];
  isExpanded?: boolean;
}

export interface Organization {
  id: string;
  name: string;
  units: Unit[];
  isExpanded?: boolean;
}

export const useOrganizations = (
  type: "Admin" | "Org",
  params?: OrgQueryParams,
) => {
  const queryClient = useQueryClient();
  const navigate = useNavigate();
  const { t } = useTranslation();
  const { handleError } = useErrorHandler(t);

  const {
    data: organizationsResponse,
    isLoading,
    isError,
    refetch,
  } = useQuery({
    queryKey: ["organizations", params],
    queryFn: async () => {
      const { data } = await getOrganizationsWithAdminFlag(params);

      return {
        count: data.count as number,
        items: data.items as OrganizationDto[],
      };
    },
    staleTime: 5 * 60 * 1000,
    retry: false,
    enabled: !!(type === "Org"),
  });

  const {
    data: organizationsAdminsResponse,
    isLoading: isLoadingAdmins,
    isError: isErrorAdmins,
    refetch: refetchAdmins,
  } = useQuery({
    queryKey: ["organizationAdmins", params?.skip, params?.take, params?.name, params?.orderBy],
    queryFn: async () => {
      const { data } = await getOrganizationsWithAdminFlag(params);
      return {
        count: data.count as number,
        items: data.items as OrganizationAdminsDto[],
      };
    },
    staleTime: 5 * 60 * 1000,
    retry: false,
    enabled: !!(type === "Admin"),
  });

  const {
    mutate: createMutation,
    isPending: isOrganizationCreating,
    isError: organizationCreationError,
    status: organizationCreationStatus,
  } = useMutation({
    mutationFn: async (payload: OrganizationPayload) => {
      const { data } = await createOrganization(payload);
      return data;
    },
    onSuccess: () => {
      toast.success("Organization created successfully!", {
        description: "Redirecting...",
      });

      navigate("/user-management/organizations");
      queryClient.invalidateQueries({ queryKey: ["organizations"] });
    },
    onError: (error) => {
      handleError(error);
    },
  });
  const {
    mutate: editMutation,
    isPending: isOrganizationEditing,
    isError: organizationEditError,
    status: organizationEditStatus,
  } = useMutation({
    mutationFn: async ({
      id,
      payload,
    }: {
      id: string;
      payload: OrganizationPayload;
    }) => {
      const { data } = await updateOrganization(id, payload);
      return data;
    },
    onSuccess: () => {
      toast.success("Organization created successfully!", {
        description: "Redirecting...",
      });

      navigate("/user-management/organizations");
      queryClient.invalidateQueries({ queryKey: ["organizations"] });
    },
    onError: (error) => {
      handleError(error);
    },
  });
  const { mutate: activateMutation, isPending: isOrganizationActivating } =
    useMutation({
      mutationFn: async ({ id }: { id: string }) => {
        const { data } = await activateOrganization(id);
        return data;
      },
      onSuccess: () => {
        toast.success("Organization Activated successfully!", {
          description: "Redirecting...",
        });

        navigate("/user-management/organizations");
        queryClient.invalidateQueries({ queryKey: ["organizations"] });
      },
      onError: (error) => {
        handleError(error);
      },
    });
  const { mutate: deActivateMutation, isPending: isOrganizationDeactivating } =
    useMutation({
      mutationFn: async ({ id }: { id: string }) => {
        const { data } = await deActivateOrganization(id);
        return data;
      },
      onSuccess: () => {
        toast.success("Organization De-Activated successfully!", {
          description: "Redirecting...",
        });

        navigate("/user-management/organizations");
        queryClient.invalidateQueries({ queryKey: ["organizations"] });
      },
      onError: (error) => {
        handleError(error);
      },
    });
  const { mutate: deleteMutation, isPending: isOrganizationDeleting } =
    useMutation({
      mutationFn: async ({ id }: { id: string }) => {
        const { data } = await softDeleteOrganization(id);
        return data;
      },
      onSuccess: () => {
        toast.success("Organization Deleted successfully!", {
          description: "Redirecting...",
        });

        navigate("/user-management/organizations");
        queryClient.invalidateQueries({ queryKey: ["organizations"] });
      },
      onError: (error) => {
        handleError(error);
      },
    });

  const { mutate: getOrganization, isPending: isFetchingOrganization } =
    useMutation({
      mutationFn: async (id: string) => {
        const { data } = await getOrganizationById(id);
        return data;
      },
      onSuccess: (data) => {
        return data;
      },
    });

  return {
    organizationsResponse,
    isLoading,
    isError,
    refetch,
    createOrganization: createMutation,
    editOrganization: editMutation,
    isCreating: isOrganizationCreating,
    isEditing: isOrganizationEditing,
    editStatus: organizationEditStatus,
    organizationCreationError,
    organizationEditError,
    getOrganizationByDetails: getOrganization,
    isFetchingOrganization,
    activateOrganization: activateMutation,
    isOrganizationActivating,
    deactivateOrganization: deActivateMutation,
    isOrganizationDeactivating,
    deleteOrganization: deleteMutation,
    isOrganizationDeleting,
    organizationsAdminsResponse,
    isLoadingAdmins,
    isErrorAdmins,
    refetchAdmins,
  };
};

export function useOrganizationDetail(type: string, id: string) {
  const query = useQuery<{ items: OrganizationDetailDTO }, Error>({
    queryKey: ["organization-detail", id],
    queryFn: async () => {
      const { data } = await getOrganizationById(id);
      return { items: data };
    },
    staleTime: 5 * 60 * 1000,
    retry: false,
    enabled: type === "Org" && !!id,
  });

  return {
    organizationsDetailResponse: query.data,
    isDetailLoading: query.isLoading,
    isDetailError: query.isError,
  };
}
