import { graphql } from '../api';
import {
	releasesFragment,
	releaseFragment,
	releaseFields,
	movieFields,
} 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 } } = 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}
            }
        `, {
			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)),
			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: DATE_DESC
					filter: {
						date: {
							isNull: false
						}
					}
				) {
					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 fetchMovieById({ _commit }, movieId) {
		// const release = await get(`/releases/${releaseId}`);

		const { movie } = await graphql(`
			query Movie(
				$movieId: Int!
				$hasAuth: Boolean!
				$userId: Int
			) {
				movie(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: moviesPoster {
						media {
							id
							path
							thumbnail
							lazy
							width
							height
							thumbnailWidth
							thumbnailHeight
							isS3
						}
					}
					covers: moviesCovers(orderBy: MEDIA_BY_MEDIA_ID__INDEX_ASC) {
						media {
							id
							path
							thumbnail
							width
							height
							thumbnailWidth
							thumbnailHeight
							lazy
							isS3
						}
					}
					trailer: moviesTrailer {
						media {
							id
							path
							isS3
						}
					}
					scenes: moviesScenes {
						scene {
							${releaseFields}
						}
					}
					tags {
						id
						slug
						name
					}
					photos {
						id
						index
						path
						thumbnail
						lazy
						width
						height
						thumbnailWidth
						thumbnailHeight
						isS3
						comment
						sfw: sfwMedia {
							id
							thumbnail
							lazy
							path
							comment
						}
					}
					entity {
						id
						name
						slug
						type
						hasLogo
						parent {
							id
							name
							slug
							type
							hasLogo
						}
					}
					stashes: 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 (!movie) {
			router.replace('/not-found');
			return null;
		}

		return curateRelease(movie);
	}

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

export default initReleasesActions;