export const GENRES = {
	'2042': 'Action',
	'1212': 'Sci-Fi',
	'4910': 'Crime',
	'62': 'Drama',
	'82': 'Comedy',
	'293': 'Animation',
	'36': 'Documentary',
	'5024': 'Horror',
	'4835': 'Romance',
	'4428': 'Thriller',
	'5709': 'War',
	'14124': 'Western',
	'218': 'Food',
	'396654': 'Reality',
	'19618': 'Travel',
	'17565': 'Mini Series',
	'2008': 'Mystery',
	'235': 'Family',
	'480': 'Fantasy'
};

export const SECTION_TYPES = [
	{ value: 'resume', label: 'Resume / Next Up' },
	{ value: 'items', label: 'Items (filtered)' },
	{ value: 'userviews', label: 'Libraries' },
	{ value: 'boxset', label: 'Box Set' },
	{ value: 'collections', label: 'Collections' },
	{ value: 'latestepisodereleases', label: 'Latest episode releases' },
	{ value: 'latestmoviereleases', label: 'Latest movie releases' },
	{ value: 'latestmediablock', label: 'Latest media' }
];

export const COLLECTION_TYPES = [
	{ value: '', label: '(none)' },
	{ value: 'movies', label: 'Movies' },
	{ value: 'tvshows', label: 'TV Shows' },
	{ value: 'boxsets', label: 'Box Sets' }
];

export const ITEM_TYPES = ['Movie', 'Series', 'Episode', 'BoxSet'];

export const SORT_OPTIONS = [
	{ value: '', label: '(none)' },
	{ value: 'default', label: 'Default (boxset)' },
	{ value: 'DatePlayed', label: 'Date played' },
	{ value: 'DateLastContentAdded,SortName', label: 'Date added' },
	{ value: 'ProductionYear,PremiereDate,SortName', label: 'Release year' },
	{ value: 'CommunityRating', label: 'Community rating' },
	{ value: 'CriticRating,SortName', label: 'Critic rating' },
	{ value: 'DateCreated,SortName', label: 'Date created' },
	{ value: 'Random', label: 'Random' },
	{ value: 'SortName', label: 'Name' }
];

export const IMAGE_TYPES = [
	{ value: '', label: 'Default' },
	{ value: 'Thumb', label: 'Thumb' },
	{ value: 'Primary', label: 'Primary / Poster' }
];

export const PAGE_ICONS = {
	edit: 'edit',
	sync: 'sync',
	collections: 'collections',
	settings: 'settings'
};

export const SECTION_ICONS = {
	resume: 'resume',
	items: 'items',
	userviews: 'userviews',
	boxset: 'boxset',
	collections: 'collections',
	latestepisodereleases: 'latestepisodereleases',
	latestmoviereleases: 'latestmoviereleases',
	latestmediablock: 'latestmediablock'
};

export function genId() {
	return crypto.randomUUID().replace(/-/g, '').slice(0, 32);
}

export function createEmptySection(userId) {
	return {
		UserId: userId,
		Name: 'New Section',
		CustomName: 'New Section',
		Id: genId(),
		SectionType: 'items',
		ImageType: 'Thumb',
		CollectionType: 'movies',
		SortBy: 'Random',
		SortOrder: 'Descending',
		Monitor: [],
		ItemTypes: ['Movie'],
		ExcludedFolders: [],
		CardSizeOffset: 0,
		IncludeNextUpInResume: true,
		Query: {
			StudioIds: [],
			TagIds: [],
			GenreIds: [],
			CollectionTypes: [],
			IsPlayed: false
		}
	};
}

export function createRecentlyWatchedSection(userId, userName = '') {
	return {
		UserId: userId,
		Name: `Recently Watched${userName ? ` - ${userName}` : ''}`,
		CustomName: `Recently Watched${userName ? ` - ${userName}` : ''}`,
		Id: genId(),
		SectionType: 'items',
		ImageType: 'Thumb',
		CollectionType: '',
		SortBy: 'DatePlayed',
		SortOrder: 'Descending',
		Monitor: [],
		ItemTypes: ['Movie', 'Series'],
		ExcludedFolders: [],
		CardSizeOffset: 0,
		IncludeNextUpInResume: true,
		Query: {
			StudioIds: [],
			TagIds: [],
			GenreIds: [],
			CollectionTypes: [],
			IsPlayed: true
		}
	};
}

export function createBoxSetSection(userId, collectionName, collectionId) {
	return {
		UserId: userId,
		Name: collectionName || 'New Collection',
		CustomName: collectionName || 'New Collection',
		Id: genId(),
		SectionType: 'boxset',
		ImageType: 'Thumb',
		ItemTypes: [],
		SortBy: 'Random',
		SortOrder: 'Descending',
		Monitor: [],
		ExcludedFolders: [],
		CardSizeOffset: 0,
		IncludeNextUpInResume: true,
		ParentItem: {
			Name: collectionName || 'New Collection',
			Id: String(collectionId || '')
		},
		ParentId: String(collectionId || '')
	};
}

export function getSectionTypeLabel(type) {
	const found = SECTION_TYPES.find((t) => t.value === type);
	return found ? found.label : type;
}

export function getSectionIconName(type) {
	return SECTION_ICONS[type] || 'spark';
}

export function getGenreNames(genreIds) {
	if (!genreIds || genreIds.length === 0) return '';
	return genreIds.map((id) => GENRES[id] || id).join(', ');
}

export function extractUserName(sections) {
	for (const s of sections) {
		const name = s.CustomName || s.Name || '';
		const extracted = extractWatchlistOwnerName(name);
		if (extracted && extracted !== name) return extracted;
	}
	return null;
}

export function isWatchlistSection(section) {
	if (!section) return false;

	const name = `${section.CustomName || ''} ${section.Name || ''}`.toLowerCase();
	return !!section.Query?.IsFavorite || name.includes('watchlist') || name.includes('watch list');
}

export function isUpNextSection(section) {
	if (!section) return false;
	if (section.SectionType === 'resume') return true;

	const name = `${section.CustomName || ''} ${section.Name || ''}`.trim().toLowerCase();
	return name === 'up next' || name === 'next up' || name === 'resume / up next';
}

export function isNewToEmbySection(section) {
	if (!section) return false;
	const name = `${section.CustomName || ''} ${section.Name || ''}`.toLowerCase();
	return name.includes('new to emby');
}

export function isRecentlyWatchedSection(section) {
	if (!section) return false;
	const name = `${section.CustomName || ''} ${section.Name || ''}`.toLowerCase();
	return section.Query?.IsPlayed === true || name.includes('recently watched');
}

export function isFixedOrderSection(section) {
	if (!section) return false;
	return (
		isUpNextSection(section) ||
		isWatchlistSection(section) ||
		isNewToEmbySection(section) ||
		isRecentlyWatchedSection(section) ||
		section.SectionType === 'latestepisodereleases' ||
		section.SectionType === 'latestmoviereleases' ||
		section.SectionType === 'latestmediablock' ||
		section.SectionType === 'userviews'
	);
}

function renameWatchlistLabel(label, targetName) {
	if (!label || !targetName) return label;
	if (/^\s*watch\s+list\s*$/i.test(label)) return 'Watch List';
	if (/^\s*watchlist\s*$/i.test(label)) return 'Watchlist';

	if (/watch\s+list/i.test(label)) {
		return label.replace(/^.*?watch\s+list/i, `${targetName}'s Watch List`);
	}

	if (/watchlist/i.test(label)) {
		return label.replace(/^.*?watchlist/i, `${targetName}'s Watchlist`);
	}

	return label;
}

function extractWatchlistOwnerName(label) {
	if (!label) return '';
	const normalized = String(label).trim();
	if (!/watchlist|watch\s+list/i.test(normalized)) return '';

	return normalized
		.replace(/\bwatchlist\b/i, '')
		.replace(/\bwatch\s+list\b/i, '')
		.replace(/['’]s$/i, '')
		.trim();
}

function normalizeNameForCompare(name) {
	return String(name || '')
		.toLowerCase()
		.replace(/['’]/g, '')
		.replace(/[^a-z0-9]+/g, '');
}

function labelsMatchUser(label, targetName) {
	const owner = extractWatchlistOwnerName(label);
	if (!owner || !targetName) return false;
	return normalizeNameForCompare(owner) === normalizeNameForCompare(targetName);
}

function getPreferredUserName(user) {
	return user?.embyName || user?.name || '';
}

export function getWatchlistLabelsForTarget(sourceSection, targetUser) {
	const existingTargetWatchlist = targetUser?.sections?.find((section) => isWatchlistSection(section));
	const targetName = getPreferredUserName(targetUser);

	if (existingTargetWatchlist) {
		const existingName = existingTargetWatchlist.CustomName || existingTargetWatchlist.Name || '';
		if (!targetName || labelsMatchUser(existingName, targetName)) {
			return {
				Name: existingTargetWatchlist.Name || sourceSection.Name,
				CustomName: existingTargetWatchlist.CustomName || existingTargetWatchlist.Name || sourceSection.CustomName || sourceSection.Name
			};
		}

		return {
			Name: renameWatchlistLabel(existingTargetWatchlist.Name || sourceSection.Name, targetName),
			CustomName: renameWatchlistLabel(
				existingTargetWatchlist.CustomName || existingTargetWatchlist.Name || sourceSection.CustomName || sourceSection.Name,
				targetName
			)
		};
	}

	return {
		Name: renameWatchlistLabel(sourceSection.Name, targetName),
		CustomName: renameWatchlistLabel(sourceSection.CustomName, targetName)
	};
}

export function applySectionStandards(sourceSection, targetUser) {
	const section = JSON.parse(JSON.stringify(sourceSection || {}));

	if (isUpNextSection(section)) {
		section.Name = 'Up Next';
		section.CustomName = 'Up Next';
		return section;
	}

	if (isWatchlistSection(section)) {
		const labels = getWatchlistLabelsForTarget(section, targetUser);
		if (labels.Name) section.Name = labels.Name;
		if (labels.CustomName) section.CustomName = labels.CustomName;
		return section;
	}

	if (isNewToEmbySection(section)) {
		section.Name = 'New to Emby';
		section.CustomName = 'New to Emby';
		section.SortBy = 'DateLastContentAdded,SortName';
		section.SortOrder = 'Descending';
		return section;
	}

	if (isRecentlyWatchedSection(section)) {
		const targetName = getPreferredUserName(targetUser);
		const label = `Recently Watched${targetName ? ` - ${targetName}` : ''}`;
		section.Name = label;
		section.CustomName = label;
		section.SortBy = 'DatePlayed';
		section.SortOrder = 'Descending';
		return section;
	}

	if (!isFixedOrderSection(section) && ['items', 'collections', 'boxset'].includes(section.SectionType)) {
		section.SortBy = 'Random';
		section.SortOrder = 'Descending';
	}

	if (section.SectionType === 'userviews') {
		section.Name = 'Libraries';
		section.CustomName = 'Libraries';
	}

	return section;
}

/**
 * Build SQL UPDATE statements from modified user data.
 * Each user's entire homescreensettings JSON is replaced.
 */
export function generateSQL(users, originalUsers) {
	const statements = [];

	for (const user of users) {
		if (!user.sections || user.sections.length === 0) continue;

		const original = originalUsers.find((u) => u.id === user.id);
		if (!original) continue;

		const origJSON = JSON.stringify({ Sections: original.sections });
		const newJSON = JSON.stringify({ Sections: user.sections });

		if (origJSON === newJSON) continue;

		const escapedValue = newJSON.replace(/'/g, "''");
		statements.push(
			`-- User: ${user.name} (DB ID: ${user.id})`,
			`UPDATE UserSettings SET Value = '${escapedValue}' WHERE UserId = ${user.id} AND UserSettingsKeyId = (SELECT UserSettingsKeyId FROM UserSettingsKeys WHERE Name = 'homescreensettings');`,
			''
		);
	}

	if (statements.length === 0) {
		return '-- No changes detected';
	}

	return [
		'-- ===========================================',
		'-- Emby Home Screen Settings Update',
		`-- Generated: ${new Date().toISOString()}`,
		'-- ===========================================',
		'-- IMPORTANT: Stop Emby before running this!',
		'-- sqlite3 /path/to/users.db < this_file.sql',
		'-- Then restart Emby.',
		'-- ===========================================',
		'',
		'BEGIN TRANSACTION;',
		'',
		...statements,
		'COMMIT;'
	].join('\n');
}
