import {cfg} from './config.mjs';

const CHANNEL_MAP = {0: 'A, B', 1: 'A', 2: 'B'};
const SENDER_TYPE = {
	0: 'Other', 1: 'Unknown', 2: 'Cargo', 3: 'Class B',
	4: 'Passenger', 5: 'Special', 6: 'Tanker', 7: 'High Speed',
	8: 'Fishing', 9: 'Aircraft', 10: 'Helicopter', 11: 'Base Station',
	12: 'AtoN', 13: 'SART/EPIRB'
};

let aisCache = null;
let aisCacheTs = 0;
const AIS_TTL = 1000;

function decodeMsgTypes(raw) {
	const types = [];
	for (let i = 0; i < 32; i++) {
		if (raw & (1 << i)) types.push(i);
	}
	return types;
}

function decodeFlags(flags) {
	return {
		validated:    flags & 3,
		validated2:   (flags & 3) == 2 ? -1 : flags & 3,
		repeat:       (flags >> 2) & 3,
		virtual_aid:  (flags >> 4) & 1,
		approx:       (flags >> 5) & 1,
		channels:     (flags >> 6) & 15,
		cs_unit:      (flags >> 10) & 3,
		raim:         (flags >> 12) & 3,
		dte:          (flags >> 14) & 3,
		assigned:     (flags >> 16) & 3,
		display:      (flags >> 18) & 3,
		dsc:          (flags >> 20) & 3,
		band:         (flags >> 22) & 3,
		msg22:        (flags >> 24) & 3,
		off_position: (flags >> 26) & 3,
		maneuver:     (flags >> 28) & 3,
	};
}

export async function getAIS() {
	if (aisCache && Date.now() - aisCacheTs < AIS_TTL) return aisCache;
	const {ADSB_URL} = cfg();
	if (!ADSB_URL) return {data: []};
	const r = await fetch(`${ADSB_URL}:9990/api/ships_array.json`);
	const {dynamic, static: staticRows, time} = await r.json();

	const staticMap = new Map(staticRows.map(row => [row[0], row]));

	aisCache = dynamic.map(row => {
		const [mmsi, lat, lon, distance, bearing, heading,
			cog, speed, status, rrsi, ppm, count, msg_type,
			last_signal, last_group, group_mask, flags, altitude,
			received_stations, mmsi_type, shipclass, country] = row;
		const s = staticMap.get(mmsi) ?? [];
		const [_mmsi, shipname, callsign, destination, shiptype,
			imo, to_bow, to_stern, to_port, to_starboard, draught,
			eta_month, eta_day, eta_hour, eta_minute] = s;

		const f = decodeFlags(flags);

		return {
			mmsi,
			type: SENDER_TYPE[shipclass],
			lat, lon, altitude,
			heading, cog, speed,
			distance, bearing,
			destination,
			rrsi, ppm, count,
			msg_type: decodeMsgTypes(msg_type),
			channels: CHANNEL_MAP[f.channels] ?? f.channels,
			...f,
			shiptype, imo, draught,
			country, callsign,
			shipname,
			to_bow, to_stern, to_port, to_starboard,
			eta_month, eta_day, eta_hour, eta_minute,
			last_signal: last_signal ? time - last_signal : null,
			last_group, group_mask,
			received_stations, shipclass,
			status
		};
	});
	aisCacheTs = Date.now();
	return aisCache;
}

export async function getAISImage(mmsi) {
	console.log(`https://www.vesselfinder.com/vessels/details/${mmsi}`)
	const res = await fetch(`https://www.vesselfinder.com/vessels/details/${mmsi}`, {
		headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36' }
	})
	const html = await res.text()
	const match = html.match(/<img.+main-photo.+>/)
	if(!match) return null;
	const srcMatch = match[0].match(/src="(.+?)"/)
	if (!srcMatch) return null;

	let imgUrl = srcMatch[1]
	if (imgUrl.startsWith('/')) imgUrl = `https://www.vesselfinder.com${imgUrl}`
	return fetch(imgUrl, {
		headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36' }
	}).then(resp => resp.blob())
}
