import {
  useMutation,
  useQueries,
  useQuery,
  useQueryClient,
} from "@tanstack/react-query";
import {
  api,
  APP_CODE,
  ENTITY_TYPE,
  MAPPED_ENTITY_TYPE,
} from "../utils/common";
import {
  APIParamsProps,
  EntityListingResponse,
  EntityTableAPIProps,
  viewSettingsDropDownAPIProps,
} from "../../types/common";
import {
  commonGetDropdownDataAPI,
  createSavedFilter,
  deleteSavedFilter,
  getFilterEntityList,
  getFilterCriteriaByEntity,
  getSettingsData,
  saveSettingsData,
  updateSavedFilter,
  viewSettingsDropDown,
  getOperationList,
  getLayoutAttributes,
  getAttributes,
  getTableTabs,
  newCommonGetDropdownDataAPI,
} from "../utils/apiColumn";
import {
  FilterDataMainFilterEntityListProps,
  FilterMasterStateProps,
  FilterStateProps,
} from "../../types/filter";
import { CraftTableOptionsProps } from "../../types/table-options";
import { saveLayoutAPI } from "../services/saveLayoutAPI";
import { useMemo } from "react";

const entityListingCall = async ({
  page,
  size,
  entity_type = ENTITY_TYPE,
  tabs = {
    columnName: "status",
    sortBy: "ASC",
    value: "",
  },
  sortby = [
    {
      sortColum: "name",
      sortType: "ASC",
    },
    {
      sortColum: "status",
      sortType: "DSC",
    },
  ],
  quickFilter = [],
  attributeFilter = [],
  flatJson,
  getAllAttributes,
}: EntityTableAPIProps): Promise<{
  responseStatus: number;
  data: EntityListingResponse;
}> => {
  const url = `filter/${APP_CODE}`;

  const body = {
    entity_type,
    tabs,
    sortby,
    quickFilter,
    attributeFilter,
    flatJson,
    getAllAttributes,
  };

  const params: APIParamsProps = {
    page,
    size,
    // use_flatjson: true,
  };

  const response = await api.post(url, body, { params });

  return { responseStatus: response.status, data: response.data };
};

export const useEntityTableAPI = ({
  page = 0,
  size = 50,
  entity_type = ENTITY_TYPE,
  tabs = {
    columnName: "status",
    sortBy: "ASC",
    value: "",
  },
  quickFilter = [],
  sortby = [
    {
      sortColum: "name",
      sortType: "ASC",
    },
  ],
  attributeFilter = [],
  flatJson,
  module_code,
  getAllAttributes,
}: EntityTableAPIProps) => {
  const { data, isPending: isTableDataPending } = useQuery({
    queryKey: ["entityTable", page, size, tabs, quickFilter],
    queryFn: () =>
      entityListingCall({
        page: page + 1,
        size,
        entity_type,
        tabs,
        quickFilter,
        sortby,
        attributeFilter,
        flatJson,
        module_code,
        getAllAttributes,
      }),
  });

  return {
    tableData: data?.data,
    status: data?.responseStatus,
    isTableDataPending,
  };
};

//for saved filter API
export const useSavedFilterAPI = () => {
  const queryClient = useQueryClient();
  const savedMutation = useMutation({
    mutationKey: ["savedFilter"],
    mutationFn: ({
      entity_type,
      payload,
    }: {
      entity_type: string;
      payload: any;
    }) => {
      return createSavedFilter(entity_type, payload);
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["meta"] });
    },
  });

  return { savedMutation };
};

//for delete filter API
export const useDeleteFilterAPI = (tableStates: CraftTableOptionsProps) => {
  const queryClient = useQueryClient();
  const deleteMutation = useMutation({
    mutationKey: ["deleteFilter"],
    mutationFn: ({
      entity_type,
      payload,
    }: {
      entity_type: string;
      payload: any;
    }) => {
      return deleteSavedFilter(entity_type, payload);
    },
    onSuccess: async () => {
      queryClient.invalidateQueries({ queryKey: ["meta"] });

      const { filters, filterToDelete, filterMaster, setFilterMaster } =
        tableStates;

      if (filterToDelete?.value === filterMaster?.saved_filters?.selectedId) {
        const newFilterMasterState = {
          ...filterMaster,
          saved_filters: {
            ...(filterMaster?.saved_filters ?? {}),
            selectedId: "",
            selectedName: "",
            selectedCode: "",
            shareWithTeam: undefined,
            allowTeamEdit: undefined,
          },
          activeFilterTabIndex: -1,
        };

        setFilterMaster(newFilterMasterState as FilterMasterStateProps);

        const newState = {
          filterMaster: newFilterMasterState as FilterMasterStateProps,
          filters: filters,
        };

        const payload = {
          entity_type: MAPPED_ENTITY_TYPE,
          mapped_entity_type: ENTITY_TYPE,
          mapped_json: newState,
          type: "filter",
        };

        await saveLayoutAPI(payload);
      }
    },
  });

  return { deleteMutation };
};

// for updating saved filter API
export const useUpdateFilterAPI = () => {
  const queryClient = useQueryClient();

  const updateMutation = useMutation({
    mutationKey: ["updateFilter"],
    mutationFn: ({
      entity_type,
      payload,
    }: {
      entity_type: string;
      payload: any;
    }) => {
      return updateSavedFilter(entity_type, payload);
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["meta"] });
    },
  });

  return { updateMutation };
};

export const useCommonDropdownAPI = (column_list?: any, value?: string) => {
  // Step 1: Extract all keys and query types
  const dropdownConfigs = (column_list || [])
    ?.filter((col) => col?.datasource_list)
    ?.map((col) => ({
      key: col.attribute_key,
      dataSourceType: value ?? col.datasource_list ?? "STS",
    }));

  // Step 2: Use useQueries to fetch them all in parallel
  const dropdownResults = useQueries({
    queries: dropdownConfigs.map((cfg) => {
      return {
        queryKey: ["commonDropdown", cfg.dataSourceType],
        queryFn: () => commonGetDropdownDataAPI(cfg.dataSourceType, null),
        enabled: !!cfg.dataSourceType,
      };
    }),
  });

  // Step 3: Map results to keys
  const dropdownData: Record<string, any> = {};
  dropdownConfigs?.forEach((cfg, idx) => {
    dropdownData[cfg.key] = dropdownResults[idx].data;
  });

  return { dropdownData };
};

export const useCommonFilterDropdownAPI = (
  filters: FilterStateProps[],
  value?: string
) => {
  // Step 1: Extract all keys and query types
  const dropdownConfigs = useMemo(() => {
    return filters
      ?.filter((col) => col?.filter_attribute_data_type === "select")
      ?.map((col) => ({
        key: col?.filter_attribute,
        dataSourceType: value ?? col?.datasource_list ?? "STS",
      }));
  }, [filters]);

  // Step 2: Use useQueries to fetch them all in parallel
  const dropdownResults = useQueries({
    queries: dropdownConfigs.map((cfg) => {
      return {
        queryKey: ["commonDropdown", cfg?.dataSourceType],
        queryFn: () =>
          newCommonGetDropdownDataAPI({
            entity_type: ENTITY_TYPE,
            attribute_key: cfg?.key,
          }),
        enabled: !!cfg?.dataSourceType,
      };
    }),
  });

  // Step 3: Map results to keys
  const dropdownFilterData: Record<string, any> = {};
  dropdownConfigs?.forEach((cfg, idx) => {
    dropdownFilterData[cfg.key] = dropdownResults[idx].data;
  });

  return { dropdownFilterData };
};

//ALL VIEW SETTINGS API

export const useSettingsDropDownAPI = ({
  entity_type,
  column,
  sort_by,
}: viewSettingsDropDownAPIProps) => {
  const {
    data: settingsTabDropdownData,
    isPending: settingsTabDropdownPending,
  } = useQuery({
    queryKey: ["viewsettingsDropdown", entity_type, column, sort_by],
    queryFn: () =>
      viewSettingsDropDown({
        entity_type,
        column,
        sort_by,
      }),
    enabled: !!column && !!entity_type && !!sort_by,
  });

  return { settingsTabDropdownData, settingsTabDropdownPending };
};

export const useSaveSettingsDataAPI = (entity_type: string) => {
  const queryClient = useQueryClient();
  const saveSettingsDataMutation = useMutation({
    mutationKey: ["saveSettingsData", entity_type],
    mutationFn: ({ payload }: { payload: any }) => {
      return saveSettingsData(payload);
    },
    onSuccess: () => {
      queryClient.invalidateQueries({
        queryKey: ["entityTable"],
      });

      queryClient.invalidateQueries({
        queryKey: ["getSettingsData", entity_type],
      });
    },
    onError: (error: any) => {
      const msg = error?.response?.data?.message;
    },
  });

  return { saveSettingsDataMutation };
};

export const useGetSettingsDataAPI = (entity_type: string, type: string) => {
  const {
    data: getSettingsAPIData,
    isSuccess: getSettingsAPIDataSuccess,
    isPending: getSettingsAPIDataPending,
  } = useQuery({
    queryKey: ["getSettingsData", entity_type],
    queryFn: () => getSettingsData(entity_type, type),
    enabled: !!entity_type,
  });

  return {
    getSettingsAPIData,
    getSettingsAPIDataSuccess,
    getSettingsAPIDataPending,
  };
};

export const useGetFilterEntityListAndCriteria = ({
  entity_type,
  selectedFilterEntity,
}: {
  entity_type: string;
  selectedFilterEntity: FilterDataMainFilterEntityListProps | undefined;
}) => {
  const filterEntityList = useQuery({
    queryKey: ["filterEntityList", entity_type],
    queryFn: () => getFilterEntityList(entity_type),
    enabled: !!entity_type,
  });

  const filterEntityWiseCriteria = useQuery({
    queryKey: ["filterEntityWiseCriteria", selectedFilterEntity],
    queryFn: () => getAttributes(selectedFilterEntity?.value as string),
    enabled: !!selectedFilterEntity,
  });

  return { filterEntityList, filterEntityWiseCriteria };
};

export const useGetAttributes = (
  entity_type: string,
  element_type?: string
) => {
  const attributes = useQuery({
    queryKey: ["attributes", entity_type, element_type],
    queryFn: () => getAttributes(entity_type, element_type),
    enabled: !!entity_type, // optional safety
  });

  return { attributes };
};
export const useGetOperationList = () => {
  // First query to get meta data
  const operationList = useQuery({
    queryKey: ["operationList"],
    queryFn: () => getOperationList(),
  });

  return { operationList };
};

export const useGetLayoutAttributes = ({
  entity_type,
  element_type,
}: {
  entity_type: string;
  element_type?: string;
}) => {
  // First query to get meta data
  const layoutAttributes = useQuery({
    queryKey: ["layoutAttributes", entity_type, element_type],
    queryFn: () =>
      getLayoutAttributes({
        entity_type,
        element_type,
      }),
  });

  return { layoutAttributes };
};

export const useGetTableTabs = (payload: any) => {
  const { data: tableTabs, isLoading } = useQuery({
    queryKey: ["tableTabs", payload],
    queryFn: () => getTableTabs(payload),
  });
  return { tableTabs, isLoading };
};

export const useDropdownAPI = ({
  entity_type,
  attribute_key,
  inactiveIds,
  parentId,
  data,
  enabled = true,
}: {
  entity_type: string;
  attribute_key?: string;
  inactiveIds?: string | null;
  parentId?: number | string;
  data?: any;
  enabled?: boolean;
}) => {
  const query = useQuery({
    queryKey: [
      "commonDropdown",
      entity_type,
      attribute_key,
      inactiveIds,
      parentId,
    ],
    queryFn: () =>
      newCommonGetDropdownDataAPI({
        entity_type,
        attribute_key,
        inactiveIds,
        parentId,
        data,
      }),
    enabled, // prevents auto call unless needed
    staleTime: 5 * 60 * 1000, // cache for 5 mins
  });

  return {
    ...query,
    dropdownData: query.data || [],
  };
};
// export const useGetSettingsColumnAttributes = (entity_type: string) => {
//   // First query to get meta data
//   const settingsColumnAttributes = useQuery({
//     queryKey: ["settingsColumnAttributes", entity_type],
//     queryFn: () => getAttributes(entity_type),
//   });

//   return { settingsColumnAttributes };
// };
