import { type Transaction, getTransactionsHistory } from "@/utils/requests/transactions";
import type { PaymentCode } from "@/utils/requests/types";
import { LOG } from "@logger";
import { useQuery } from "@tanstack/react-query";
import { useCallback, useMemo, useState } from "react";

const log = LOG.extend("useTransactionsHistory");

// biome-ignore lint/style/useNamingConvention: <explanation>
export type OperatorsFilter = { [key in PaymentCode]: boolean };

const useTransactionsHistory = () => {
	log.verbose("useTransactionsHistory");

	const [referenceFilter, setReferenceFilter] = useState<string>("");
	// biome-ignore lint/style/useNamingConvention: <Types values are in uppercase>
	const [operatorsFilter, setOperatorsFilter] = useState<OperatorsFilter>({
		// biome-ignore lint/style/useNamingConvention: <Types values are in uppercase>
		OM: true,
		// biome-ignore lint/style/useNamingConvention: <Types values are in uppercase>
		MTN: true,
		// biome-ignore lint/style/useNamingConvention: <Types values are in uppercase>
		FLOOZ: true,
		// biome-ignore lint/style/useNamingConvention: <Types values are in uppercase>
		WAVE: true,
		// biome-ignore lint/style/useNamingConvention: <Types values are in uppercase>
		CB: true,
	});

	const { data, isLoading, error, refetch } = useQuery({
		queryKey: ["transactionsHistory"],
		queryFn: getTransactionsHistory,
	});

	const filterByReference = useCallback(
		(reference: string) => {
			if (!data?.length) return [];

			return data.filter(
				(transaction) => transaction.reference.includes(reference) && transaction.reference,
			);
		},
		[data],
	);

	const filterDataByReference = (data: Transaction[], reference: string) => {
		if (!data?.length) return [];

		return data.filter(
			(transaction) => transaction.reference.includes(reference) && transaction.reference,
		);
	};

	const filterByOperators = (data: Transaction[]) => {
		if (!data?.length) return [];
		// create a set
		const set = new Set<PaymentCode>();

		for (const key of Object.keys(operatorsFilter)) {
			if (operatorsFilter[key as keyof OperatorsFilter]) {
				set.add(key as PaymentCode);
			}
		}
		return data.filter((transaction) => {
			// return true if the set is empty, as there is no need to check
			if (set.size === 0) return true;
			// return true if the set contains the value
			return set.has(transaction.type_paiement_label);
		});
	};

	const transactionsHistory: Transaction[] = useMemo(() => {
		if (!data) return [];
		const filteredByOperators = filterByOperators(data);
		const filteredByReference = filterDataByReference(filteredByOperators, referenceFilter);
		return filteredByReference;
		// return filterByReference(referenceFilter);
	}, [data, referenceFilter, filterByOperators, filterDataByReference]);

	return {
		transactionsHistory,
		isLoading,
		error,
		refetch,
		setReferenceFilter,
		operatorsFilter,
		setOperatorsFilter,
	};
};

export default useTransactionsHistory;
