'use strict';

const { get, geta, ctxa } = require('../utils/q');
const slugify = require('../utils/slugify');
const { heightToCm } = require('../utils/convert');

const slugUrlMap = {
    nubiles: 'https://www.nubiles.net',
    nubilesporn: 'https://www.nubiles-porn.com',
};

async function getPhotos(albumUrl) {
    const thumbnails = await geta(albumUrl, '.photo-thumb');

    return thumbnails
        ? thumbnails.map(({ q }) => q('source').srcset)
        : [];
}

function scrapeAll(scenes, site, origin) {
    return scenes.map(({ q, qa, qu, qd }) => {
        const release = {};

        release.title = q('.title a', true);

        const url = qu('.title a').split('?')[0];
        const channelUrl = qu('.site-link');

        if (/^http/.test(url)) {
            const { pathname } = new URL(url);
            release.entryId = pathname.split('/')[3];

            if (channelUrl) release.url = `${channelUrl}${pathname}`;
            else release.url = url;
        } else if (!/\/join/.test(url)) {
            release.entryId = url.split('/')[3];

            if (channelUrl) release.url = `${channelUrl}${url}`;
            else if (site?.url) release.url = `${site.url}${url}`;
            else if (origin) release.url = `${origin}${url}`;
        } else {
            release.entryId = q('a img', 'tube_tour_thumb_id');
        }

        release.date = qd('.date', 'MMM D, YYYY');
        release.actors = qa('.models a.model', true);

        const poster = q('img').dataset.original;
        release.poster = [
            poster.replace('_640', '_1280'),
            poster,
        ];

        release.stars = Number(q('.rating', true));
        release.likes = Number(q('.likes', true));

        return release;
    });
}

async function scrapeScene({ q, qa, qd, qp, qu, qi }, url, site) {
    const release = {};

    const { origin, pathname } = new URL(url);
    release.url = `${origin}${pathname}`;

    release.entryId = new URL(url).pathname.split('/')[3];
    release.title = q('.content-pane-title h2', true);
    release.description = q('.content-pane-column div', true);

    release.date = qd('.date', 'MMM D, YYYY');

    release.actors = qa('.content-pane-performers .model', true);
    release.tags = qa('.categories a', true);

    release.poster = qp() || qi('.fake-video-player img');
    release.trailer = qa('source').map(source => ({
        src: source.src,
        quality: Number(source.getAttribute('res')),
    }));

    release.stars = Number(q('.score', true));
    release.likes = Number(q('#likecount', true));

    const albumLink = qu('.content-pane-related-links a[href*="gallery"]');
    if (albumLink) release.photos = await getPhotos(`${site.url}${albumLink}`);

    return release;
}

function scrapeProfile({ q, qa, qi, qu }, _actorName, origin) {
    const profile = {};

    const keys = qa('.model-profile h5', true);
    const values = qa('.model-profile h5 + p', true);

    const bio = keys.reduce((acc, key, index) => ({ ...acc, [slugify(key, { delimiter: '_' })]: values[index] }), {});

    profile.age = Number(bio.age);
    profile.description = q('.model-bio', true);

    profile.residencePlace = bio.location;

    profile.height = heightToCm(bio.height);
    [profile.bust, profile.waist, profile.hip] = bio.figure.split('-').map(v => Number(v) || v);

    profile.avatar = qi('.model-profile img');

    const releases = qa('.content-grid-item').filter(el => /video\//.test(qu(el, '.img-wrapper a'))); // filter out photos
    profile.releases = scrapeAll(ctxa(releases), null, origin);

    return profile;
}

async function fetchLatest(site, page = 1) {
    const url = `${site.url}/video/gallery/${(page - 1) * 12}`;
    const qLatest = await geta(url, '.content-grid-item');

    return qLatest && scrapeAll(qLatest, site);
}

async function fetchUpcoming(site) {
    if (site.parameters?.upcoming) {
        const url = `${site.url}/video/upcoming`;
        const qUpcoming = await geta(url, '.content-grid-item');

        return qUpcoming && scrapeAll(qUpcoming, site);
    }

    return [];
}

async function fetchScene(url, site) {
    const qScene = await get(url);

    return qScene && scrapeScene(qScene, url, site);
}

async function fetchProfile(actorName, siteSlug) {
    const firstLetter = actorName.charAt(0).toLowerCase();
    const origin = slugUrlMap[siteSlug] || `https://www.${siteSlug}.com`;

    const url = `${origin}/model/alpha/${firstLetter}`;
    const { qa } = await get(url);

    const modelPath = qa('.content-grid-item a.title').find(el => slugify(el.textContent) === slugify(actorName));

    if (modelPath) {
        const modelUrl = `${origin}${modelPath}`;
        const qModel = await get(modelUrl);

        if (qModel) return scrapeProfile(qModel, actorName, origin);
    }

    return null;
}

module.exports = {
    fetchLatest,
    fetchUpcoming,
    fetchScene,
    fetchProfile,
};
