'use strict';

const qu = require('../utils/qu');
const slugify = require('../utils/slugify');

function scrapeAll(scenes, channel) {
	return scenes.map(({ query }) => {
		const release = {};

		release.url = query.url('.title', 'href', { origin: channel.url });
		release.entryId = new URL(release.url).pathname.match(/\/scene\/(\d+)/)?.[1];

		release.title = query.cnt('.title');

		release.actors = query.all('.actors a').map(actorEl => ({
			name: query.cnt(actorEl),
			url: query.url(actorEl, null, 'href', { origin: channel.url }),
		}));

		const fallbackPoster = query.img('.thumb img');
		release.poster = query.sourceSet('.thumb img', 'data-srcset') || [fallbackPoster.replace('_crop', ''), fallbackPoster];

		return release;
	});
}

function scrapeScene({ query }, url, channel) {
	const release = {};

	release.entryId = new URL(url).pathname.match(/\/scene\/(\d+)/)?.[1];

	release.title = query.cnt('h1.title');
	release.description = query.cnt('.content-description .full p');

	release.date = query.date('.publish_date', 'MMMM DD, YYYY');
	release.duration = query.dur('.duration');

	release.actors = query.all('.actress a').map(actorEl => ({
		name: query.cnt(actorEl),
		url: query.url(actorEl, null, 'href', { origin: channel.url }),
	}));

	release.director = query.cnt('.director')?.split(/\s*:\s*/)[1];

	const fallbackPoster = query.img('.player img');
	release.poster = query.sourceSet('.player img', 'data-srcset') || [fallbackPoster.replace('_crop', ''), fallbackPoster];

	release.movie = {
		title: query.cnt('.movie a'),
		url: query.url('.movie a', 'href', { origin: channel.url }),
	};

	return release;
}

function scrapeMovies(movies, channel) {
	return movies.map(({ query }) => {
		const release = {};

		release.url = query.url(null, 'href', { origin: channel.url });
		release.entryId = new URL(release.url).pathname.match(/\/porn-movie\/([\w-]+)/)?.[1];

		release.title = query.cnt('h2');

		release.covers = [query.sourceSet('img', 'data-srcset')];

		return release;
	});
}

function scrapeMovie({ query, el }, url, channel) {
	const release = {};

	release.title = query.cnt('.header h1');
	release.description = query.cnt('.content-text p');

	release.entryId = new URL(url).pathname.match(/\/porn-movie\/([\w-]+)/)?.[1];

	release.date = query.date('.out_date', 'YYYY');
	release.datePrecision = 'year';

	release.duration = query.dur('.duration');

	release.actors = query.all('.actors .actor').map(actorEl => ({
		name: query.cnt(actorEl, '.name'),
		url: query.url(actorEl, 'a', 'href', { origin: channel.url }),
		avatar: query.sourceSet(actorEl, '.thumbnail img', 'data-srcset'),
	}));

	release.poster = query.sourceSet('.banner', 'data-srcset');
	release.covers = [query.sourceSet('.cover', 'data-srcset')];

	release.scenes = scrapeAll(qu.initAll(el, '.scene'), channel);

	return release;
}

async function scrapeProfile({ query, el }, entity, avatar) {
	const profile = {};

	profile.description = query.cnt('.content-description .content-text > p, .content-description .full p'); // different structure for overflowing vs short text
	profile.nationality = query.cnt('.nationality');

	profile.banner = query.img('.header img:not([src*="actor/banner"])'); // ignore stock banner

	if (avatar) {
		profile.avatar = [
			avatar.replace('crop_', ''),
			avatar,
		];
	}

	profile.releases = scrapeAll(qu.initAll(el, '.scene'), entity);

	return profile;
}

async function fetchLatest(channel, page = 1) {
	const url = `${channel.url}/scene/list/more/?lang=en&page=${page}&sorting=new`;

	const res = await qu.getAll(url, '.scene', {
		'X-Requested-With': 'XMLHttpRequest',
		'Accept-Language': 'en-US,en', // fetch English rather than French titles
	});

	if (res.ok) {
		return scrapeAll(res.items, channel);
	}

	return res.status;
}

async function fetchMovies(channel, page = 1) {
	const url = `${channel.url}/movies/more?lang=en&page=${page}&sorting=new`;

	const res = await qu.getAll(url, '.movie', {
		'X-Requested-With': 'XMLHttpRequest',
		'Accept-Language': 'en-US,en', // fetch English rather than French titles
		Referer: 'https://www.dorcelclub.com/en/porn-movie?sorting=new', // might be used to derive sorting
	});

	if (res.ok) {
		return scrapeMovies(res.items, channel);
	}

	return res.status;
}

async function fetchScene(url, channel) {
	const res = await qu.get(url, '.content', {
		'Accept-Language': 'en-US,en', // fetch English rather than French titles
	});

	if (res.ok) {
		return scrapeScene(res.item, url, channel);
	}

	return res.status;
}

async function fetchMovie(url, channel) {
	const res = await qu.get(url, '.content', {
		'Accept-Language': 'en-US,en', // fetch English rather than French titles
	});

	if (res.ok) {
		return scrapeMovie(res.item, url, channel);
	}

	return res.status;
}

async function fetchProfile(baseActor, { entity }) {
	// URL slugs are unpredictable: /jessie-volt, /aleska_diamond, /liza-del_sierra
	const searchRes = await qu.postAll(`${entity.url}/en/search`, { s: baseActor.name }, '.actors .actor', { 'Accept-Language': 'en-US,en' });

	if (!searchRes.ok) {
		return searchRes.status;
	}

	const actorItem = searchRes.items.find(({ query }) => slugify(query.cnt('.name')) === baseActor.slug);

	if (!actorItem) {
		return null;
	}

	const actorUrl = actorItem.query.url('a', 'href', { origin: entity.url });
	const actorAvatar = actorItem.query.img();

	const actorRes = await qu.get(actorUrl, null, { 'Accept-Language': 'en-US,en' });

	if (actorRes.ok) {
		return scrapeProfile(actorRes.item, entity, actorAvatar);
	}

	return null;
}

module.exports = {
	fetchLatest,
	fetchScene,
	fetchMovie,
	fetchMovies,
	fetchProfile,
};