import { apiError } from "@/lib/auth";
import { ensureSchema, rawDb } from "@/lib/db";
import { exchangeOAuthCode, type Platform } from "@/lib/meta";

type StateRow = { id: string; owner_id: string; brand_id: string; platform: Platform; expires_at: number };

export async function GET(request: Request) {
  const destination = new URL("/", request.url);
  destination.searchParams.set("view", "brands");
  try {
    const url = new URL(request.url);
    const code = url.searchParams.get("code");
    const stateId = url.searchParams.get("state");
    if (!code || !stateId) throw new Error(url.searchParams.get("error_description") || "연결이 취소되었습니다.");
    await ensureSchema();
    const db = rawDb();
    const state = await db.prepare("SELECT * FROM oauth_states WHERE id = ?").bind(stateId).first<StateRow>();
    if (!state || state.expires_at < Date.now()) throw new Error("연결 요청이 만료되었습니다. 다시 시도해주세요.");
    await db.prepare("DELETE FROM oauth_states WHERE id = ?").bind(stateId).run();
    const account = await exchangeOAuthCode(state.platform, code, request.url);
    const now = Date.now();
    await db.prepare(`INSERT INTO social_accounts
      (id, owner_id, brand_id, platform, platform_user_id, username, profile_image_url,
       token_encrypted, token_iv, token_expires_at, status, created_at, updated_at)
      VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'connected', ?, ?)
      ON CONFLICT(brand_id, platform, platform_user_id) DO UPDATE SET
       username = excluded.username, profile_image_url = excluded.profile_image_url,
       token_encrypted = excluded.token_encrypted, token_iv = excluded.token_iv,
       token_expires_at = excluded.token_expires_at, status = 'connected', updated_at = excluded.updated_at`)
      .bind(crypto.randomUUID(), state.owner_id, state.brand_id, state.platform, account.platformUserId,
        account.username, account.profileImageUrl, account.tokenEncrypted, account.tokenIv,
        account.tokenExpiresAt, now, now).run();
    destination.searchParams.set("brandId", state.brand_id);
    destination.searchParams.set("oauth", "connected");
    destination.searchParams.set("platform", state.platform);
    return Response.redirect(destination, 302);
  } catch (error) {
    const response = apiError(error);
    const payload = await response.clone().json().catch(() => ({ error: "연결하지 못했습니다." })) as { error?: string };
    destination.searchParams.set("oauth", "error");
    destination.searchParams.set("message", payload.error || "연결하지 못했습니다.");
    return Response.redirect(destination, 302);
  }
}
