const prisma = require('../models/prisma');
const { validationResult } = require('express-validator');
const { ROLES } = require('../utils/roles');

exports.getByProject = async (req, res, next) => {
  try {
    const { projectId } = req.params;
    const { status, assigneeId, parentId } = req.query;

    const where = {
      projectId,
      parentId: parentId === 'null' ? null : parentId || undefined,
    };
    if (status) where.status = status;
    if (assigneeId) where.assigneeId = assigneeId;

    const tasks = await prisma.task.findMany({
      where,
      include: {
        assignee: { select: { id: true, firstName: true, lastName: true, avatarUrl: true } },
        creator: { select: { id: true, firstName: true, lastName: true } },
        _count: { select: { children: true, comments: true } },
      },
      orderBy: [{ priority: 'asc' }, { dueDate: 'asc' }],
    });

    res.json({ tasks });
  } catch (err) {
    next(err);
  }
};

exports.getById = async (req, res, next) => {
  try {
    const task = await prisma.task.findUniqueOrThrow({
      where: { id: req.params.id },
      include: {
        assignee: { select: { id: true, firstName: true, lastName: true, avatarUrl: true } },
        creator: { select: { id: true, firstName: true, lastName: true } },
        children: {
          include: {
            assignee: { select: { id: true, firstName: true, lastName: true } },
          },
        },
        comments: {
          include: { user: { select: { id: true, firstName: true, lastName: true } } },
          orderBy: { createdAt: 'asc' },
        },
      },
    });
    res.json({ task });
  } catch (err) {
    next(err);
  }
};

exports.create = async (req, res, next) => {
  try {
    const errors = validationResult(req);
    if (!errors.isEmpty()) return res.status(400).json({ errors: errors.array() });

    const task = await prisma.task.create({
      data: { ...req.body, createdById: req.user.id },
    });
    res.status(201).json({ task });
  } catch (err) {
    next(err);
  }
};

const ALLOWED_TASK_UPDATE_FIELDS = [
  'title', 'description', 'status', 'priority', 'assigneeId',
  'startDate', 'dueDate', 'estimatedHours', 'actualHours',
  'progressPct', 'parentId', 'tags',
];

const pickTaskFields = (obj) =>
  Object.fromEntries(Object.entries(obj).filter(([k]) => ALLOWED_TASK_UPDATE_FIELDS.includes(k)));

exports.update = async (req, res, next) => {
  try {
    const safeData = pickTaskFields(req.body);
    const task = await prisma.task.update({
      where: { id: req.params.id },
      data: safeData,
    });
    res.json({ task });
  } catch (err) {
    next(err);
  }
};

exports.updateStatus = async (req, res, next) => {
  try {
    const { status } = req.body;
    if (!status) return res.status(400).json({ message: 'status requerido' });

    const task = await prisma.task.update({
      where: { id: req.params.id },
      data: { status },
      include: {
        assignee: { select: { id: true, firstName: true, lastName: true } },
      },
    });
    res.json({ task });
  } catch (err) {
    next(err);
  }
};

exports.addComment = async (req, res, next) => {
  try {
    const { content } = req.body;
    if (!content?.trim()) return res.status(400).json({ message: 'Contenido requerido' });

    const comment = await prisma.comment.create({
      data: { taskId: req.params.id, userId: req.user.id, content: content.trim() },
      include: { user: { select: { id: true, firstName: true, lastName: true } } },
    });
    res.status(201).json({ comment });
  } catch (err) {
    next(err);
  }
};
