import { config, pgClients, yml2json } from "@opengis/fastify-table/utils.js";

const { prefix = '/api' } = config;

function getBBox(coordinates) {
    return coordinates[0].reduce(
        ([minLon, minLat, maxLon, maxLat], [lon, lat]) => [
            Math.min(minLon, lon),
            Math.min(minLat, lat),
            Math.max(maxLon, lon),
            Math.max(maxLat, lat)
        ],
        [coordinates[0][0][0], coordinates[0][0][1], coordinates[0][0][0], coordinates[0][0][1]]
    );
}

export default async function mapCatalog({ pg = pgClients.client }, reply) {
    const { rows: services = [] } = pg.pk?.['gis.services']
        ? await pg.query(`select 
                service_id as id, name, service_type, service_url as url, 
                source_type, source_path, geometry_column, style, layers, 
                st_asgeojson(bbox)::json->'coordinates' as bbox, 
                st_asgeojson(center)::json->'coordinates' as center,
                popup, card, filters
            from gis.services where is_active and is_public`
        )
        : {};

    const bboxq = services.filter(el => el.source_path && pg?.pk?.[el.source_path] && !el.bbox).map(el => `update gis.services set bbox = (select st_extent(${el.geometry_column || 'geom'})::geometry from ${el.source_path}) where service_id='${el.id}'`).join(';');
    await pg.query(bboxq).catch(err => console.error(err.toString()));

    services.filter(row => row.style).map(row => {
        row.style = yml2json(row.style);
    });

    services.filter(el => el.bbox).forEach(el => {
        el.bbox = getBBox(el.bbox);
    });

    services.filter(el => el.source_type === 'database').forEach(el => {
        el.url = `${prefix}/layer-vtile/${el.id}/{z}/{x}/{y}.vmt`;
    });

    const { rows: rasters = [] } = pg.pk?.['gis.rasters']
        ? await pg.query(
            `select
                raster_id as id, name, source_type,
                st_asgeojson(bbox):: json -> 'coordinates' as bbox,
                st_asgeojson(center):: json -> 'coordinates' as center
            from gis.rasters where is_active and is_public`
        )
        : {};
    
     const { rows: ogc = [] } = pg.pk?.['gis.ogc_service']
        ? await pg.query(
            `select
                service_id as id, name, 'raster' as source_type,  url
            from gis.ogc_service `
        )
        : {};
    
    
    
    rasters.forEach(el => {
        el.url = `${prefix}/layer-rtile/${el.id}/{z}/{x}/{y}.png`;
    });

    rasters.filter(el => el.bbox).forEach(el => {
        el.bbox = getBBox(el.bbox);
    });

    return reply.status(200).send({ services, rasters: rasters.concat(ogc) });
}