import type { APIService } from './API';
import type { Group } from '../protocols/meshcore.types';
import { PayloadType } from '../protocols/meshcore.types';
import { GroupSecret } from '../protocols/meshcore';

interface FetchedMeshCoreGroup {
	id: number;
	name: string;
	secret: string;
	isPublic: boolean;
}

export type MeshCoreGroupRecord = Group & {
	id: number;
	isPublic: boolean;
};

export interface FetchedGroupPacket {
	id: number;
	radio_id: number;
	snr: number;
	rssi: number;
	version: number;
	route_type: number;
	payload_type: number;
	hash: string;
	path: string;
	payload: string;
	raw: string;
	channel_hash: string;
	received_at: string;
}

export class MeshCoreServiceImpl {
	private api: APIService;

	constructor(api: APIService) {
		this.api = api;
	}

	/**
	 * Fetch all available MeshCore groups
	 * @returns Array of Group objects with metadata
	 */
	public async fetchGroups(): Promise<MeshCoreGroupRecord[]> {
		const groups = await this.api.fetch<FetchedMeshCoreGroup[]>('/meshcore/groups');
		return groups.map((group) => ({
			id: group.id,
			name: group.name,
			secret: group.secret && group.secret.trim().length > 0
				? new GroupSecret(group.secret)
				: GroupSecret.fromName(group.name),
			isPublic: group.isPublic,
		}));
	}

	/**
	 * Fetch all MeshCore packets
	 * @param limit Maximum number of packets to fetch (default: 200)
	 * @returns Array of raw packet data
	 */
	public async fetchPackets(limit = 200): Promise<FetchedGroupPacket[]> {
		const endpoint = '/meshcore/packets';
		const params = { limit };
		return this.api.fetch<FetchedGroupPacket[]>(endpoint, { params });
	}

	/**
	 * Fetch GROUP_TEXT packets for a specific channel hash
	 * @param channelHash The channel hash to fetch packets for
	 * @returns Array of raw packet data
	 */
	public async fetchGroupPackets(channelHash: string): Promise<FetchedGroupPacket[]> {
		const endpoint = '/meshcore/packets';
		const params = {
			type: PayloadType.GROUP_TEXT,
			channel_hash: channelHash,
		};
		return this.api.fetch<FetchedGroupPacket[]>(endpoint, { params });
	}
}

export default MeshCoreServiceImpl;
