import type { key_val } from '$lib/stores/ae_stores';
import { api } from '$lib/api/api';
import { process_ae_obj__activity_log_props, properties_to_save } from '$lib/ae_core/ae_core__activity_log';
import { db_save_ae_obj_li__ae_obj } from '$lib/ae_core/core__idb_dexie';
import { db_core } from '$lib/ae_core/db_core';

/**
 * @description Queries all Jitsi-related activity logs and processes them into a structured report,
 * grouped by meeting ID.
 * @param api_cfg The API configuration object.
 * @param account_id The account ID to query against.
 * @param enabled Filter by enabled status.
 * @param hidden Filter by hidden status.
 * @param limit Maximum number of logs to fetch.
 * @param try_cache Whether to sync the raw logs to the local activity_log table.
 * @param log_lvl The logging level.
 * @returns A structured array of meeting report objects.
 */
export async function qry__jitsi_report({
	api_cfg,
	account_id,
	enabled = 'all',
	hidden = 'all',
	limit = 500,
	try_cache = true,
	log_lvl = 0
}: {
	api_cfg: any;
	account_id: string;
	enabled?: 'enabled' | 'all' | 'not_enabled' | undefined;
	hidden?: 'hidden' | 'all' | 'not_hidden' | undefined;
	limit?: number;
	try_cache?: boolean;
	log_lvl?: number;
}) {
	if (log_lvl) console.log('*** qry__jitsi_report() ***');

	// Step 1: Query all relevant activity logs from the API.
	const search_query = {
		or: [
			{ field: 'name', op: 'eq', value: 'jitsi_meeting_stats_update' },
			{ field: 'name', op: 'eq', value: 'jitsi_meeting_event' },
			{ field: 'name', op: 'eq', value: 'jitsi_meeting_stats' }
		],
		and: [
			{ field: 'account_id_random', op: 'eq', value: account_id }
		]
	};

	const result = await api.search_ae_obj_v3({
		api_cfg: api_cfg,
		obj_type: 'activity_log',
		search_query,
		headers: { 'x-account-id': account_id },
		enabled,
		hidden,
		limit,
		log_lvl: log_lvl
	});

	// Handle potential V3 API envelope
	let flat_log_list: any[] = [];
	if (Array.isArray(result)) {
		flat_log_list = result;
	} else if (result && typeof result === 'object' && Array.isArray((result as any).data)) {
		flat_log_list = (result as any).data;
	}

	if (!flat_log_list || !Array.isArray(flat_log_list) || flat_log_list.length === 0) {
		if (log_lvl) console.log('No Jitsi activity logs found or error occurred.');
		return [];
	}

	// Frontier Standard: Process and Save to local cache
	if (try_cache) {
		const processed_obj_li = await process_ae_obj__activity_log_props({
			obj_li: flat_log_list,
			log_lvl: log_lvl
		});
		await db_save_ae_obj_li__ae_obj({
			db_instance: db_core,
			table_name: 'activity_log',
			obj_li: processed_obj_li,
			properties_to_save: properties_to_save,
			log_lvl: log_lvl
		});
	}

	// Step 2: Process the flat list into a structured report.
	const meetings = new Map<string, any>();

	for (const log of flat_log_list) {
		const meeting_id = log.external_client_id;
		if (!meeting_id) continue;

		// Make sure the name field is prefixed with "jitsi_"
		if (!log.name.startsWith('jitsi_')) continue;

		// Ensure a base entry for the meeting exists
		if (!meetings.has(meeting_id)) {
			meetings.set(meeting_id, {
				meeting_id: meeting_id,
				room_name: 'Unknown',
				start_time: log.created_on, // Fallback start time
				final_duration: '00:00:00',
				final_participants: [],
				final_participant_count: 0,
				events: []
			});
		}

		const meeting_report = meetings.get(meeting_id);

		if (log.action === 'jitsi_meeting_init') {
			// This is the main log entry, containing the final state.
			meeting_report.room_name = log.description;
			meeting_report.start_time = log.created_on; // The init log has the true start time
			if (log.meta_json) {
				meeting_report.final_duration = log.meta_json.duration;
				meeting_report.final_participants = log.meta_json.participants;
				meeting_report.final_participant_count = log.meta_json.participant_count;
			}
		} else {
			// This is a discrete event log.
			meeting_report.events.push({
				timestamp: log.created_on,
				action: log.action,
				details: log.meta_json
			});
		}
	}

	// Sort events within each meeting chronologically
	for (const report of meetings.values()) {
		report.events.sort((a: any, b: any) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
	}

	const final_report = Array.from(meetings.values());
	final_report.sort((a, b) => new Date(b.start_time).getTime() - new Date(a.start_time).getTime());

	if (log_lvl) console.log('Final Jitsi report:', final_report);

	return final_report;
}

export const load_jitsi_report = qry__jitsi_report;
