import { NextResponse } from "next/server";
import { getSessionUser } from "@/lib/auth/get-session-user";
import { exchangeLinkedInCode } from "@/lib/auth/linkedin";
import { getLinkedInConfig, getSocialLinkedInRedirectUri } from "@/lib/env";
import { linkedInReconnectHint } from "@/lib/social/linkedin-scopes";
import { clearOAuthCookies, readOAuthCookies } from "@/lib/social/oauth-cookies";
import { isLinkedInExternalIdValid } from "@/lib/social/linkedin-member";
import { persistSocialConnection } from "@/lib/social/save-connection";

const PREFIX = "linkedin";

/** Exchange LinkedIn code — persists tokens server-side for the project. */
export async function POST(request: Request) {
  try {
    const user = await getSessionUser();
    if (!user) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });

    const body = (await request.json()) as { code?: string; state?: string };
    const { code, state } = body;

    if (!code || !state) {
      return NextResponse.json({ error: "code and state are required" }, { status: 400 });
    }

    const cookies = await readOAuthCookies(PREFIX);
    const savedState = cookies.state;
    const projectId = cookies.projectId;
    const returnTo = cookies.returnTo ?? "/connected-accounts";

    if (!savedState || savedState !== state) {
      return NextResponse.json({ error: "Invalid or expired OAuth state" }, { status: 400 });
    }

    if (!projectId) {
      return NextResponse.json({ error: "Missing project context for OAuth" }, { status: 400 });
    }

    const result = await exchangeLinkedInCode(code, getSocialLinkedInRedirectUri());

    if (!isLinkedInExternalIdValid(result.profile.accountId)) {
      const { scopeValidation } = getLinkedInConfig();
      return NextResponse.json(
        {
          error:
            "LinkedIn connected but member profile was not returned. " +
            linkedInReconnectHint(scopeValidation),
        },
        { status: 400 },
      );
    }

    const account = await persistSocialConnection(
      user.id,
      projectId,
      {
        platform: "linkedin",
        profileName: result.profile.accountName,
        accessToken: result.accessToken,
        refreshToken: result.refreshToken ?? null,
        expiresAt: result.expiresAt ?? null,
        externalId: result.profile.accountId,
      },
      { email: user.email, name: user.name },
    );

    const response = NextResponse.json({
      success: true,
      projectId,
      returnTo,
      platform: "linkedin",
      profileName: account.profileName,
      externalId: account.externalId,
      expiresAt: account.expiresAt,
    });

    clearOAuthCookies(response, PREFIX);
    return response;
  } catch (error) {
    const message = error instanceof Error ? error.message : "LinkedIn connection failed";
    return NextResponse.json({ error: message }, { status: 400 });
  }
}
