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

import sendEmail from './sendEmail.js';

// eslint-disable-next-line max-len, no-control-regex
const emailReg = /(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/g;

const rclient = getRedis();

async function generateNotificationContent({
  pg, table, template, id, message, data: data1,
}) {
  if (template) {
    const data = table && id ? await pg.one(`select * from ${table} where ${pg.pk[table]}=$1`, [id]) : data1;
    // console.log(data);
    const body = await getTemplate('pt', template);
    // console.log(body);
    const html = handlebars.compile(body || template || 'template not found')(data || {});
    // console.log(html);
    return html;
  }
  return message;
}

// to do: refactor fastify-file to remove funcs completely
export default async function notification({
  pg = pgClients.client,
  provider = ['email'],
  from,
  to,
  template,
  table,
  message,
  title,
  file,
  data,
  id,
  nocache,
}) {
  if (pg?.readonly) {
    return null;
  }

  const keyTo = `${pg.options?.database}:mail:${provider[0]}:${to || ''}${id || ''}${table || ''}${title || ''}`;
  const uniqueTo = await rclient.setnx(keyTo, 1);

  if (!uniqueTo && !nocache) {
    logger.file('notification/sent', { keyTo, send: uniqueTo, nocache });
    return `already sent: ${keyTo}`;
  }
  await rclient.expire(keyTo, 1000 * 600);

  if (!to.length) {
    return null;
  }

  if (!(Array.isArray(provider) && provider.length)) {
    return 'notification provider - must be array and not empty';
  }

  const html = await generateNotificationContent({
    pg, table, template, id, message, data,
  });

  if (provider.includes('email')) {
    const files = Array.isArray(file) ? file : [file];
    const attachments = files?.length && false ? await Promise.all(files?.filter((el) => el).map(async (el) => {
      /* const content = await downloadFile(el, { buffer: true }); // ?
      return {
        filename: el.split('/').pop(),
        encoding: 'base64',
        content,
      }; */
    })) : [];

    const toEmail = Array.isArray(to) ? to.map((emails) => emails.match(emailReg)?.join(',')) : to;

    const result = await sendEmail({
      attachments,
      html,
      subject: title,
      from,
      to: toEmail,
    });

    return result;
  }
  return null;
}
