import { graphql, patch } from '../api';

import {
	releaseFields,
	batchFragment,
	campaignFields,
	actorStashesFields,
} from '../fragments';

import { curateRelease, curateActor, curateNotification } from '../curate';

function initUiActions(store, _router) {
	function setTagFilter({ commit }, filter) {
		const tagFilter = Array.from(new Set(filter));

		commit('setTagFilter', tagFilter);
		localStorage.setItem('tagFilter', tagFilter);
	}

	function setSummaryFormat({ commit }, summaryFormat) {
		commit('setSummaryFormat', summaryFormat);
		localStorage.setItem('summaryFormat', JSON.stringify(summaryFormat));
	}

	function setRange({ commit }, range) {
		commit('setRange', range);
	}

	function setBatch({ commit }, batch) {
		commit('setBatch', batch);
		localStorage.setItem('batch', batch);
	}

	function setTheme({ commit }, theme) {
		commit('setTheme', theme);
		localStorage.setItem('theme', theme);
	}

	async function setSfw({ commit }, sfw) {
		commit('setSfw', sfw);
		localStorage.setItem('sfw', sfw);
	}

	async function fetchNotifications(_context, { page = 1, limit = 10 } = {}) {
		if (!store.state.auth.user) {
			return [];
		}

		const { notifications, unseenNotifications } = await graphql(`
            query Notifications(
				$hasAuth: Boolean!
				$userId: Int
				$limit: Int = 10
				$offset: Int = 0
			) {
				notifications: notificationsConnection(
					first: $limit
					offset: $offset
					orderBy: CREATED_AT_DESC
				) {
					nodes {
						id
						sceneId
						userId
						seen
						createdAt
						scene {
							${releaseFields}
						}
						alert {
							all
							tags: alertsTags {
								tag {
									id
									name
									slug
								}
							}
							actors: alertsActors {
								actor {
									id
									name
									slug
								}
							}
							entities: alertsEntities {
								entity {
									id
									name
									slug
									independent
								}
							}
							matches: alertsMatches {
								property
								expression
							}
						}
					}
					totalCount
				}
				unseenNotifications: notificationsConnection(
					filter: { seen: { equalTo: false } }
				) {
					totalCount
				}
            }
        `, {
			hasAuth: !!store.state.auth.user,
			userId: store.state.auth.user?.id,
			limit,
			offset: (page - 1) * limit,
		});

		if (!notifications) {
			return {
				notifications: [],
				totalCount: 0,
				unseenCount: 0,
			};
		}

		const curatedNotifications = notifications.nodes.map((notification) => curateNotification(notification));

		return {
			notifications: curatedNotifications,
			totalCount: notifications.totalCount,
			unseenCount: unseenNotifications.totalCount,
		};
	}

	async function checkNotification(context, notificationId) {
		await patch(`/users/${store.state.auth.user?.id}/notifications/${notificationId}`, {
			seen: true,
		});
	}

	async function checkNotifications() {
		await patch(`/users/${store.state.auth.user?.id}/notifications`, {
			seen: true,
		});
	}

	async function search({ _commit }, { query, limit = 20 }) {
		const res = await graphql(`
            query SearchReleases(
                $query: String!
                $limit: Int = 20
				$hasAuth: Boolean!
				$userId: Int
            ) {
                results: searchReleases(
                    query: $query
                    first: $limit
					orderBy: RANK_DESC
					filter: {
						rank: {
							greaterThan: 0.015
						}
					}
                ) {
					release {
						${releaseFields}
					}
					rank
                }
                actors: searchActors(
                    query: $query,
                    first: $limit
                ) {
                    id
                    name
                    slug
                    age
					ageAtDeath
                    dateOfBirth
                    dateOfDeath
                    gender
					aliasFor: actorByAliasFor {
						id
						name
						slug
						age
						ageAtDeath
						dateOfBirth
						dateOfDeath
						gender
						entity {
							id
							name
							slug
						}
						avatar: avatarMedia {
							id
							path
							thumbnail
							lazy
							isS3
							width
							height
							comment
							credit
						}
						birthCountry: countryByBirthCountryAlpha2 {
						  alpha2
						  name
						  alias
						}
					}
                    entity {
                        id
                        name
                        slug
                    }
					avatar: avatarMedia {
						id
						path
						thumbnail
						lazy
						isS3
						width
						height
						comment
						credit
					}
                    birthCountry: countryByBirthCountryAlpha2 {
                      alpha2
                      name
                      alias
                    }
					${actorStashesFields}
                }
				${batchFragment}
            }
        `, {
			query,
			limit,
			hasAuth: !!store.state.auth.user,
			userId: store.state.auth.user?.id,
		});

		return {
			releases: res?.results.map((result) => curateRelease(result.release, 'scene', { lastBatch: res?.batches[0].id })) || [],
			actors: res?.actors.map((actor) => curateActor(actor)) || [],
		};
	}

	async function fetchRandomCampaign(context, { minRatio, maxRatio }) {
		const { randomCampaign } = await graphql(`
			query Campaign(
				$minRatio: BigFloat
				$maxRatio: BigFloat
			) {
			  randomCampaign: getRandomCampaign(minRatio: $minRatio, maxRatio: $maxRatio) {
				  ${campaignFields}
			  }
			}
		`, {
			minRatio,
			maxRatio,
		});

		return randomCampaign;
	}

	async function fetchCampaign(context, campaignId) {
		const { campaign } = await graphql(`
			query Campaign(
				$campaignId: Int!
			) {
			  campaign(id: $campaignId) {
				  ${campaignFields}
			  }
			}
		`, {
			campaignId: Number(campaignId),
		});

		return campaign;
	}

	async function fetchStats() {
		const {
			scenes,
			movies,
			actors,
			networks,
			channels,
			batches: [batch],
		} = await graphql(`
            query Stats {
				scenes: releasesConnection { totalCount }
				movies: moviesConnection { totalCount }
				actors: actorsConnection { totalCount }
				networks: entitiesConnection(filter: { type: { equalTo: "network" } }) { totalCount }
				channels: entitiesConnection(filter: { type: { equalTo: "channel" } }) { totalCount }
				batches(orderBy: CREATED_AT_DESC, first: 1) { createdAt }
			}
		`);

		return {
			totalScenes: scenes.totalCount,
			totalMovies: movies.totalCount,
			totalActors: actors.totalCount,
			totalNetworks: networks.totalCount,
			totalChannels: channels.totalCount,
			lastScrape: new Date(batch.createdAt),
		};
	}

	return {
		checkNotification,
		checkNotifications,
		search,
		setTagFilter,
		setSummaryFormat,
		setRange,
		setBatch,
		setSfw,
		setTheme,
		fetchCampaign,
		fetchRandomCampaign,
		fetchNotifications,
		fetchStats,
	};
}

export default initUiActions;