import { browser } from '$app/environment';

/**
 * View-level UI preferences. Persisted to localStorage so collapse state,
 * thumb size, etc. survive a refresh. Same module is reused by the
 * timeline page and the preview overlay so the sidebar toggle stays in
 * sync across views (matches mule-image's "intelligent preview recall").
 */
const STORAGE_KEY = 'mule_view';

/**
 * Mirrors mule-image's mule-image-viewSettingsStore thumbnail presets so the
 * UX scales the same way: five steps with `M` as the default. Labels are
 * cosmetic; the numbers feed the `minmax(<size>px, 1fr)` grid template.
 */
export const THUMBNAIL_SIZE_PRESETS = [96, 128, 160, 208, 272] as const;
export type ThumbnailSize = (typeof THUMBNAIL_SIZE_PRESETS)[number];
export const THUMBNAIL_SIZE_LABELS = ['XS', 'S', 'M', 'L', 'XL'] as const;
export const DEFAULT_THUMBNAIL_SIZE: ThumbnailSize = 160;

interface Persisted {
	rightSidebarCollapsed?: boolean;
	leftSidebarCollapsed?: boolean;
	thumbnailSize?: ThumbnailSize;
	leftSidebarWidth?: number;
	rightSidebarWidth?: number;
}

export const MIN_LEFT_WIDTH = 180;
export const MAX_LEFT_WIDTH = 480;
export const DEFAULT_LEFT_WIDTH = 224;
export const MIN_RIGHT_WIDTH = 220;
export const MAX_RIGHT_WIDTH = 480;
export const DEFAULT_RIGHT_WIDTH = 280;

function clamp(n: number, lo: number, hi: number): number {
	return Math.min(hi, Math.max(lo, n));
}

function isThumbnailSize(n: unknown): n is ThumbnailSize {
	return (
		typeof n === 'number' &&
		(THUMBNAIL_SIZE_PRESETS as readonly number[]).includes(n)
	);
}

function loadInitial(): Persisted {
	if (!browser) return {};
	try {
		const raw = localStorage.getItem(STORAGE_KEY);
		return raw ? (JSON.parse(raw) as Persisted) : {};
	} catch {
		return {};
	}
}

const initial = loadInitial();

export const view = $state<{
	rightSidebarCollapsed: boolean;
	leftSidebarCollapsed: boolean;
	thumbnailSize: ThumbnailSize;
	leftSidebarWidth: number;
	rightSidebarWidth: number;
}>({
	rightSidebarCollapsed: initial.rightSidebarCollapsed ?? false,
	leftSidebarCollapsed: initial.leftSidebarCollapsed ?? false,
	thumbnailSize: isThumbnailSize(initial.thumbnailSize)
		? initial.thumbnailSize
		: DEFAULT_THUMBNAIL_SIZE,
	leftSidebarWidth: clamp(
		typeof initial.leftSidebarWidth === 'number' ? initial.leftSidebarWidth : DEFAULT_LEFT_WIDTH,
		MIN_LEFT_WIDTH,
		MAX_LEFT_WIDTH
	),
	rightSidebarWidth: clamp(
		typeof initial.rightSidebarWidth === 'number' ? initial.rightSidebarWidth : DEFAULT_RIGHT_WIDTH,
		MIN_RIGHT_WIDTH,
		MAX_RIGHT_WIDTH
	)
});

function persist(): void {
	if (!browser) return;
	const payload: Persisted = {
		rightSidebarCollapsed: view.rightSidebarCollapsed,
		leftSidebarCollapsed: view.leftSidebarCollapsed,
		thumbnailSize: view.thumbnailSize,
		leftSidebarWidth: view.leftSidebarWidth,
		rightSidebarWidth: view.rightSidebarWidth
	};
	localStorage.setItem(STORAGE_KEY, JSON.stringify(payload));
}

export function setLeftSidebarWidth(px: number): void {
	view.leftSidebarWidth = clamp(Math.round(px), MIN_LEFT_WIDTH, MAX_LEFT_WIDTH);
	persist();
}

export function setRightSidebarWidth(px: number): void {
	view.rightSidebarWidth = clamp(Math.round(px), MIN_RIGHT_WIDTH, MAX_RIGHT_WIDTH);
	persist();
}

export function setThumbnailSize(size: ThumbnailSize): void {
	view.thumbnailSize = size;
	persist();
}

export function toggleRightSidebar(): void {
	view.rightSidebarCollapsed = !view.rightSidebarCollapsed;
	persist();
}

export function setRightSidebarCollapsed(collapsed: boolean): void {
	view.rightSidebarCollapsed = collapsed;
	persist();
}

export function toggleLeftSidebar(): void {
	view.leftSidebarCollapsed = !view.leftSidebarCollapsed;
	persist();
}
