import { error, json } from '@sveltejs/kit';
import { normalizeLookupItem } from '../../../lib/collection-tools.js';
import {
	buildSingleGenreUpdate,
	normalizeGenreNames,
	pickSuggestedGenre
} from '../../../lib/genre-cleanup.js';
import { fetchEmby, fetchEmbyJson, normalizeEmbyGuid } from '../../../lib/server/emby-api.js';
import { fetchTmdbDetails, searchTmdbByTitle } from '../../../lib/server/tmdb-api.js';

function getItemTmdbId(item) {
	const providerIds = item?.ProviderIds || item?.providerIds || {};
	return String(providerIds.Tmdb || providerIds.TMDB || providerIds.tmdb || '').trim();
}

function getTmdbMediaType(item) {
	return item?.Type === 'Series' || item?.type === 'Series' ? 'tv' : 'movie';
}

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

async function fetchFullItem(userId, itemId) {
	const candidates = [
		() => fetchEmbyJson(`/Users/${encodeURIComponent(userId)}/Items/${encodeURIComponent(itemId)}`),
		() =>
			fetchEmbyJson(`/Items/${encodeURIComponent(itemId)}`, {
				params: { UserId: userId }
			})
	];

	let lastError = null;
	for (const candidate of candidates) {
		try {
			return await candidate();
		} catch (err) {
			lastError = err;
		}
	}

	throw lastError || new Error('Could not fetch item details from Emby');
}

async function resolveTmdbMatch(item) {
	const directTmdbId = getItemTmdbId(item);
	if (directTmdbId) {
		return {
			tmdbId: Number(directTmdbId),
			mediaType: getTmdbMediaType(item),
			source: 'providerId'
		};
	}

	const matches = await searchTmdbByTitle({
		mediaType: getTmdbMediaType(item),
		name: item?.Name || item?.name,
		year: item?.ProductionYear || item?.year
	});
	const exactTitle = normalizeTitle(item?.Name || item?.name);
	const bestMatch =
		matches.find(
			(candidate) =>
				normalizeTitle(candidate?.name) === exactTitle &&
				(!item?.ProductionYear || !candidate?.year || candidate.year === item.ProductionYear)
		) || matches[0];

	if (!bestMatch?.tmdbId) return null;

	return {
		tmdbId: Number(bestMatch.tmdbId),
		mediaType: bestMatch.mediaType,
		source: 'search'
	};
}

async function inspectItemGenres(userId, itemId) {
	const fullItem = await fetchFullItem(userId, itemId);
	const normalizedItem = normalizeLookupItem(fullItem);
	const currentGenres = normalizeGenreNames([
		...(fullItem?.Genres || []),
		...((fullItem?.GenreItems || []).map((entry) => entry?.Name))
	]);

	const tmdbMatch = await resolveTmdbMatch(fullItem);
	if (!tmdbMatch?.tmdbId) {
		return {
			item: normalizedItem,
			currentGenres,
			tmdb: null,
			suggestedGenre: ''
		};
	}

	const details = await fetchTmdbDetails(tmdbMatch);
	const tmdbGenres = normalizeGenreNames((details?.genres || []).map((genre) => genre?.name));

	return {
		item: normalizedItem,
		currentGenres,
		tmdb: {
			tmdbId: tmdbMatch.tmdbId,
			mediaType: tmdbMatch.mediaType,
			source: tmdbMatch.source,
			genres: tmdbGenres
		},
		suggestedGenre: pickSuggestedGenre(tmdbGenres, currentGenres)
	};
}

export async function GET({ url }) {
	const userId = normalizeEmbyGuid(url.searchParams.get('userId'));
	const itemId = String(url.searchParams.get('itemId') || '').trim();

	if (!userId) {
		throw error(400, 'Missing userId');
	}

	if (!itemId) {
		throw error(400, 'Missing itemId');
	}

	try {
		return json(await inspectItemGenres(userId, itemId));
	} catch (err) {
		if (String(err.message || '').includes('not configured')) {
			throw error(400, err.message);
		}
		throw error(502, `Could not inspect item genres: ${err.message}`);
	}
}

export async function POST({ request }) {
	const body = await request.json();
	const userId = normalizeEmbyGuid(body?.userId);
	const itemId = String(body?.itemId || '').trim();
	const genreName = String(body?.genreName || '').trim();

	if (!userId) {
		throw error(400, 'Missing userId');
	}

	if (!itemId) {
		throw error(400, 'Missing itemId');
	}

	if (!genreName) {
		throw error(400, 'Missing genreName');
	}

	try {
		const fullItem = await fetchFullItem(userId, itemId);
		const updatedItem = buildSingleGenreUpdate(fullItem, genreName);

		await fetchEmby(`/Items/${encodeURIComponent(itemId)}`, {
			method: 'POST',
			headers: {
				'Content-Type': 'application/json'
			},
			body: JSON.stringify(updatedItem)
		});

		return json(await inspectItemGenres(userId, itemId));
	} catch (err) {
		if (err?.status) throw err;
		if (String(err.message || '').includes('not configured')) {
			throw error(400, err.message);
		}
		throw error(502, `Could not update item genres: ${err.message}`);
	}
}
