import { NextResponse } from "next/server";
import { accountHasStoredSession } from "@/lib/threads-browser";
import { prisma } from "@/lib/db";
import { setActiveAccountForUser } from "@/lib/account-context";
import { apiRouteErrorResponse } from "@/lib/auth/api";
import { requireSessionUser } from "@/lib/auth/session";

function accountSelect() {
  return {
    id: true,
    username: true,
    displayName: true,
    persona: true,
    styleProfile: true,
    styleBenchmark: true,
    brief: true,
    productBrief: true,
    targetAudience: true,
    goals: true,
    valid: true,
    storageState: true,
    updatedAt: true,
    threadsUserId: true,
    threadsTokenExpiresAt: true,
  } as const;
}

type RawAccount = Awaited<
  ReturnType<typeof prisma.account.findFirst<{ select: ReturnType<typeof accountSelect> }>>
>;

function toPublicAccount(account: NonNullable<RawAccount>) {
  const { threadsUserId, threadsTokenExpiresAt } = account;
  return {
    id: account.id,
    username: account.username,
    displayName: account.displayName,
    persona: account.persona,
    styleProfile: account.styleProfile,
    styleBenchmark: account.styleBenchmark,
    brief: account.brief,
    productBrief: account.productBrief,
    targetAudience: account.targetAudience,
    goals: account.goals,
    valid: account.valid,
    updatedAt: account.updatedAt,
    apiConnected: !!threadsUserId,
    browserConnected: accountHasStoredSession(account),
    sessionSynced: accountHasStoredSession(account),
    threadsUserId,
    threadsTokenExpiresAt: threadsTokenExpiresAt?.toISOString() ?? null,
  };
}

export async function GET() {
  try {
    const user = await requireSessionUser();
    const accounts = await prisma.account.findMany({
      where: { userId: user.id },
      orderBy: { updatedAt: "desc" },
      select: accountSelect(),
    });
    const activeAccountId = user.activeAccountId ?? accounts[0]?.id ?? null;

    if (!user.activeAccountId && activeAccountId) {
      await setActiveAccountForUser(user.id, activeAccountId);
    }

    return NextResponse.json({
      accounts: accounts.map(toPublicAccount),
      activeAccountId,
    });
  } catch (error) {
    return apiRouteErrorResponse(error, "accounts");
  }
}

export async function POST(request: Request) {
  try {
    const user = await requireSessionUser();
    const body = (await request.json()) as {
      displayName?: string;
      username?: string;
      persona?: string;
      brief?: string;
      productBrief?: string;
      targetAudience?: string;
      goals?: string;
      activate?: boolean;
    };

    const account = await prisma.account.create({
      data: {
        userId: user.id,
        displayName: body.displayName?.trim() || body.username?.trim() || "新經營帳號",
        username: body.username?.replace(/^@/, "").trim() || null,
        persona: body.persona?.trim() || null,
        brief: body.brief?.trim() || null,
        productBrief: body.productBrief?.trim() || null,
        targetAudience: body.targetAudience?.trim() || null,
        goals: body.goals?.trim() || null,
        storageState: "",
        valid: false,
      },
      select: accountSelect(),
    });

    if (body.activate ?? true) {
      await setActiveAccountForUser(user.id, account.id);
    }

    return NextResponse.json({ account: toPublicAccount(account) });
  } catch (error) {
    return apiRouteErrorResponse(error, "accounts/create");
  }
}
