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";
import { createWebhookSecret, encryptWebhookSecret } from "@/lib/developers/webhooks";

export async function GET(req: Request) {
  try {
    const supabase = await createRouteClient();
    const {
      data: { user },
    } = await supabase.auth.getUser();

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

    const url = new URL(req.url);
    const teamId = url.searchParams.get("teamId");
    const manageable = await canManageWorkspace(user.id, teamId);

    if (!manageable) {
      return NextResponse.json({ error: "Forbidden" }, { status: 403 });
    }

    const { rows } = teamId
      ? await sql`
          SELECT id, user_id, team_id, name, url, event_types, is_active, last_delivery_at, last_response_status, last_error, created_at, updated_at
          FROM webhook_endpoints
          WHERE team_id = ${teamId}
          ORDER BY created_at DESC
        `
      : await sql`
          SELECT id, user_id, team_id, name, url, event_types, is_active, last_delivery_at, last_response_status, last_error, created_at, updated_at
          FROM webhook_endpoints
          WHERE team_id IS NULL AND user_id = ${user.id}
          ORDER BY created_at DESC
        `;

    return NextResponse.json({ webhooks: rows });
  } catch (error) {
    logApiError("Webhook endpoints GET error", error);
    return NextResponse.json({ error: "Failed to load webhooks" }, { status: 500 });
  }
}

export async function POST(req: Request) {
  try {
    const supabase = await createRouteClient();
    const {
      data: { user },
    } = await supabase.auth.getUser();

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

    const body = await req.json();
    const teamId = typeof body.teamId === "string" && body.teamId ? body.teamId : null;
    const manageable = await canManageWorkspace(user.id, teamId);

    if (!manageable) {
      return NextResponse.json({ error: "Forbidden" }, { status: 403 });
    }

    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])
          )
      : [];

    if (!body.url || eventTypes.length === 0) {
      return NextResponse.json(
        { error: "Webhook URL and at least one event are required" },
        { status: 400 }
      );
    }

    const secret = createWebhookSecret();
    const name = String(body.name || "Webhook endpoint").trim() || "Webhook endpoint";
    const webhookUrl = String(body.url).trim();
    const isActive = body.isActive !== false;
    const signingSecretEncrypted = encryptWebhookSecret(secret);

    const { rows } = await sql`
      INSERT INTO webhook_endpoints
        (user_id, team_id, name, url, event_types, signing_secret_encrypted, is_active)
      VALUES
        (${user.id}, ${teamId}, ${name}, ${webhookUrl}, ${JSON.stringify(eventTypes)}, ${signingSecretEncrypted}, ${isActive})
      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 create webhook" }, { status: 400 });
    }

    return NextResponse.json({
      webhook: rows[0],
      signingSecret: secret,
    });
  } catch (error) {
    logApiError("Webhook endpoint POST error", error);
    return NextResponse.json({ error: "Failed to create webhook" }, { status: 500 });
  }
}
