import type { Request, Response, NextFunction } from 'express';
import * as costCodeModel from '../models/costCode.model.js';
import { successResponse, errorResponse } from '../utils/response.js';
import { parsePagination, paginatedResponse } from '../utils/pagination.js';

async function createCostCode(req: Request, res: Response, next: NextFunction) {
  try {
    const costCode = await costCodeModel.createCostCode(req.body);
    return successResponse(res, 'Cost code created successfully', costCode, 201);
  } catch (error) {
    next(error);
    return;
  }
}

async function getCostCodes(req: Request, res: Response, next: NextFunction) {
  try {
    const pagination = parsePagination(req.query);
    const [costCodes, total] = await Promise.all([
      costCodeModel.getCostCodes(pagination),
      costCodeModel.countCostCodes(),
    ]);
    return successResponse(res, 'Cost codes fetched successfully', paginatedResponse(costCodes, total, pagination));
  } catch (error) {
    next(error);
    return;
  }
}

async function getCostCode(req: Request, res: Response, next: NextFunction) {
  try {
    const costCode = await costCodeModel.getCostCodeById(Number(req.params.id));
    if (!costCode) return void errorResponse(res, 'Cost code not found', 404);
    return successResponse(res, 'Cost code fetched successfully', costCode);
  } catch (error) {
    next(error);
    return;
  }
}

async function updateCostCode(req: Request, res: Response, next: NextFunction) {
  try {
    const costCode = await costCodeModel.updateCostCode(Number(req.params.id), req.body);
    return successResponse(res, 'Cost code updated successfully', costCode);
  } catch (error) {
    next(error);
    return;
  }
}

async function deleteCostCode(req: Request, res: Response, next: NextFunction) {
  try {
    await costCodeModel.deleteCostCode(Number(req.params.id));
    return successResponse(res, 'Cost code deleted successfully');
  } catch (error) {
    next(error);
    return;
  }
}

export { createCostCode, getCostCodes, getCostCode, updateCostCode, deleteCostCode };
