import asyncHandler from 'express-async-handler';
import { escapeRegExp } from 'es-toolkit/compat';
import { Op } from 'sequelize';

import { REFERENCE_TYPES } from '@tamanu/constants';
import { NotFoundError } from '@tamanu/errors';
import { getResourceList } from '@tamanu/shared/utils/crudHelpers';

import { getDeletableDesignationOrThrow } from './designations.delete';

export const getDesignations = asyncHandler(async (req, res) => {
  req.checkPermission('list', 'ReferenceData');

  const idQuery = req.query.id?.trim();
  const nameQuery = req.query.name?.trim();

  const additionalFilters = { type: REFERENCE_TYPES.DESIGNATION };
  // Not matching word boundary; IDs often camel case
  if (idQuery) additionalFilters.id = { [Op.iLike]: `%${idQuery}%` };
  if (nameQuery) additionalFilters.name = { [Op.iRegexp]: `\\m${escapeRegExp(nameQuery)}` };

  const response = await getResourceList(req, 'ReferenceData', '', { additionalFilters });
  res.send(response);
});

export const getDesignationById = asyncHandler(async (req, res) => {
  req.checkPermission('read', 'ReferenceData');

  const {
    store: {
      models: { ReferenceData },
    },
    params: { id },
  } = req;

  const designation = await ReferenceData.findOne({
    where: { id, type: REFERENCE_TYPES.DESIGNATION },
  });
  if (!designation) {
    throw new NotFoundError(`No designation found with ID ‘${id}’`);
  }

  res.send(designation.forResponse());
});

export const getDesignationDeletabilityById = asyncHandler(async (req, res) => {
  req.checkPermission('delete', 'ReferenceData');

  const {
    store: { models, sequelize },
    params: { id },
  } = req;

  await sequelize.transaction({ readOnly: true }, async () => {
    await getDeletableDesignationOrThrow(models, id);
  });

  res.status(204).send();
});
