import { NextResponse } from "next/server";
import { getSessionUser } from "@/lib/auth/get-session-user";
import { writePublishLog } from "@/lib/logging/publish-logs";
import { ensureFreshAccountTokens, getLinkedInPublishBlockReason } from "@/lib/social/ensure-publish-tokens";
import { validateAccountsForPublish } from "@/lib/social/token-validation";
import { resolveScheduleSeed } from "@/lib/scheduling/resolve-schedule";
import { publishPostToPlatforms } from "@/lib/social/publish-post";
import {
  getGeneratedPost,
  updateGeneratedPostPublished,
} from "@/lib/storage/generated-posts";
import {
  mergeAccountsForPublish,
} from "@/lib/storage/social-accounts";
import type { ConnectedAccount } from "@/types/workflow";

export async function POST(
  request: Request,
  { params }: { params: Promise<{ id: string }> },
) {
  const user = await getSessionUser();
  if (!user) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  const { id } = await params;
  const body = (await request.json()) as {
    projectStatus?: string;
    accounts?: ConnectedAccount[];
    projectTimezone?: string;
    projectCountries?: string[];
    postsPerDay?: 1 | 2;
    scheduleSeed?: number;
    scheduleSaved?: boolean;
    forcePublish?: boolean;
    quickPublish?: boolean;
  };

  if (body.projectStatus === "paused") {
    await writePublishLog({
      level: "warn",
      action: "publish_blocked",
      postId: id,
      message: "Project is paused — publishing disabled.",
    });
    return NextResponse.json(
      {
        error: "Project is paused. Publishing is disabled.",
        code: "PROJECT_PAUSED",
      },
      { status: 403 },
    );
  }

  const existing = await getGeneratedPost(id);
  if (!existing) {
    return NextResponse.json({ error: "Post not found" }, { status: 404 });
  }
  if (existing.userId && existing.userId !== user.id) {
    return NextResponse.json({ error: "Forbidden" }, { status: 403 });
  }

  const serverAccounts = await ensureFreshAccountTokens(user.id, existing.projectId);

  const linkedInBlock = getLinkedInPublishBlockReason(serverAccounts);
  const linkedinWillPublish = body.quickPublish
    ? serverAccounts.some((a) => a.platform === "linkedin" && a.connected)
    : existing.platforms.includes("linkedin");
  if (linkedInBlock && linkedinWillPublish) {
    await writePublishLog({
      level: "error",
      action: "publish_blocked",
      projectId: existing.projectId,
      postId: id,
      platform: "linkedin",
      message: linkedInBlock,
    });
    return NextResponse.json(
      { error: linkedInBlock, code: "ACCOUNT_INVALID", platform: "linkedin" },
      { status: 403 },
    );
  }

  const mergedAccounts = mergeAccountsForPublish(body.accounts ?? [], serverAccounts);

  if (body.quickPublish) {
    const targets = mergeAccountsForPublish(body.accounts ?? [], serverAccounts).filter(
      (a) => a.connected && a.platform !== "youtube",
    );
    if (!targets.length && !serverAccounts.some((a) => a.platform === "youtube" && a.connected)) {
      return NextResponse.json(
        {
          error:
            "No connected publish-ready accounts. Connect LinkedIn, Facebook, or Instagram.",
          code: "NOT_CONNECTED",
        },
        { status: 403 },
      );
    }
  } else if (mergedAccounts.length && existing.platforms.length) {
    const validation = validateAccountsForPublish(mergedAccounts, existing.platforms, {
      allowServerStored: true,
    });
    if (!validation.ok) {
      await writePublishLog({
        level: "error",
        action: "publish_blocked",
        projectId: existing.projectId,
        postId: id,
        platform: validation.platform,
        message: validation.message,
      });
      return NextResponse.json(
        {
          error: validation.message,
          code: validation.platform ? "ACCOUNT_INVALID" : "NOT_CONNECTED",
          platform: validation.platform,
        },
        { status: 403 },
      );
    }
  } else if (existing.platforms.length) {
    const validation = validateAccountsForPublish(
      mergeAccountsForPublish([], serverAccounts),
      existing.platforms,
      { allowServerStored: true },
    );
    if (!validation.ok) {
      return NextResponse.json(
        { error: validation.message, code: "NOT_CONNECTED", platform: validation.platform },
        { status: 403 },
      );
    }
  }

  const result = await publishPostToPlatforms({
    post: existing,
    accounts: mergedAccounts.length ? mergedAccounts : mergeAccountsForPublish([], serverAccounts),
    projectTimezone: body.projectTimezone ?? "UTC",
    projectCountries: body.projectCountries ?? [],
    postsPerDay: body.postsPerDay ?? 2,
    scheduleSeed: resolveScheduleSeed(existing.projectId, body.scheduleSeed),
    scheduleSaved: body.scheduleSaved ?? false,
    forcePublish: body.forcePublish ?? body.quickPublish ?? false,
    quickPublish: body.quickPublish ?? false,
  });

  if (!result.ok) {
    return NextResponse.json(
      {
        error: result.error ?? "Publish failed",
        code: "PUBLISH_FAILED",
        outcomes: result.outcomes,
      },
      { status: 400 },
    );
  }

  const permalinks: Record<string, string> = {};
  for (const outcome of result.outcomes) {
    if (outcome.success && outcome.permalink) {
      permalinks[outcome.platform] = outcome.permalink;
    }
  }

  const post = await updateGeneratedPostPublished(id, permalinks);
  return NextResponse.json({
    success: true,
    post,
    outcomes: result.outcomes,
    message: `Published to ${result.outcomes.filter((o) => o.success).map((o) => o.platform).join(", ")}`,
  });
}
