import { readFileSync, existsSync } from 'fs';
import { resolve } from 'path';

const CONFIG_PATH = resolve('config.json');
const TMDB_BASE = 'https://api.themoviedb.org/3';

function loadConfig() {
	if (!existsSync(CONFIG_PATH)) return {};
	try {
		return JSON.parse(readFileSync(CONFIG_PATH, 'utf-8'));
	} catch {
		return {};
	}
}

export function loadTmdbConfig() {
	const config = loadConfig();
	return {
		tmdbApiKey: String(config?.tmdbApiKey || '').trim()
	};
}

export function hasTmdbConfig() {
	return !!loadTmdbConfig().tmdbApiKey;
}

async function fetchTmdb(pathname, params = {}) {
	const { tmdbApiKey } = loadTmdbConfig();
	if (!tmdbApiKey) {
		throw new Error('TMDB API key not configured');
	}

	const url = new URL(`${TMDB_BASE}${pathname.startsWith('/') ? pathname : `/${pathname}`}`);
	for (const [key, value] of Object.entries({
		api_key: tmdbApiKey,
		language: 'en-US',
		include_adult: 'false',
		...params
	})) {
		if (value === undefined || value === null || value === '') continue;
		url.searchParams.set(key, String(value));
	}

	const response = await fetch(url, {
		headers: { Accept: 'application/json' }
	});

	if (!response.ok) {
		const text = await response.text().catch(() => response.statusText);
		throw new Error(text || `${response.status} ${response.statusText}`);
	}

	return response.json();
}

function normalizeTmdbSearchItem(item, mediaType) {
	return {
		tmdbId: Number(item?.id || 0) || null,
		name: item?.title || item?.name || '',
		year: Number(String(item?.release_date || item?.first_air_date || '').slice(0, 4)) || null,
		mediaType,
		overview: item?.overview || '',
		genreIds: Array.isArray(item?.genre_ids) ? item.genre_ids : [],
		originalLanguage: item?.original_language || '',
		popularity: Number(item?.popularity || 0),
		voteAverage: Number(item?.vote_average || 0),
		voteCount: Number(item?.vote_count || 0)
	};
}

export async function searchTmdbByTitle({ mediaType, name, year }) {
	const searchType = mediaType === 'tv' ? 'tv' : 'movie';
	const payload = await fetchTmdb(`/search/${searchType}`, {
		query: name,
		page: 1,
		...(year ? (searchType === 'movie' ? { year } : { first_air_date_year: year }) : {})
	});

	return (payload?.results || []).map((item) => normalizeTmdbSearchItem(item, searchType));
}

export async function fetchTmdbSimilar({ mediaType, tmdbId, page = 1 }) {
	const pathType = mediaType === 'tv' ? 'tv' : 'movie';
	const payload = await fetchTmdb(`/${pathType}/${encodeURIComponent(tmdbId)}/similar`, { page });
	return (payload?.results || []).map((item) => normalizeTmdbSearchItem(item, pathType));
}

export async function fetchTmdbRecommendations({ mediaType, tmdbId, page = 1 }) {
	const pathType = mediaType === 'tv' ? 'tv' : 'movie';
	const payload = await fetchTmdb(`/${pathType}/${encodeURIComponent(tmdbId)}/recommendations`, { page });
	return (payload?.results || []).map((item) => normalizeTmdbSearchItem(item, pathType));
}

export async function fetchTmdbDetails({ mediaType, tmdbId }) {
	const pathType = mediaType === 'tv' ? 'tv' : 'movie';
	return fetchTmdb(`/${pathType}/${encodeURIComponent(tmdbId)}`);
}

export async function fetchTmdbKeywords({ mediaType, tmdbId }) {
	const pathType = mediaType === 'tv' ? 'tv' : 'movie';
	const payload = await fetchTmdb(`/${pathType}/${encodeURIComponent(tmdbId)}/keywords`);
	return payload?.keywords || payload?.results || [];
}

export async function fetchTmdbCredits({ mediaType, tmdbId }) {
	if (mediaType === 'tv') {
		return fetchTmdb(`/tv/${encodeURIComponent(tmdbId)}/aggregate_credits`);
	}

	return fetchTmdb(`/movie/${encodeURIComponent(tmdbId)}/credits`);
}

export async function fetchTmdbGenres(mediaType) {
	const pathType = mediaType === 'tv' ? 'tv' : 'movie';
	const payload = await fetchTmdb(`/genre/${pathType}/list`, { language: 'en' });
	return payload?.genres || [];
}

export async function fetchTmdbDiscover({ mediaType, params = {} }) {
	const pathType = mediaType === 'tv' ? 'tv' : 'movie';
	const payload = await fetchTmdb(`/discover/${pathType}`, params);
	return (payload?.results || []).map((item) => normalizeTmdbSearchItem(item, pathType));
}
