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

export default async function layerList({
  pg = pgClients.client, query = {}, user = {},
}, reply) {
  const { sql } = query;
  const layers = getTemplates('layer');
  const files = Promise.all(layers.map(async (el) => {
    const layer = await getTemplate('layer', el[0]);
    return layer;
  }));

  if (!pg.pk?.['gis.services']) {
    return files;
    // return reply.status(404).send('services table not found');
  }

  const q = `
    select service_id as id, name, category, style, bbox::box2d as extent, st_asgeojson(bbox)::json as geom, null as url, coalesce(service_type, 'vtile') as service, group_id,
        popup, card, filters, style, source_path
    from gis.services where is_active and ${!user.uid ? 'is_public' : '1=1'}
    union all 
    select ogc_service_id as id, name, category, null as style, geom::box2d as extent, st_asgeojson(geom)::json as geom, url, 'ogc' as service, group_id,
        null as popup, null as card, null as filters, null as style, table_name as source_path
    from gis.ogc_service where enabled and ${!user.uid ? 'ispublic' : '1=1'}
    `;

  if (user.uid && sql) return q;

  const rows = await pg.query(q).then(el => el.rows || []);

  const totals = pg.queryCache ? await pg.queryCache('select json_object_agg(oid::regclass, reltuples) from pg_class')
    .then(el => el.rows?.[0]?.json_object_agg || {}) : {};
  rows.filter(row => row.source_path).forEach(row => Object.assign(row, { count: totals[row.source_path] || 0 }));

  const groupIds = rows.map(el => el.group_id).filter(Boolean);
  const groupNames = groupIds.length ? await pg.query('select json_object_agg(group_id,group_name) from gis.group_list where group_id=any($1)', [groupIds]).then(el => el.rows?.[0]?.json_object_agg || {}) : {};
  rows.filter(el => el.group_id).forEach(row => Object.assign(row, { group_name: groupNames[row.group_id] }));

  if (!rows.length) {
    return reply.status(200).send([]);
  }

  // parse service style
  rows.forEach(row => Object.assign(row, { style: row.style ? yml2json(row.style) : null }));
  // assign service url
  rows.filter(row => row.service !== 'ogc').forEach(row => Object.assign(row, { url: `${config.prefix || '/api'}/vtile/${row.id}/ua/{z}/{x}/{y}.vmt` }));
  // parse extent string to number[]
  rows.filter(row => row.extent).forEach(row => Object.assign(row, {
    extent: row.extent.match(/BOX\(([^)]+)\)/)?.[1]
      ?.replace?.(/ /g, ',')
      ?.split?.(','),
  }));

  // return files;

  return reply.status(200).send(rows.concat(files));
}
