import { pgClients, getMeta, getSelect, getSelectVal } from "@opengis/fastify-table/utils.js";

export default async function mapCatalogAttribute({ pg = pgClients.client, params = {}, query = {} }, reply) {
    const { service, attr } = params;
    if (!service) {
        return reply.status(404).send('not enough params: service');
    }

    if (!attr) {
        return reply.status(404).send('not enough params: attr');
    }

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

    const source = await pg.query(
        'select source_path from gis.services where service_id=$1 and is_active and is_public',
        [params.service]
    ).then(el => el.rows?.[0]?.source_path);

    if (!source) {
        return reply.status(404).send('service not found');
    }

    const cls = await getSelect(query.cls || attr, pg);
    const colname = query.cls ? attr : attr.split(':').pop();

    if (!colname) {
        return reply.status(400).send('invalid params: attr');
    }

    const { columns = [] } = await getMeta({ pg, table: source });
    const { dataTypeID } = columns.find(el => el.name === colname) || {};

    const q = pg.pgType[dataTypeID]?.includes('[]')
        ? `select unnest(${colname})::text as id,count(*) from ${source} group by unnest(${colname}) limit 100`
        : `select ${colname}::text as id,count(*) from ${source} group by ${colname} limit 100`;

    const countArr = await pg.queryCache(q);

    const ids = countArr.rows.map(el => el.id);

    const clsData = await getSelectVal({ pg, values: ids, name: query.cls || attr });

    const legend = countArr.rows.map(cel => {
        const data = cls?.arr?.find(c => c.id?.toString?.() === cel.id?.toString?.()) || { text: clsData?.[cel.id]?.text || clsData?.[cel.id] };
        return { ...cel, ...data };
    });

    const { min, max } = await pg.queryCache(
        `select min(${attr}), max(${attr}) from ${source} where 1=1`,
    ).then(el => { return el.rows?.[0] || {}; });

    return reply.status(200).send({ legend, min, max });
}