import { createSlice } from "@reduxjs/toolkit";

import type { Token } from "@/types/index";
import type { ManualOrderData } from "@hooks/apis/auto/useAutoHistory";
import { updateLocalStorage } from "./settingsSlice";

export enum ScreenTab {
	HOME = "home",
	REVIEW = "review",
	INFLIGHT = "inflight",
}

const bungeeLocalStore =
	typeof window !== "undefined"
		? JSON.parse(localStorage.getItem("bungee") || "{}")
		: {};

const initialState: GlobalParams = {
	supportedChains: [],
	shortTokenList: [],
	largeTokenList: [],
	showRecipientModal: false,
	showCompareModal: false,
	showHistoryModal: false,
	screenTab: ScreenTab.HOME,
	importedTokens: bungeeLocalStore?.tokens?.imported,
	manualHistory: bungeeLocalStore?.history?.manual || {}, // Ensure it's an object
};

const globalStates = createSlice({
	name: "global",
	initialState,
	reducers: {
		setSupportedChains: (state, action) => {
			state.supportedChains = action.payload;
		},
		setShortTokenList: (state, action) => {
			state.shortTokenList = action.payload;
		},
		setLargeTokenList: (state, action) => {
			state.largeTokenList = action.payload;
		},
		toggleRecipientModal: (state, action) => {
			state.showRecipientModal = action.payload;
		},
		toggleCompareModal: (state, action) => {
			state.showCompareModal = action.payload;
		},
		setScreenTab: (state, action) => {
			state.screenTab = action.payload;
		},
		toggleHistoryModal: (state, action) => {
			state.showHistoryModal = action.payload;
		},
		importToken: (state, action: { payload: { token: Token } }) => {
			const importedTokens = state.importedTokens || {};
			const id = action.payload.token.chainId;
			const tags = action.payload.token?.tags || [];

			// Add "imported" tag only if not already present
			const updatedTags = tags.includes("imported") ? tags : [...tags, "imported"];
			const token = { ...action.payload.token, tags: updatedTags };

			if (!importedTokens[id]) {
				importedTokens[id] = [token];
			} else {
				const _tokens = importedTokens[id];
				const alreadyExists = _tokens.some(
					(existingToken) =>
						existingToken.address.toLowerCase() === token.address.toLowerCase(),
				);

				if (!alreadyExists) {
					importedTokens[id].push(token);
				}
			}

			state.importedTokens = importedTokens;
			updateLocalStorage("tokens", "imported", importedTokens);
		},
		updateManualHistory: (
			state,
			action: { payload: { address: string; data: ManualOrderData } },
		) => {
			const { address, data } = action.payload;
			const lowerCasedAddress = address?.toLowerCase();

			if (!state.manualHistory) state.manualHistory = {};

			const existingEntries = state.manualHistory[lowerCasedAddress] || [];
			const existingEntryIndex = existingEntries.findIndex(
				(entry) => entry.routeId === data?.routeId,
			);

			if (existingEntryIndex !== -1) {
				// Update the existing entry with the new data
				existingEntries[existingEntryIndex] = data;
			} else {
				// Add new entry if it doesn't exist
				existingEntries.push(data);
			}

			state.manualHistory[lowerCasedAddress] = existingEntries;
			const existingStore = JSON.parse(localStorage.getItem("bungee") || "{}");
			localStorage.setItem(
				"bungee",
				JSON.stringify({
					...existingStore,
					history: {
						...existingStore.history,
						manual: state.manualHistory,
					},
				}),
			);
		},
		resetManualHistory: (
			state,
			action: { payload: { address: string; data: ManualOrderData[] } },
		) => {
			const { address, data } = action.payload;
			if (!address) return; // Skip logging to local storage if address is undefined
			const lowerCasedAddress = address.toLowerCase();
			if (!state.manualHistory) state.manualHistory = {};

			state.manualHistory[lowerCasedAddress] = data;

			// Update local storage with the new manual history
			const existingStore = JSON.parse(localStorage.getItem("bungee") || "{}");
			localStorage.setItem(
				"bungee",
				JSON.stringify({
					...existingStore,
					history: {
						...existingStore.history,
						manual: state.manualHistory,
					},
				}),
			);
		},
	},
});

export const {
	setSupportedChains,
	setShortTokenList,
	setLargeTokenList,
	toggleRecipientModal,
	toggleCompareModal,
	setScreenTab,
	toggleHistoryModal,
	importToken,
	updateManualHistory,
	resetManualHistory,
} = globalStates.actions;
export default globalStates.reducer;

export interface GlobalParams {
	supportedChains: Chain[];
	shortTokenList: { [chainId: number]: Token[] };
	largeTokenList: { [chainId: number]: Token[] };
	showRecipientModal: boolean;
	showCompareModal: boolean;
	showHistoryModal: boolean;
	screenTab: ScreenTab;
	importedTokens?: { [chainId: number]: Token[] };
	manualHistory?: { [address: string]: ManualOrderData[] };
}

export interface Chain {
	chainId: number;
	name: string;
	isL1: boolean;
	sendingEnabled: boolean;
	icon: string;
	receivingEnabled: boolean;
	rpcs: string[];
	explorers: string[];
	currency: Currency;
}

interface Currency extends Token {
	minNativeCurrencyForGas: string;
}
