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

async function createMaterial(req: Request, res: Response, next: NextFunction) {
  try {
    const material = await materialModel.createMaterial(req.body);
    return successResponse(res, 'Material created successfully', material, 201);
  } catch (error) {
    next(error);
    return;
  }
}

async function getMaterials(req: Request, res: Response, next: NextFunction) {
  try {
    const pagination = parsePagination(req.query);
    const [materials, total] = await Promise.all([
      materialModel.getMaterials(pagination),
      materialModel.countMaterials(),
    ]);
    return successResponse(res, 'Materials fetched successfully', paginatedResponse(materials, total, pagination));
  } catch (error) {
    next(error);
    return;
  }
}

async function getMaterial(req: Request, res: Response, next: NextFunction) {
  try {
    const material = await materialModel.getMaterialById(Number(req.params.id));
    if (!material) return void errorResponse(res, 'Material not found', 404);
    return successResponse(res, 'Material fetched successfully', material);
  } catch (error) {
    next(error);
    return;
  }
}

async function updateMaterial(req: Request, res: Response, next: NextFunction) {
  try {
    const material = await materialModel.updateMaterial(Number(req.params.id), req.body);
    return successResponse(res, 'Material updated successfully', material);
  } catch (error) {
    next(error);
    return;
  }
}

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

export { createMaterial, getMaterials, getMaterial, updateMaterial, deleteMaterial };
