import { NextRequest, NextResponse } from "next/server";
import { getServerSession } from "next-auth";
import { authOptions } from "../../auth/authOptions";
import { PrismaClient, TaskStatus } from "@prisma/client";
import { TaskSchema } from "@/lib/validations/schemas";
import { successResponse, errorResponse, unauthorizedResponse, validationErrorResponse } from "@/lib/api-response";
import { z } from "zod";

const prisma = new PrismaClient();

function addCorsHeaders(response: NextResponse, request?: NextRequest) {
    const origin = request?.headers.get('origin') || '*';
    response.headers.set('Access-Control-Allow-Origin', origin);
    response.headers.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
    response.headers.set('Access-Control-Allow-Headers', 'Content-Type, Authorization');
    response.headers.set('Access-Control-Allow-Credentials', 'true');
    response.headers.set('Vary', 'Origin');
    return response;
}

export async function OPTIONS(request: NextRequest) {
    return addCorsHeaders(new NextResponse(null, { status: 204 }), request);
}

// Helper to wrap successResponse with CORS
const successResponseCors = (data: any, req: NextRequest, status = 200) => addCorsHeaders(successResponse(data, status), req);
const errorResponseCors = (msg: string, req: NextRequest, details?: any, status = 500) => addCorsHeaders(errorResponse(msg, details, status), req);

export async function GET(req: NextRequest, { params }: { params: Promise<{ id: string }> }) {
  const resolvedParams = await params;
  const taskId = parseInt(resolvedParams.id);

  if (isNaN(taskId)) {
    return errorResponseCors("Invalid Task ID", req, undefined, 400);
  }

  try {
    const session = await getServerSession(authOptions);
    if (!session) return addCorsHeaders(unauthorizedResponse(), req);

    const task = await prisma.task.findUnique({
      where: { id: taskId },
      include: {
        responsible: true,
        client: true,
        folder: true,
        calendarEvent: true,
        collaborators: { include: { user: true } },
        comments: { include: { user: true } },
      },
    });

    if (!task) return errorResponseCors("Task not found", req, undefined, 404);

    return successResponseCors(task, req);
  } catch (error: any) {
    return errorResponseCors("Error GET task by ID", req, error.message);
  }
}

export async function PUT(req: NextRequest, { params }: { params: Promise<{ id: string }> }) {
  const resolvedParams = await params;
  const taskId = parseInt(resolvedParams.id);

  if (isNaN(taskId)) {
    return errorResponseCors("Invalid Task ID", req, undefined, 400);
  }

  try {
    const session = await getServerSession(authOptions);
    if (!session || (session.user.role !== "MANAGER" && session.user.role !== "ADMIN")) {
      return addCorsHeaders(unauthorizedResponse(), req);
    }

    const rawData = await req.json();
    
    // Partial schema validation since PUT usually requires partial updates
    const PartialTaskSchema = TaskSchema.partial();
    
    try {
      PartialTaskSchema.parse(rawData);
    } catch (validationError: any) {
      if (validationError instanceof z.ZodError) {
        return addCorsHeaders(validationErrorResponse(validationError), req);
      }
    }

    const { 
      title, description, startDate, dueDate, responsibleId, 
      clientId, folderId, isAutomatic, priority, status, 
      completedAt, duration, appreciation, isPrivate 
    } = rawData;

    const updatedData: any = {
      title,
      description: description || null,
      startDate: startDate ? new Date(startDate) : null,
      dueDate: dueDate ? new Date(dueDate) : null,
      isAutomatic: isAutomatic || false,
      priority: priority || null,
      status: status || TaskStatus.PENDING,
      completedAt: completedAt ? new Date(completedAt) : null,
      duration: duration ? String(duration) : null,
      appreciation: appreciation || null,
      isPrivate: isPrivate || false,
    };

    if (responsibleId) {
      updatedData.responsible = { connect: { id: parseInt(responsibleId) } };
    }
    if (clientId) {
      updatedData.client = { connect: { id: parseInt(clientId) } };
    }
    if (folderId) {
      updatedData.folder = { connect: { id: parseInt(folderId) } };
    }

    const updatedTask = await prisma.task.update({
      where: { id: taskId },
      data: updatedData,
      include: { responsible: true, client: true, folder: true },
    });
    
    return successResponseCors(updatedTask, req);
  } catch (error: any) {
    return errorResponseCors("Error PUT task by ID", req, error.message, 400);
  }
}

export async function DELETE(req: NextRequest, { params }: { params: Promise<{ id: string }> }) {
  const resolvedParams = await params;
  const taskId = parseInt(resolvedParams.id);

  if (isNaN(taskId)) return errorResponseCors("Invalid Task ID", req, undefined, 400);

  try {
    const session = await getServerSession(authOptions);
    if (!session || (session.user.role !== "MANAGER" && session.user.role !== "ADMIN")) {
      return addCorsHeaders(unauthorizedResponse(), req);
    }
    
    await prisma.taskCollaborator.deleteMany({ where: { taskId: taskId } });
    await prisma.taskComment.deleteMany({ where: { taskId: taskId } });
    await prisma.task.delete({ where: { id: taskId } });
    
    return successResponseCors({ message: "Task deleted successfully" }, req);
  } catch (error: any) {
    return errorResponseCors("Error DELETE task by ID", req, error.message);
  }
}