import { DEFAULT_LOCALE } from "@providers/LocalizationProvider";
import { createSlice } from "@reduxjs/toolkit";

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

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

const initialState: SettingsParams = {
	isSettingsVisible: false,
	sound: bungeeLocalStore?.settings?.sound || false,
	dynamicSlippage: bungeeLocalStore?.settings?.dynamicSlippage ?? true,
	slippage: bungeeLocalStore?.settings?.slippage,
	language: bungeeLocalStore?.settings?.locale || DEFAULT_LOCALE,
	notifications: bungeeLocalStore?.settings?.notifications || false,
	smartBatching: bungeeLocalStore?.settings?.smartBatching ?? true, // true by default
	routingMode: bungeeLocalStore?.settings?.routingMode || "auto",
	originalRoutingMode:
		bungeeSessionStore?.settings?.originalRoutingMode || null,
};

export function updateLocalStorage(
	section: string,
	key: string,
	// biome-ignore lint/suspicious/noExplicitAny: <explanation>
	value: any,
) {
	let bungee =
		typeof window !== "undefined"
			? JSON.parse(localStorage.getItem("bungee") || "{}")
			: {};
	if (!bungee) bungee = {};
	if (!bungee[section]) bungee[section] = {};

	bungee = {
		...bungee,
		[section]: {
			...bungee[section],
			[key]: value,
		},
	};

	localStorage.setItem("bungee", JSON.stringify(bungee));
}

export function updateSessionStorage(
	section: string,
	key: string,
	// biome-ignore lint/suspicious/noExplicitAny: <explanation>
	value: any,
) {
	let bungee =
		typeof window !== "undefined"
			? JSON.parse(sessionStorage.getItem("bungee") || "{}")
			: {};
	if (!bungee) bungee = {};
	if (!bungee[section]) bungee[section] = {};

	bungee = {
		...bungee,
		[section]: {
			...bungee[section],
			[key]: value,
		},
	};

	sessionStorage.setItem("bungee", JSON.stringify(bungee));
}

const settingsSlice = createSlice({
	name: "settings",
	initialState,
	reducers: {
		toggleSettingsModal: (state, action) => {
			state.isSettingsVisible = action.payload;
		},
		setSound: (state, action) => {
			state.sound = action.payload;
			updateLocalStorage("settings", "sound", action.payload);
		},
		toggleDynamicSlippage: (state, action) => {
			state.dynamicSlippage = action.payload;
			updateLocalStorage("settings", "dynamicSlippage", action.payload);
		},
		setSlippage: (state, action) => {
			state.slippage = action.payload;
			updateLocalStorage("settings", "slippage", action.payload);
		},
		setLanguage: (state, action) => {
			state.language = action.payload;
			updateLocalStorage("settings", "locale", action.payload);
		},
		enableNotifications: (state, action) => {
			state.notifications = action.payload;
			updateLocalStorage("settings", "notifications", action.payload);
		},
		toggleSmartBatching: (state, action) => {
			state.smartBatching = action.payload;
			updateLocalStorage("settings", "smartBatching", action.payload);
		},
		setRoutingMode: (state, action) => {
			const newMode = action.payload;
			const currentMode = state.routingMode;
			const isModeChange = currentMode !== newMode;

			state.routingMode = newMode;
			updateLocalStorage("settings", "routingMode", newMode);

			// Clear originalRoutingMode when user manually changes mode, but NOT during:
			//
			// Scenario 1: Auto-switch (currentMode === originalRoutingMode)
			//   - User is on "auto", no auto routes available, we auto-switch to "manual"
			//   - currentMode = "auto", originalRoutingMode = "auto" (just set)
			//   - currentMode !== originalRoutingMode = false → don't clear
			//
			// Scenario 2: Auto-restore (handled in useTemporaryRoutingMode.ts)
			//   - Routes become available, hook restores and clears originalRoutingMode
			//   - This reducer also clears it as a safeguard when newMode === originalRoutingMode
			//
			// Manual changes: Any mode change where currentMode !== originalRoutingMode
			//   - User manually switches back to original mode → clear
			//   - User manually switches to other mode → clear (though impossible with 2 modes)
			if (
				state.originalRoutingMode !== null &&
				isModeChange &&
				currentMode !== state.originalRoutingMode // Not Scenario 1 (auto-switch)
			) {
				// User manually changed mode - clear the temporary switch tracking
				state.originalRoutingMode = null;
				updateSessionStorage("settings", "originalRoutingMode", null);
			}
		},
		setOriginalRoutingMode: (state, action) => {
			state.originalRoutingMode = action.payload;
			updateSessionStorage("settings", "originalRoutingMode", action.payload);
		},
	},
});

export interface SettingsParams {
	isSettingsVisible: boolean;
	sound: boolean;
	dynamicSlippage: boolean;
	slippage: string;
	language: string;
	notifications: boolean;
	smartBatching: boolean;
	routingMode: "auto" | "manual";
	originalRoutingMode: "auto" | "manual" | null;
}

export const {
	toggleSettingsModal,
	setSound,
	toggleDynamicSlippage,
	setSlippage,
	setLanguage,
	enableNotifications,
	toggleSmartBatching,
	setRoutingMode,
	setOriginalRoutingMode,
} = settingsSlice.actions;
export default settingsSlice.reducer;
