import { graphql } from '../api';
// import { sitesFragment, releaseFields } from '../fragments';
import { releaseFields } 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: { releases, totalCount } } = 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",
                $afterTime: Datetime = "1900-01-01",
                $beforeTime: Datetime = "2100-01-01",
                $orderBy: [ReleasesOrderBy!]
                $exclude: [String!]
            ) {
				entity: entityBySlugAndType(slug: $entitySlug, type: $entityType) {
                    id
                    name
                    slug
                    url
					independent
					hasLogo
					tags: entitiesTags {
						tag {
							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
						}
                    }
                    parent {
                        id
                        name
                        slug
						type
                        url
						independent
						hasLogo
                    }
                }
				connection: releasesConnection(
					first: $limit
					offset: $offset
					orderBy: $orderBy
					filter: {
						and: [
							{
								entity: {
									or: [
										{
											slug: { equalTo: $entitySlug }
										},
										{
											parent: {
												slug: { equalTo: $entitySlug }
												type: { equalTo: $entityType }
											}
										},
										{
											parent: {
												parent: {
													slug: { equalTo: $entitySlug }
													type: { equalTo: $entityType }
												}
											}
										}
									]
								}
							}
							{
								or: [
									{
										date: {
											lessThan: $before,
											greaterThan: $after
										}
									},
									{
										date: {
											isNull: true
										},
										createdAt: {
											lessThan: $beforeTime,
											greaterThan: $afterTime,
										}
									}
								]
							}
						]
						releasesTagsConnection: {
							none: {
								tag: {
									slug: {
										in: $exclude
									}
								}
							}
						}
					}
				) {
					releases: nodes {
						${releaseFields}
					}
					totalCount
				}
            }
        `, {
			entitySlug,
			entityType,
			limit,
			offset: Math.max(0, (pageNumber - 1)) * limit,
			after,
			before,
			orderBy,
			afterTime: store.getters.after,
			beforeTime: store.getters.before,
			exclude: store.state.ui.filter,
		});

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

		return {
			entity: curateEntity(entity, null, releases),
			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
                ) {
                    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;