import { createHash } from 'node:crypto';

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

import mapnik from '../../../plugins/mapnik/funcs/mapnik.js';

const { ClearTile } = mapnik();

/**
 * Формування растрового tile cartoCss
 *
 * @method GET
 * @alias rtile
 * @param {String} bbox - bbox
 * @param {Number} height - висота по координатам
 * @param {Number} width - ширина по координатам
 * @param {String} data - стилізація
 * @param {String} lang - мова
 * @param {String} z - координата z
 * @param {String} x - координата y
 * @param {String} y - координата x
 */

export default async function clearTiles({
    pg = pgClients.client, params, query,
}, reply) {
    if (!ClearTile) {
        return reply.status(400).send({ error: 'mapnik server address needed', code: 400 });
    }

    if (!params.id) {
        return reply.status(400).send({ error: 'not enough params: id', code: 400 });
    }

    const decodedPath = Buffer.from(params.id, 'base64url').toString('utf-8');

    const raster = pg.pk?.['gis.rasters']
        ? await pg.query(`select raster_id, source_path from gis.rasters where raster_id=$1::text union all
        select raster_id, source_path from gis.rasters where source_path=$2::text`, [params.id, decodedPath]).then(el => el.rows?.[0] || {})
        : {};

    const carto = pg.pk?.['gis.cartocss']
        ? await pg.query(`select cartocss_id, source_path from gis.cartocss where cartocss_id=$1::text union all
        select cartocss_id, source_path from gis.cartocss where source_path=$2::text`, [params.id, decodedPath]).then(el => el.rows?.[0] || {})
        : {};

    if (!raster.raster_id && !carto.cartocss_id) {
        Object.assign(raster, { source_path: decodedPath });
    }

    if (!raster.source_path && !carto.cartocss_id) {
        return reply.status(404).send({ error: 'raster / cartocss not found', code: 404 });
    }

    if (query.debug) {
        const md5 = raster.source_path
            ? createHash('md5').update(raster.source_path).digest('hex')
            : undefined;
        const base64 = raster.source_path
            ? Buffer.from(raster.source_path).toString('base64url')
            : undefined;
        return {
            id: raster.raster_id || carto.cartocss_id,
            carto: !!carto.cartocss_id,
            raster: !!raster.raster_id,
            md5_path: md5,
            base64_path: base64,
            source_path: raster.source_path || carto.source_path,
        };
    }

    try {
        const data = await ClearTile({
            path: carto.cartocss_id ? null : raster.source_path, // for rasters only
            name: carto.cartocss_id && carto.source_path ? `vector/${carto.source_path}` : params.id, // required for cartocss
        });

        // if empty directory not found (no tiles rendered yet)
        if (data.result === 'skip') {
            return reply.status(200).send({ message: 'tiles directory not found', code: 200 });
        }

        // if cache deleted or empty directory exists = ok
        if (data.result === 'success') {
            return reply.status(200).send({ message: 'ok', code: 200 });
        }

        throw new Error(data.err);
    }
    catch (err) {
        logger.file('clearTiles/error', { error: err.toString(), stack: err.stack });
        return reply.status(500).send({ error: config.local ? err.toString() : 'clearTiles error', code: 500 });
    }
}
