import { NextResponse } from "next/server";
import { logApiError } from "@/lib/api/security";
import { createRouteClient } from "@/lib/supabase/route";
import { sql } from "@/lib/db/postgres";
import { WEBHOOK_EVENT_VALUES } from "@/lib/developers/catalog";
import { canManageWorkspace } from "@/lib/developers/auth";

export async function PATCH(
  req: Request,
  context: { params: Promise<{ id: string }> }
) {
  try {
    const supabase = await createRouteClient();
    const {
      data: { user },
    } = await supabase.auth.getUser();

    if (!user) {
      return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
    }

    const { id } = await context.params;
    const { rows: existingRows } = await sql`
      SELECT id, team_id FROM webhook_endpoints WHERE id = ${id}
    `;
    const existing = existingRows[0];

    if (!existing) {
      return NextResponse.json({ error: "Webhook not found" }, { status: 404 });
    }

    const manageable = await canManageWorkspace(user.id, (existing.team_id as string | null) || null);
    if (!manageable) {
      return NextResponse.json({ error: "Forbidden" }, { status: 403 });
    }

    const body = await req.json();
    const eventTypes = Array.isArray(body.eventTypes)
      ? body.eventTypes
          .map((value: unknown) => String(value))
          .filter(
            (value: string): value is (typeof WEBHOOK_EVENT_VALUES)[number] =>
              WEBHOOK_EVENT_VALUES.includes(value as (typeof WEBHOOK_EVENT_VALUES)[number])
          )
      : undefined;

    // Build partial update using COALESCE to keep existing values when not provided
    const newName =
      typeof body.name === "string" ? body.name.trim() || "Webhook endpoint" : null;
    const newUrl = typeof body.url === "string" ? body.url.trim() : null;
    const newEventTypes = Array.isArray(eventTypes) ? JSON.stringify(eventTypes) : null;
    const newIsActive = typeof body.isActive === "boolean" ? body.isActive : null;

    const { rows } = await sql`
      UPDATE webhook_endpoints
      SET
        name        = COALESCE(${newName}, name),
        url         = COALESCE(${newUrl}, url),
        event_types = COALESCE(${newEventTypes}::jsonb, event_types),
        is_active   = COALESCE(${newIsActive}, is_active),
        updated_at  = NOW()
      WHERE id = ${id}
      RETURNING id, user_id, team_id, name, url, event_types, is_active, last_delivery_at, last_response_status, last_error, created_at, updated_at
    `;

    if (!rows[0]) {
      return NextResponse.json({ error: "Failed to update webhook" }, { status: 400 });
    }

    return NextResponse.json({ webhook: rows[0] });
  } catch (error) {
    logApiError("Webhook PATCH error", error);
    return NextResponse.json({ error: "Failed to update webhook" }, { status: 500 });
  }
}

export async function DELETE(
  _req: Request,
  context: { params: Promise<{ id: string }> }
) {
  try {
    const supabase = await createRouteClient();
    const {
      data: { user },
    } = await supabase.auth.getUser();

    if (!user) {
      return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
    }

    const { id } = await context.params;
    const { rows: existingRows } = await sql`
      SELECT id, team_id FROM webhook_endpoints WHERE id = ${id}
    `;
    const existing = existingRows[0];

    if (!existing) {
      return NextResponse.json({ error: "Webhook not found" }, { status: 404 });
    }

    const manageable = await canManageWorkspace(user.id, (existing.team_id as string | null) || null);
    if (!manageable) {
      return NextResponse.json({ error: "Forbidden" }, { status: 403 });
    }

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

    return NextResponse.json({ success: true });
  } catch (error) {
    logApiError("Webhook DELETE error", error);
    return NextResponse.json({ error: "Failed to delete webhook" }, { status: 500 });
  }
}
