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

// ?projectId=5 filters to one project; ?parentId=root filters to top-level
// nodes only; ?parentId=12 filters to direct children of that node.
function parseListFilter(query: Request['query']): wbsModel.WbsListFilter {
  const projectId = query.projectId ? Number(query.projectId) : undefined;
  const rawParentId = query.parentId;
  const parentId = rawParentId === 'root' ? 'root' : rawParentId ? Number(rawParentId) : undefined;
  return { projectId, parentId };
}

async function createWbs(req: Request, res: Response, next: NextFunction) {
  try {
    const wbs = await wbsModel.createWbs(req.body);
    return successResponse(res, 'WBS item created successfully', wbs, 201);
  } catch (error) {
    next(error);
    return;
  }
}

async function getWbsItems(req: Request, res: Response, next: NextFunction) {
  try {
    const pagination = parsePagination(req.query);
    const filter = parseListFilter(req.query);
    const [items, total] = await Promise.all([
      wbsModel.getWbsItems(pagination, filter),
      wbsModel.countWbsItems(filter),
    ]);
    return successResponse(res, 'WBS items fetched successfully', paginatedResponse(items, total, pagination));
  } catch (error) {
    next(error);
    return;
  }
}

async function getWbs(req: Request, res: Response, next: NextFunction) {
  try {
    const wbs = await wbsModel.getWbsById(Number(req.params.id));
    if (!wbs) return void errorResponse(res, 'WBS item not found', 404);
    return successResponse(res, 'WBS item fetched successfully', wbs);
  } catch (error) {
    next(error);
    return;
  }
}

async function updateWbs(req: Request, res: Response, next: NextFunction) {
  try {
    const wbs = await wbsModel.updateWbs(Number(req.params.id), req.body);
    return successResponse(res, 'WBS item updated successfully', wbs);
  } catch (error) {
    next(error);
    return;
  }
}

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

export { createWbs, getWbsItems, getWbs, updateWbs, deleteWbs };
