import { NextResponse } from "next/server";
import { logApiError } from "@/lib/api/security";
import { createRouteClient } from "@/lib/supabase/route";
import {
  canManageWorkspace,
  generateDeveloperToken,
  getTokenPrefix,
  hashDeveloperToken,
  maskTokenPrefix,
} from "@/lib/developers/auth";
import { accessLevelFor, parseScopes, type TokenScopes } from "@/lib/developers/scopes";
import { insertToken, listTokens } from "@/lib/developers/token-store";

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 tokens = teamId
      ? await listTokens("team_id = $1", [teamId])
      : await listTokens("team_id IS NULL AND user_id = $1", [user.id]);

    return NextResponse.json({ tokens });
  } catch (error) {
    logApiError("Developer tokens GET error", error);
    return NextResponse.json({ error: "Failed to load API tokens" }, { 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 });
    }

    // Per-section rights (preferred). Without scopes the old access level applies to all sections except finances/vault.
    let scopes: TokenScopes | null = null;
    if (body.scopes !== undefined && body.scopes !== null) {
      const parsed = parseScopes(body.scopes);
      if (!parsed.ok) return NextResponse.json({ error: parsed.error }, { status: 400 });
      scopes = parsed.value;
    }

    const token = generateDeveloperToken();
    const tokenHash = hashDeveloperToken(token);
    const tokenPrefix = getTokenPrefix(token);
    const name = String(body.name || "Developer token").trim() || "Developer token";
    const accessLevel = scopes ? accessLevelFor(scopes) : body.accessLevel === "read_only" ? "read_only" : "read_write";
    const expiresAt =
      typeof body.expiresAt === "string" && body.expiresAt ? body.expiresAt : null;

    let created;
    try {
      created = await insertToken({ userId: user.id, teamId, name, accessLevel, scopes, tokenPrefix, tokenHash, expiresAt });
    } catch (error) {
      if ((error as { status?: number }).status === 409) {
        return NextResponse.json({ error: (error as Error).message }, { status: 409 });
      }
      throw error;
    }

    if (!created) {
      return NextResponse.json({ error: "Failed to create API token" }, { status: 400 });
    }

    return NextResponse.json({
      token: created,
      tokenValue: token,
      tokenHint: maskTokenPrefix(tokenPrefix),
    });
  } catch (error) {
    logApiError("Developer token POST error", error);
    return NextResponse.json({ error: "Failed to create API token" }, { status: 500 });
  }
}
