import { RadioProfile } from "@db_models"

async function scanKeysWithPagination(pattern, count = 10, cursor = "0") {
	const result = await global.redis.scan(
		cursor,
		"MATCH",
		pattern,
		"COUNT",
		count,
	)

	return result[1]
}

export default class Radio {
	static async list({ limit = 50, offset = 0 } = {}) {
		let result = await scanKeysWithPagination(
			`radio-*`,
			limit,
			String(offset),
		)

		return await Radio.data(result.map((key) => key.split("radio-")[1]))
	}

	static async data(ids) {
		if (typeof ids === "string") {
			ids = [ids]
		}

		const results = []

		let profiles = await RadioProfile.find({
			_id: { $in: ids },
		})

		for await (const id of ids) {
			let data = await redis.hgetall(`radio-${id}`)

			if (!data) {
				continue
			}

			let profile = profiles.find(
				(profile) => profile._id.toString() === id,
			)

			if (!profile) {
				continue
			}

			profile = profile.toObject()

			data.now_playing = JSON.parse(data.now_playing)
			data.online = ToBoolean(data.online)
			data.listeners = parseInt(data.listeners)

			results.push({ ...data, ...profile })
		}

		return results
	}

	static async trendings() {
		const stationsWithListeners = []

		let cursor = "0"

		do {
			const scanResult = await global.redis.scan(
				cursor,
				"MATCH",
				"radio-*",
				"COUNT",
				100,
			)
			cursor = scanResult[0]
			const keys = scanResult[1]

			for (const key of keys) {
				const id = key.split("radio-")[1]
				const listenersStr = await global.redis.hget(key, "listeners")

				if (listenersStr !== null) {
					const listeners = parseInt(listenersStr, 10)
					if (!isNaN(listeners)) {
						stationsWithListeners.push({ id, listeners })
					}
				}
			}
		} while (cursor !== "0")

		// Sort stations by listeners in descending order
		stationsWithListeners.sort((a, b) => b.listeners - a.listeners)

		// Get the IDs of the top 4 stations
		const stationsIds = stationsWithListeners
			.slice(0, 4)
			.map((station) => station.id)

		// If no stations found or no stations with valid listener counts, return an empty array
		if (stationsIds.length === 0) {
			return []
		}

		return await Radio.data(stationsIds)
	}
}