import { useMemo } from "react";

import { useAuth } from "@/shared/context/AuthContext";
import { useMyAdminUnits } from "@/user-management/hooks/useOrgAdminOrganizations";
import { useUnit } from "@/user-management/hooks/useUnit";
import { UnitDto } from "@/user-management/dto/unit/unitDto";
import { Entity } from "../types";

interface UseUnitsData {
  units: Entity[];
  fetchedUnits: UnitDto[];
  isLoading: boolean;
  setUnits: (units: Entity[]) => void;
}

interface UnitsParam {
  take: number;
  skip: number;
}

const normalizeName = (
  name: string | { am?: string; en?: string },
): Entity["name"] => {
  if (typeof name === "string") {
    return { am: name, en: name };
  }

  const fallback = name.en || name.am || "";
  return {
    am: name.am || fallback,
    en: name.en || fallback,
  };
};

const dedupeById = <T extends { id: string }>(items: T[]) => {
  const map = new Map<string, T>();

  items.forEach((item) => {
    if (!item?.id || map.has(item.id)) return;
    map.set(item.id, item);
  });

  return Array.from(map.values());
};

export const useUnitsData = (
  organizationId: string,
  params: UnitsParam,
): UseUnitsData => {
  const { user } = useAuth();
  const isOrganizationAdmin =
    user?.roles?.some((role) => role.key === "organization_admin") ?? false;

  const { units: adminUnits, isLoading: isAdminUnitsLoading } =
    useMyAdminUnits(organizationId, !isOrganizationAdmin);
  const { data: allUnitsResponse, isLoading: isAllUnitsLoading } =
    useUnit().getList(organizationId, params, isOrganizationAdmin);

  const fetchedUnits = useMemo(
    () => {
      const sourceUnits = isOrganizationAdmin
        ? (allUnitsResponse?.data?.items ?? [])
        : adminUnits;

      return dedupeById(sourceUnits as UnitDto[]);
    },
    [adminUnits, allUnitsResponse, isOrganizationAdmin],
  );

  const units = useMemo<Entity[]>(
    () =>
      fetchedUnits.map((unit) => ({
        id: unit.id,
        name: normalizeName(unit.name),
      })),
    [fetchedUnits],
  );

  // Kept for backwards compatibility. Units are derived from query data.
  const setUnits = (_: Entity[]) => {};

  return {
    units,
    fetchedUnits,
    isLoading: isOrganizationAdmin
      ? isAllUnitsLoading
      : isAdminUnitsLoading,
    setUnits,
  };
};
