import { logApiError } from "@/lib/api/security";
import { NextResponse } from "next/server";
import { canManageOrganizationWorkspace } from "@/lib/organization-auth";
import { createRouteClient } from "@/lib/supabase/route";
import { sql } from "@/lib/db/postgres";

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 body = await req.json();
    const status = String(body.status || "").trim();

    if (!["approved", "declined", "withdrawn"].includes(status)) {
      return NextResponse.json({ error: "Invalid join request status" }, { status: 400 });
    }

    const { rows: requestRows } = await sql`
      SELECT * FROM organization_join_requests WHERE id = ${id} LIMIT 1
    `;
    const requestRow = requestRows[0];

    if (!requestRow) {
      return NextResponse.json({ error: "Join request not found" }, { status: 404 });
    }

    if (status === "withdrawn") {
      if (requestRow.user_id !== user.id) {
        return NextResponse.json({ error: "Forbidden" }, { status: 403 });
      }

      let data: Record<string, unknown>;
      try {
        const { rows } = await sql`
          UPDATE organization_join_requests
          SET status = 'withdrawn'
          WHERE id = ${id}
          RETURNING *
        `;
        data = rows[0];
      } catch (updateError) {
        const msg = updateError instanceof Error ? updateError.message : "Join request could not be updated";
        return NextResponse.json({ error: msg }, { status: 400 });
      }

      return NextResponse.json({ request: data });
    }

    const canManage = await canManageOrganizationWorkspace({
      organizationId: requestRow.organization_id as string,
      userId: user.id,
    });

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

    if (status === "approved") {
      try {
        await sql`
          INSERT INTO organization_members (organization_id, user_id, role, title, seat_status, counts_toward_seat)
          VALUES (
            ${requestRow.organization_id as string},
            ${requestRow.user_id as string},
            'member',
            'Joined via request',
            'active',
            true
          )
          ON CONFLICT (organization_id, user_id) DO UPDATE SET
            role = EXCLUDED.role,
            title = EXCLUDED.title,
            seat_status = EXCLUDED.seat_status,
            counts_toward_seat = EXCLUDED.counts_toward_seat
        `;
      } catch (memberError) {
        const msg = memberError instanceof Error ? memberError.message : "Member could not be added";
        return NextResponse.json({ error: msg }, { status: 400 });
      }
    }

    let data: Record<string, unknown>;
    try {
      const { rows } = await sql`
        UPDATE organization_join_requests
        SET status = ${status}, reviewed_at = ${new Date().toISOString()}, reviewed_by = ${user.id}
        WHERE id = ${id}
        RETURNING *
      `;
      data = rows[0];
    } catch (updateError) {
      const msg = updateError instanceof Error ? updateError.message : "Join request could not be updated";
      return NextResponse.json({ error: msg }, { status: 400 });
    }

    return NextResponse.json({ request: data });
  } catch (error) {
    logApiError("Organization join request PATCH error:", error);
    return NextResponse.json({ error: "Join request could not be updated" }, { status: 500 });
  }
}
