import { LazyStore } from '@tauri-apps/plugin-store';
import { writable, get } from 'svelte/store';
import { platform, arch } from '@tauri-apps/plugin-os';
import { appDataDir } from '@tauri-apps/api/path';
import { ensureLibraryStructure, selectDirectory } from './file_utils.js';

// Define the settings structure
/** @typedef {Object} Settings
 * @property {string} [libraryDir] - Path to library directory
 * @property {string} [defaultPlatform] - Default platform ('auto', 'windows', 'linux', 'macos')
 * @property {string} [defaultArch] - Default architecture ('x86_64', 'arm64', etc.)
 * @property {string} [theme] - Theme ('light', 'dark')
 * @property {boolean} [autoCreateShortcuts] - should smoothie create a shortcut to newly installed blender versions
 * @property {boolean} [keepDownloadedArchives] - Whether to keep downloaded archives after extraction
 * @property {boolean} [closeToTray] - Whether to close the window to the tray instead of exiting when the close button is clicked
 */

// Settings lazy store
const settingsStore = new LazyStore('settings.json');
export const currentSettings = writable(/** @type {Settings} */ ({}));

export const BASE_LIBRARY_DIR = 'smoothie-library';
let DEFAULT_SETTINGS = null;

export async function initSettings() {
	const detectedPlatform = await detectPlatform();
	const detectedArch = await detectArch();
	const defaultLibraryDir = await appDataDir();

	DEFAULT_SETTINGS = {
		libraryDir: defaultLibraryDir, // Will be filled with default library directory
		defaultPlatform: detectedPlatform, //Automatic
		defaultArch: detectedArch,
		keepDownloadedArchives: false,
		autoCreateShortcuts: true,
		theme: 'light', //
		closeToTray: true
	};
}

/**
 * Get the current settings, filling with defaults if missing.
 * @returns {Promise<Settings>}
 */
export async function getSettings() {
	if (DEFAULT_SETTINGS === null) {
		await initSettings();
	}
	try {
		// Get all stored values
		const storeEntries = await settingsStore.entries();

		// Store empty, load defaults
		if (storeEntries.length === 0) {
			await resetSettings();
		}

		//load settings object and patch with defaults for missing fields
		const settings = Object.fromEntries(storeEntries);
		const filledSettings = { ...DEFAULT_SETTINGS, ...settings };
		currentSettings.set(filledSettings);
		await ensureLibraryStructure(filledSettings.libraryDir);
		return filledSettings;
	} catch (error) {
		console.error('Error loading settings:', error);
		currentSettings.set(DEFAULT_SETTINGS);
		return DEFAULT_SETTINGS;
	}
}

/**
 * @typedef {Partial<Settings>} PartialSettings
 */
export async function saveSettings(newSettings) {
	try {
		for (const [key, value] of Object.entries(newSettings)) {
			await settingsStore.set(key, value);
		}
		if (newSettings.libraryDir) {
			//if new library dir check it
			await ensureLibraryStructure(newSettings.libraryDir);
		}
		await settingsStore.save();
		let completeSettings = { ...get(currentSettings), ...newSettings };
		currentSettings.set(completeSettings);
	} catch (error) {
		console.error('Error saving settings:', error);
		throw error;
	}
}

/**
 * Clear store and reset all settings to defaults.
 * @returns {Promise<Settings>}
 */
export async function resetSettings() {
	try {
		await settingsStore.clear();
		await saveSettings(DEFAULT_SETTINGS);

		return DEFAULT_SETTINGS;
	} catch (error) {
		console.error('Error resetting settings:', error);
		throw error;
	}
}

/**
 * Detect the current platform, mapping to our supported values.
 * @returns {Promise<string>} 'windows', 'linux', or 'macos'
 */
async function detectPlatform() {
	try {
		const currentPlatform = platform();
		// Map from OS plugin values to our settings values (desktop only)
		const platformMap = {
			linux: 'linux',
			windows: 'windows',
			darwin: 'macos',
			macos: 'macos'
		};

		// Only desktop platforms are supported
		if (currentPlatform in platformMap) {
			return currentPlatform;
		}
		console.warn(`Platform "${currentPlatform}" is not supported, defaulting to linux`);
		return 'linux';
	} catch (error) {
		console.error('Error detecting platform:', error);
		return 'linux'; // fallback
	}
}
/**
 * Detect the current platform, mapping to our supported values.
 * @returns {Promise<string>} 'windows', 'linux', or 'macos'
 */
async function detectArch() {
	try {
		const currentArch = arch();
		const archmap = {
			x86_64: 'x64',
			arm: 'arm64',
			aarch64: 'arm64'
		};
		if (currentArch in archmap) {
			return currentArch;
		}
		console.warn(`Architecture "${currentArch}" is not supported, defaulting to x64`);
		return 'x64';
	} catch (error) {
		console.error('Error detecting platform:', error);
		return 'linux'; // fallback
	}
}
export { selectDirectory };
