import { graphql } from '../api';
import {
	batchFragment,
	releasesFragment,
	releaseFragment,
	releaseFields,
	movieFields,
	mediaFragment,
	mediaFields,
} from '../fragments';
import { curateRelease } from '../curate';
import getDateRange from '../get-date-range';

function initReleasesActions(store, router) {
	async function fetchReleases({ _commit }, { limit = 10, pageNumber = 1, range = 'latest' }) {
		const { before, after, orderBy } = getDateRange(range);

		const { connection: { releases, totalCount }, batches: [lastBatch] } = await graphql(`
            query Releases(
				$hasAuth: Boolean!
				$userId: Int
                $limit:Int = 1000,
                $offset:Int = 0,
                $after:Datetime = "1900-01-01 00:00:00",
                $before:Datetime = "2100-01-01 00:00:00",
                $orderBy: [ReleasesOrderBy!],
                $exclude: [String!]
            ) {
                ${releasesFragment}
                ${batchFragment}
            }
        `, {
			hasAuth: !!store.state.auth.user,
			userId: store.state.auth.user?.id,
			limit,
			offset: Math.max(0, (pageNumber - 1)) * limit,
			after,
			before,
			orderBy,
			exclude: store.state.ui.tagFilter,
		});

		return {
			releases: releases.map((release) => curateRelease(release.release || release, 'scene', { lastBatch: lastBatch.id })),
			totalCount,
		};
	}

	async function fetchReleaseById({ _commit }, releaseId) {
		// const release = await get(`/releases/${releaseId}`);

		const { release } = await graphql(`
            query Release(
				$releaseId: Int!
				$hasAuth: Boolean!
				$userId: Int
			) {
                ${releaseFragment}
            }
        `, {
			releaseId: Number(releaseId),
			hasAuth: !!store.state.auth.user,
			userId: store.state.auth.user?.id,
		});

		if (!release) {
			router.replace('/not-found');
			return null;
		}

		return curateRelease(release);
	}

	async function fetchMovies({ _commit }, { limit = 10, pageNumber = 1 }) {
		const { connection: { movies, totalCount } } = await graphql(`
            query Movies(
                $limit:Int = 1000,
                $offset:Int = 0,
				$hasAuth: Boolean!
				$userId: Int
            ) {
				connection: moviesConnection(
					first: $limit
					offset: $offset
					orderBy: EFFECTIVE_DATE_DESC
				) {
					movies: nodes {
						${movieFields}
					}
					totalCount
				}
			}
        `, {
			hasAuth: !!store.state.auth.user,
			userId: store.state.auth.user?.id,
			limit,
			offset: Math.max(0, (pageNumber - 1)) * limit,
		});

		return {
			movies: movies.map((release) => curateRelease(release)),
			totalCount,
		};
	}

	async function searchMovies({ _commit }, { query, limit = 20, pageNumber = 1 }) {
		const { connection: { movies, totalCount } } = await graphql(`
            query SearchMovies(
                $query: String!
                $limit:Int = 20
                $offset:Int = 0
				$hasAuth: Boolean!
				$userId: Int
            ) {
				connection: searchMoviesConnection(
                    query: $query
                    first: $limit
					offset: $offset
					orderBy: RANK_DESC
                ) {
					movies: nodes {
						movie {
							${movieFields}
						}
					}
					totalCount
                }
            }
        `, {
			hasAuth: !!store.state.auth.user,
			userId: store.state.auth.user?.id,
			query,
			limit,
			offset: Math.max(0, (pageNumber - 1)) * limit,
		});

		return {
			movies: movies.map(({ movie }) => curateRelease(movie)),
			totalCount,
		};
	}

	async function fetchCollectionById({ _commit }, movieId, type = 'movie') {
		// const release = await get(`/releases/${releaseId}`);

		const result = await graphql(`
			query Movie(
				$movieId: Int!
				$hasAuth: Boolean!
				$userId: Int
			) {
				${type}(id: $movieId) {
					id
					title
					description
					slug
					url
					date
					createdBatchId
					actors {
						id
						name
						slug
						age
						ageFromBirth
						dateOfBirth
						birthCountry: countryByBirthCountryAlpha2 {
						  alpha2
						  name
						  alias
						}
						avatar: avatarMedia {
							id
							path
							thumbnail
							width
							height
							thumbnailWidth
							thumbnailHeight
							lazy
							isS3
						}
					}
					poster: ${type === 'series' ? 'seriesPosterBySerieId' : 'moviesPoster'} {
						media {
							id
							path
							thumbnail
							lazy
							width
							height
							thumbnailWidth
							thumbnailHeight
							isS3
						}
					}
					covers: ${type === 'series' ? 'seriesCoversBySerieId' : 'moviesCovers'}(orderBy: MEDIA_BY_MEDIA_ID__INDEX_ASC) {
						media {
							id
							path
							thumbnail
							width
							height
							thumbnailWidth
							thumbnailHeight
							lazy
							isS3
						}
					}
					trailer: ${type === 'series' ? 'seriesTrailerBySerieId' : 'moviesTrailer'} {
						media {
							id
							path
							isS3
						}
					}
					scenes: ${type === 'series' ? 'seriesScenesBySerieId' : 'moviesScenes'} {
						scene {
							${releaseFields}
						}
					}
					tags {
						id
						slug
						name
					}
					photos: ${type === 'series' ? 'seriesPhotosBySerieId' : 'moviesPhotos'} {
						${mediaFragment}
					}
					scenesPhotos {
						${mediaFields}
					}
					entity {
						id
						name
						slug
						type
						hasLogo
						parent {
							id
							name
							slug
							type
							hasLogo
						}
					}
					stashes: ${type === 'series' ? 'stashesSeriesBySerieId' : 'stashesMovies'}(
						filter: {
							stash: {
								userId: {
									equalTo: $userId
								}
							}
						}
					) @include(if: $hasAuth) {
						stash {
							id
							name
							slug
							primary
						}
					}
				}
			}
		`, {
			movieId: Number(movieId),
			hasAuth: !!store.state.auth.user,
			userId: store.state.auth.user?.id,
		});

		if (!result[type]) {
			router.replace('/not-found');
			return null;
		}

		return curateRelease(result[type]);
	}

	async function fetchMovieById(context, movieId) {
		return fetchCollectionById(context, movieId, 'movie');
	}

	async function fetchSerieById(context, serieId) {
		return fetchCollectionById(context, serieId, 'series');
	}

	return {
		fetchReleases,
		fetchReleaseById,
		fetchMovies,
		fetchMovieById,
		fetchSerieById,
		searchMovies,
	};
}

export default initReleasesActions;