import { NextResponse } from "next/server";
import { authenticateDeveloperRequest } from "@/lib/developers/auth";
import { emitWorkspaceWebhookEvent } from "@/lib/developers/webhooks";
import { logProjectActivity } from "@/lib/project-activity";
import { logTeamAudit } from "@/lib/team-audit";
import { sql } from "@/lib/db/postgres";
import type { Task } from "@/types";

async function loadOwnedTask(
  id: string,
  workspaceUserId: string,
  workspaceTeamId: string | null
) {
  const { rows } = workspaceTeamId
    ? await sql<Task>`SELECT * FROM tasks WHERE id = ${id} AND team_id = ${workspaceTeamId} LIMIT 1`
    : await sql<Task>`SELECT * FROM tasks WHERE id = ${id} AND team_id IS NULL AND user_id = ${workspaceUserId} LIMIT 1`;
  return rows[0] ?? null;
}

export async function GET(req: Request, context: { params: Promise<{ id: string }> }) {
  const auth = await authenticateDeveloperRequest(req, { section: "tasks" });
  if (!auth) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });

  const { id } = await context.params;
  const task = await loadOwnedTask(id, auth.workspaceUserId, auth.workspaceTeamId);
  if (!task) return NextResponse.json({ error: "Task not found" }, { status: 404 });

  return NextResponse.json({ task });
}

export async function PATCH(req: Request, context: { params: Promise<{ id: string }> }) {
  const auth = await authenticateDeveloperRequest(req, { write: true, section: "tasks" });
  if (!auth) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });

  const { id } = await context.params;
  const current = await loadOwnedTask(id, auth.workspaceUserId, auth.workspaceTeamId);
  if (!current) return NextResponse.json({ error: "Task not found" }, { status: 404 });

  const body = await req.json();
  const title = typeof body.title === "string" && body.title.trim() ? body.title.trim() : current.title;
  const description = typeof body.description === "string" ? body.description : current.description;
  const priority =
    body.priority === "urgent" ||
    body.priority === "high" ||
    body.priority === "medium" ||
    body.priority === "low" ||
    body.priority === "none"
      ? body.priority
      : current.priority;
  const status =
    body.status === "todo" ||
    body.status === "in_progress" ||
    body.status === "done" ||
    body.status === "cancelled"
      ? body.status
      : current.status;
  const deadline = body.deadline !== undefined ? (typeof body.deadline === "string" ? body.deadline : null) : current.deadline;
  const project_id = body.project_id !== undefined ? (typeof body.project_id === "string" ? body.project_id : null) : current.project_id;
  const goal_id = body.goal_id !== undefined ? (typeof body.goal_id === "string" ? body.goal_id : null) : current.goal_id;
  const assignee_id = body.assignee_id !== undefined ? (typeof body.assignee_id === "string" ? body.assignee_id : null) : current.assignee_id;
  const reviewer_id = body.reviewer_id !== undefined ? (typeof body.reviewer_id === "string" ? body.reviewer_id : null) : current.reviewer_id;
  const review_notes = typeof body.review_notes === "string" ? body.review_notes : current.review_notes;
  // Completing/un-completing a task through the API mirrors the "abhaken" checkbox in the UI.
  const completed_at = status === "done" ? current.completed_at || new Date().toISOString() : status === current.status ? current.completed_at : null;

  const { rows } = await sql<Task>`
    UPDATE tasks SET
      title = ${title},
      description = ${description},
      priority = ${priority},
      status = ${status},
      deadline = ${deadline},
      project_id = ${project_id},
      goal_id = ${goal_id},
      assignee_id = ${assignee_id},
      reviewer_id = ${reviewer_id},
      review_notes = ${review_notes},
      completed_at = ${completed_at}
    WHERE id = ${id}
    RETURNING *
  `;
  const task = rows[0];

  await logProjectActivity(auth.admin, {
    userId: auth.workspaceUserId,
    projectId: task.project_id,
    entityType: "task",
    entityId: task.id,
    action: "task_updated",
    title: task.title,
    details: { status: task.status, priority: task.priority },
  });
  await logTeamAudit(auth.admin, {
    teamId: auth.workspaceTeamId,
    actorId: auth.workspaceUserId,
    action: "task_updated",
    entityType: "task",
    entityId: task.id,
    title: task.title,
    details: { status: task.status, priority: task.priority },
  });
  await emitWorkspaceWebhookEvent({
    userId: auth.workspaceUserId,
    teamId: auth.workspaceTeamId,
    actorId: auth.workspaceUserId,
    eventType: "task.updated",
    data: { task, source: "developer_api" },
  });

  return NextResponse.json({ task });
}

export async function DELETE(req: Request, context: { params: Promise<{ id: string }> }) {
  const auth = await authenticateDeveloperRequest(req, { write: true, section: "tasks" });
  if (!auth) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });

  const { id } = await context.params;
  const current = await loadOwnedTask(id, auth.workspaceUserId, auth.workspaceTeamId);
  if (!current) return NextResponse.json({ error: "Task not found" }, { status: 404 });

  await sql`DELETE FROM tasks WHERE id = ${id}`;

  await logTeamAudit(auth.admin, {
    teamId: auth.workspaceTeamId,
    actorId: auth.workspaceUserId,
    action: "task_deleted",
    entityType: "task",
    entityId: current.id,
    title: current.title,
  });
  await emitWorkspaceWebhookEvent({
    userId: auth.workspaceUserId,
    teamId: auth.workspaceTeamId,
    actorId: auth.workspaceUserId,
    eventType: "task.deleted",
    data: { task: { id: current.id, title: current.title }, source: "developer_api" },
  });

  return NextResponse.json({ success: true });
}
