import { NextResponse } from "next/server";
import { pool } from "@/lib/db";

function escapeAttr(s: string): string {
  return s
    .replace(/&/g, "&amp;")
    .replace(/"/g, "&quot;")
    .replace(/</g, "&lt;")
    .replace(/>/g, "&gt;");
}

export async function POST(request: Request) {
  try {
    const form = await request.formData();
    const code = String(form.get("code") ?? "");
    const state = String(form.get("state") ?? "");
    const error = String(form.get("error") ?? "");
    const originHeader = request.headers.get("origin");
    const baseUrl = originHeader ?? new URL(request.url).origin;

    if (error) {
      return NextResponse.redirect(
        new URL(
          `/admin/settings/payments?error=square_oauth_denied&reason=${encodeURIComponent(error)}`,
          baseUrl,
        ),
      );
    }
    if (!code || !state) {
      return NextResponse.redirect(
        new URL("/admin/settings/payments?error=square_oauth_missing_params", baseUrl),
      );
    }

    let brandId: string | null = null;
    try {
      const decoded = JSON.parse(Buffer.from(state, "base64").toString("utf-8"));
      brandId = decoded?.brandId ?? null;
    } catch {
      return NextResponse.redirect(
        new URL("/admin/settings/payments?error=square_oauth_invalid_state", baseUrl),
      );
    }
    if (!brandId) {
      return NextResponse.redirect(
        new URL("/admin/settings/payments?error=square_oauth_missing_state", baseUrl),
      );
    }

    const appId = process.env.NEXT_PUBLIC_SQUARE_APP_ID;
    const appSecret = process.env.SQUARE_APP_SECRET;
    const env = process.env.SQUARE_ENVIRONMENT ?? "sandbox";
    if (!appId || !appSecret) {
      return NextResponse.redirect(
        new URL("/admin/settings/payments?error=square_credentials_not_configured", baseUrl),
      );
    }

    const tokenUrl =
      env === "production"
        ? "https://connect.squareup.com/v2/oauth2/token"
        : "https://connect.squareupsandbox.com/v2/oauth2/token";
    const redirectUri = `${baseUrl}/api/square/oauth/callback`;

    const tokenResponse = await fetch(tokenUrl, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "Square-Version": "2025-01-16",
      },
      body: JSON.stringify({
        client_id: appId,
        client_secret: appSecret,
        code,
        grant_type: "authorization_code",
        redirect_uri: redirectUri,
      }),
    });
    const tokenData = await tokenResponse.json();

    const accessToken: string | null = tokenData?.access_token ?? null;
    const locationId: string | null = tokenData?.location_id ?? null;
    if (!tokenResponse.ok || !accessToken) {
      return NextResponse.redirect(
        new URL("/admin/settings/payments?error=square_token_exchange_failed", baseUrl),
      );
    }

    await pool.query(
      "SELECT upsert_payment_settings($1, $2, $3, $4, $5, $6, $7, $8, $9)",
      [
        brandId,
        "square",
        null,
        null,
        null,
        accessToken,
        locationId,
        null,
        null,
      ],
    );

    return NextResponse.redirect(
      new URL("/admin/settings/payments?square_connected=true", baseUrl),
    );
  } catch (err) {
    const baseUrl = request.headers.get("origin") ?? new URL(request.url).origin;
    return NextResponse.redirect(
      new URL("/admin/settings/payments?error=square_token_save_error", baseUrl),
    );
  }
}

export async function GET() {
  // GET on /complete is not supported; redirect to settings.
  return NextResponse.redirect(new URL("/admin/settings/payments"));
}
