import type { Request, Response } from 'express';
import { paramStr, queryNum, queryStr } from '@/api/http/request';
import { toCsv } from '@/shared/csv';
import Service from '@/services/permissions';
import processFile from '@/middlewares/upload';
import ValidationError from '@/shared/errors/validation';

const CSV_FIELDS = ['id', 'name'];

export async function create(req: Request, res: Response): Promise<void> {
  await Service.create(req.body.data, req.currentUser);
  res.status(200).send(true);
}

export async function bulkImport(req: Request, res: Response): Promise<void> {
  await processFile(req, res);

  if (!req.file) {
    throw new ValidationError('importer.errors.invalidFileEmpty');
  }

  await Service.bulkImport(req.file.buffer, req.currentUser);
  res.status(200).send(true);
}

export async function update(req: Request, res: Response): Promise<void> {
  await Service.update(req.body.data, req.body.id, req.currentUser);
  res.status(200).send(true);
}

export async function remove(req: Request, res: Response): Promise<void> {
  await Service.remove(paramStr(req.params.id), req.currentUser);
  res.status(200).send(true);
}

export async function deleteByIds(req: Request, res: Response): Promise<void> {
  await Service.deleteByIds(req.body.data, req.currentUser);
  res.status(200).send(true);
}

export async function list(req: Request, res: Response): Promise<void> {
  const payload = await Service.list(req.query, req.currentUser);

  if (req.query.filetype === 'csv') {
    const csv = toCsv(payload.rows, CSV_FIELDS);
    res.status(200).attachment(csv);
    res.send(csv);
  } else {
    res.status(200).send(payload);
  }
}

export async function count(req: Request, res: Response): Promise<void> {
  const payload = await Service.count(req.query, req.currentUser);
  res.status(200).send(payload);
}

export async function autocomplete(req: Request, res: Response): Promise<void> {
  const payload = await Service.autocomplete(
    queryStr(req.query.query),
    queryNum(req.query.limit),
    queryNum(req.query.offset),
  );
  res.status(200).send(payload);
}

export async function findById(req: Request, res: Response): Promise<void> {
  const payload = await Service.findById(paramStr(req.params.id));
  res.status(200).send(payload);
}
