import { graphql } from '../api';
// import { sitesFragment, releaseFields } from '../fragments';
import { releaseFields, batchFragment, campaignsFragment } from '../fragments';
import { curateEntity } from '../curate';
import getDateRange from '../get-date-range';

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

		const { entity, connection, batches: [lastBatch] } = await graphql(`
            query Entity(
                $entitySlug: String!
                $entityType: String! = "channel"
                $limit: Int = 10,
                $offset: Int = 0,
                $after: Datetime = "1900-01-01",
                $before: Datetime = "2100-01-01",
                $orderBy: [ReleasesSummariesOrderBy!]
                $exclude: [String!]
				$hasAuth: Boolean!
				$userId: Int
            ) {
				entity: entityBySlugAndType(slug: $entitySlug, type: $entityType) {
                    id
                    name
                    slug
                    url
					independent
					hasLogo
					tags: entitiesTags {
						tag {
							id
							name
							slug
						}
					}
					sceneTags {
						id
						name
						slug
					}
					children: childEntitiesConnection(
                        orderBy: [PRIORITY_DESC, NAME_ASC],
						filter: {
							type: {
								notEqualTo: "info"
							}
							visible: {
								equalTo: true
							}
						}
                    ) {
						nodes {
							id
							name
							slug
							url
							type
							priority
							independent
							hasLogo
							${campaignsFragment}
							children: childEntitiesConnection {
								totalCount
							}
						}
                    }
					${campaignsFragment}
                    parent {
                        id
                        name
                        slug
						type
                        url
						independent
						hasLogo
						${campaignsFragment}
                    }
                }
				connection: releasesSummariesConnection(
					first: $limit
					offset: $offset
					orderBy: $orderBy
					filter: {
					    effectiveDate: { lessThan: $before, greaterThan: $after }
					    showcased: { equalTo: true }
						and: [
							{
								or: [
									{
										not: { tags: { overlaps: $exclude } }
									}
									{
										tags: { isNull: true }
									}
								]
							}
							{
								or: [
									{
										channelSlug: { equalTo: $entitySlug }
										channelType: { equalTo: $entityType }
									}
									{
										networkSlug: { equalTo: $entitySlug }
										networkType: { equalTo: $entityType }
									}
									{
										parentNetworkSlug: { equalTo: $entitySlug }
										parentNetworkType: { equalTo: $entityType }
									}
								]
							}
						]
					}
				) {
					releases: nodes {
						release {
							${releaseFields}
						}
					}
					totalCount
				}
				${batchFragment}
            }
        `, {
			entitySlug,
			entityType,
			limit,
			offset: Math.max(0, (pageNumber - 1)) * limit,
			after,
			before,
			orderBy,
			exclude: store.state.ui.tagFilter,
			hasAuth: !!store.state.auth.user,
			userId: store.state.auth.user?.id,
		});

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

		return {
			entity: curateEntity(entity, null, connection.releases.map(({ release }) => release), { lastBatch: lastBatch?.id }),
			totalCount: connection.totalCount,
		};
	}

	async function fetchEntities({ _commit }, { type, entitySlugs }) {
		const { entities } = await graphql(`
            query Entities(
				$entitySlugs: [String!] = []
			) {
				entities(
					orderBy: SLUG_ASC
					filter: {
						or: [
							{
								type: {
									equalTo: "network"
								}
								childEntitiesConnection: {
									some: {
										type: {
											equalTo: "channel"
										}
										independent: {
											notEqualTo: true
										}
									}
								}
							}
							{
								independent: {
									equalTo: true
								}
							}
							{
								type: {
									equalTo: "channel"
								}
								parentExists: false
							}
							{
								slug: {
									in: $entitySlugs
								}
							}
						],
					}
				) {
                    id
                    name
                    slug
					type
                    url
					independent
					hasLogo
					children: childEntitiesConnection {
						totalCount
					}
                }
            }
        `, {
			type,
			entitySlugs,
		});

		return entities.map((entity) => curateEntity(entity));
	}

	async function searchEntities({ _commit }, { query, limit = 20 }) {
		const { entities } = await graphql(`
            query SearchEntities(
                $query: String!
                $limit: Int = 20,
            ) {
                entities: searchEntities(
                    search: $query
                    first: $limit
                ) {
					id
                    name
                    slug
					type
                    url
					independent
					hasLogo
                    parent {
                        name
                        slug
						type
                        url
						hasLogo
                    }
                }
            }
        `, {
			query,
			limit,
		});

		return entities.map((entity) => curateEntity(entity));
	}

	return {
		fetchEntityBySlugAndType,
		fetchEntities,
		searchEntities,
	};
}

export default initEntitiesActions;