import { Router } from 'express';

import {
	createAlert,
	fetchAlerts,
	fetchNotifications,
	removeAlert,
	updateNotification,
	updateNotifications,
} from '../alerts.js';

// actors and actorIds, stashes and stashIds are aliases for consistency
export const alertsSchema = `
	extend type Query {
		alerts: [Alert]

		alert(
			id: Int!
		): Alert

		notifications(
			limit: Int = 10
		): Notifications
	}

	extend type Mutation {
		createAlert(
			all: Boolean = true
			allActors: Boolean = true
			allTags: Boolean = true
			allMatches: Boolean = true
			actors: [Int!]
			actorIds: [Int!]
			tags: [String!]
			tagIds: [Int!]
			entities: [String!]
			entityIds: [Int!]
			matches: [AlertMatchInput!]
			notify: Boolean = true
			email: Boolean = false
			stashes: [Int!]
			stashIds: [Int!]
			comment: String
			meta: JSON
		): Alert

		removeAlert(id: Int!): Alert

		updateNotification(
			id: Int!
			seen: Boolean
		): Int!

		updateNotifications(
			seen: Boolean
		): Int!
	}

	type AlertAnd {
		fields: Boolean
		actors: Boolean
		tags: Boolean
		entities: Boolean
		matches: Boolean
	}

	type AlertActor {
		id: Int
		name: String
		slug: String
	}

	type AlertTag {
		id: Int
		name: String
		slug: String
	}

	enum EntityType {
		network
		channel
		studio
		info
	}

	type AlertEntity {
		id: Int
		name: String
		slug: String
		type: EntityType
	}

	type AlertMatch {
		id: Int
		property: String
		expression: String
	}

	input AlertMatchInput {
		property: String!
		expression: String!
	}

	type AlertStash {
		id: Int
		name: String
		slug: String
		isPrimary: Boolean
	}

	type Alert {
		id: Int
		notify: Boolean
		email: Boolean
		isFromPreset: Boolean
		isPrimary: Boolean
		createdAt: Date
		and: AlertAnd
		actors: [AlertActor]
		tags: [AlertTag]
		entities: [AlertEntity]
		matches: [AlertMatch]
		stashes: [AlertStash]
		comment: String
		meta: JSON
	}

	type Notifications {
		notifications: [Notification!]!
		unseen: Int!
	}

	type Notification {
		id: Int!
		alertId: Int
		sceneId: Int
		scene: Release
		isSeen: Boolean!
		matchedActors: [Actor!]!
		matchedTags: [Tag!]!
		matchedEntity: Entity
		createdAt: Date!
	}
`;

export async function fetchAlertsApi(req, res) {
	const alerts = await fetchAlerts(req.user);

	res.send(alerts);
}

export async function fetchAlertsGraphql(query, req) {
	const alerts = await fetchAlerts(req.user);

	return alerts;
}

export async function createAlertApi(req, res) {
	const alert = await createAlert(req.body, req.user);

	res.send(alert);
}

export async function createAlertGraphql(query, req) {
	const alert = await createAlert(query, req.user);

	return alert;
}

export async function removeAlertApi(req, res) {
	await Promise.all(req.params.alertId.split(',').map(async (alertId) => removeAlert(alertId, req.user)));

	res.status(204).send();
}

export async function removeAlertGraphql(query, req) {
	const removedAlert = await removeAlert(query.id, req.user);

	return removedAlert;
}

export async function fetchNotificationsApi(req, res) {
	const notifications = await fetchNotifications(req.user, {
		limit: req.query.limit || 10,
	});

	res.send(notifications);
}

export async function fetchNotificationsGraphql(query, req) {
	const notifications = await fetchNotifications(req.user, {
		limit: query.limit || 10,
	});

	return notifications;
}

export async function updateNotificationsApi(req, res) {
	await updateNotifications(req.body, req.user);

	res.status(204).send();
}

export async function updateNotificationsGraphql(query, req) {
	const updatedCount = await updateNotifications(query, req.user);

	return updatedCount;
}

export async function updateNotificationApi(req, res) {
	await updateNotification(req.params.notificationId, req.body, req.user);

	res.status(204).send();
}

export async function updateNotificationGraphql(query, req) {
	const updatedNotification = await updateNotification(query.id, query, req.user);

	return updatedNotification;
}

export const alertsRouter = Router();

alertsRouter.get('/api/alerts', fetchAlertsApi);
alertsRouter.post('/api/alerts', createAlertApi);
alertsRouter.delete('/api/alerts/:alertId', removeAlertApi);

alertsRouter.get('/api/users/:userId/notifications', fetchNotificationsApi);
alertsRouter.patch('/api/users/:userId/notifications', updateNotificationsApi);
alertsRouter.patch('/api/users/:userId/notifications/:notificationId', updateNotificationApi);
