import { useQuery } from "@tanstack/react-query";
import { useEffect, useRef } from "react";

import type {
	Input,
	Output,
	Protocol,
	RequestStatusEnum,
	STATUS_CODE,
} from "@/types/index";
import { useConfig } from "@hooks/useConfig";
import { bungeeApiFetcher } from "@utils/fetcher";
import type {
	ManualRefuel,
	RequestType,
	Rewards,
	TxData,
} from "../common/quote/types";

export const useAutoHistory = ({
	userAddress,
	pageSize,
	pageNumber,
}: { userAddress: string; pageSize: number; pageNumber: number }) => {
	const { apiKey, baseUrl } = useConfig();
	const shouldFetch = !!userAddress;

	// biome-ignore format:
	const query = `${baseUrl}/bungee-auto/history?sender=${userAddress}&pageSize=${pageSize}&pageNumber=${pageNumber}`;

	const { data, isLoading, refetch, isSuccess } = useQuery({
		queryKey: ["bungee-order-history", apiKey, userAddress, pageNumber],
		queryFn: () => bungeeApiFetcher(query, apiKey),
		enabled: shouldFetch,
		refetchOnWindowFocus: false,
		retry: 2,
		staleTime: 10000,
	});

	const res = data?.result?.data?.requests as AutoOrderData[];
	const totalRequests = data?.result?.data?.totalRequests;
	const formattedData: AutoOrderData[] = res?.map((item) => {
		// calculating the swap time (in seconds)
		const timeDiffInSeconds = item.destTimestamp
			? item.destTimestamp - item.srcTimestamp
			: 0;

		return {
			...item,
			primaryInput: item.input?.[0],
			primaryOutput: item.output?.[0],
			swapTime: timeDiffInSeconds,
			isSwapRoute: item.requestType === "SWAP_REQUEST",
			routingMode: "auto",
		} as AutoOrderData;
	});

	const previousTotalPagesRef = useRef(Math.ceil(totalRequests / pageSize));

	useEffect(() => {
		if (!isLoading) {
			previousTotalPagesRef.current = Math.ceil(totalRequests / pageSize);
		}
	}, [isLoading, totalRequests, pageSize]);

	return {
		data: formattedData,
		totalPages: isLoading
			? previousTotalPagesRef.current
			: Math.ceil(totalRequests / pageSize),
		isLoading,
		refetch,
		isSuccess,
	};
};

export interface BaseOrderData {
	routingMode: "auto" | "manual";
	input: Input[];
	output: Output[];
	orderTimestamp: number;
	srcTimestamp: number;
	destTimestamp?: number;
	statusCode: STATUS_CODE;
	sender: string;
	receiver: string;
	requestHash: string; // derived for manual

	// derived
	status: keyof typeof RequestStatusEnum;
	swapTime: number;
	primaryInput: Input;
	primaryOutput: Output;
	isSwapRoute: boolean;
}

export interface AutoOrderData extends BaseOrderData {
	routingMode: "auto";
	txData: TxData | null;
	requestType: RequestType;
	quoteId: string;
	rewards?: Rewards;
}

export interface ManualOrderData extends BaseOrderData {
	routingMode: "manual";
	routeId: string;
	protocol: Protocol;
	estimatedFulfilTime: number;
	refuel?: ManualRefuel;
}

export type OrderData = AutoOrderData | ManualOrderData;
