import type { RegionalName } from '$lib/regional-name';

/**
 * Lobby conversation data.
 */
export interface Conversation {
	/**
	 * Character who owns the conversation as a gallery entry.
	 */
	chara_id: number;
	/**
	 * Number of the conversation within the character's conversation gallery.
	 */
	number: number;
	/**
	 * Location ID of the conversation.
	 */
	location: 110 | 120 | 130 | 210 | 220 | 310 | 410 | 420 | 430 | 510 | 520 | 530;
	/**
	 * First character in the conversation.
	 * Not necessarily equal to chara_id.
	 */
	chara_1: number;
	/**
	 * Second character, if present.
	 */
	chara_2?: number;
	/**
	 * Third character, if present.
	 */
	chara_3?: number;
	/**
	 * Some unknown number in the game's local database.
	 */
	condition_type: 0 | 1 | 2 | 3 | 4;
}

export async function conversation(): Promise<Conversation[]> {
	const resp = await fetch('/api/global/conversation');
	return resp.json();
}

export function byChara(convos: Conversation[]) {
	return convos.reduce(
		(m, c) => m.set(c.chara_id, (m.get(c.chara_id) ?? []).concat(c as Conversation)),
		new Map<number, Conversation[]>(),
	);
}

export const locations: Record<Conversation['location'], { name: RegionalName; group: 1 | 2 | 3 | 4 | 5 }> = {
	110: { name: { en: 'right side front' }, group: 1 },
	120: { name: { en: 'right side front' }, group: 1 },
	130: { name: { en: 'right side front' }, group: 1 },
	210: { name: { en: 'left side table' }, group: 2 },
	220: { name: { en: 'left side table' }, group: 2 },
	310: { name: { en: 'center back seat' }, group: 3 },
	410: { name: { en: 'center posters' }, group: 4 },
	420: { name: { en: 'center posters' }, group: 4 },
	430: { name: { en: 'center posters' }, group: 4 },
	510: { name: { en: 'left side school map' }, group: 5 },
	520: { name: { en: 'left side school map' }, group: 5 },
	530: { name: { en: 'left side school map' }, group: 5 },
};

function locCharas(convos: Conversation[], locGroup: 1 | 2 | 3 | 4 | 5) {
	const m = convos
		.filter((c) => locations[c.location].group === locGroup)
		.flatMap((c) => [c.chara_1, c.chara_2, c.chara_3].filter((x) => x != null))
		.reduce((m, id) => m.set(id, 1 + (m.get(id) ?? 0)), new Map<number, number>());
	return [...m].toSorted((a, b) => b[1] - a[1]); // descending
}

export function groupPopulars(convos: Conversation[]) {
	return {
		1: locCharas(convos, 1),
		2: locCharas(convos, 2),
		3: locCharas(convos, 3),
		4: locCharas(convos, 4),
		5: locCharas(convos, 5),
	};
}
