import { NextResponse } from "next/server";
import { prisma } from "@/lib/db";
import { apiRouteErrorResponse } from "@/lib/auth/api";
import { requireSessionUser } from "@/lib/auth/session";
import { getOrCreateSettingsForUser } from "@/lib/user-settings";
import {
  getApiKeyStatus,
  getMaskedProviderApiKeys,
  mergeProviderApiKeys,
  parseProviderApiKeys,
  serializeProviderApiKeys,
  type ProviderApiKeys,
} from "@/lib/ai/keys";
import { getAppBaseUrl } from "@/lib/threads-api";
import type { Setting } from "@prisma/client";

function toPublicSettings(settings: Setting, request?: Request) {
  const apiKeys = parseProviderApiKeys(settings.providerApiKeys);

  return {
    id: settings.id,
    persona: settings.persona,
    aiProvider: settings.aiProvider,
    aiModel: settings.aiModel,
    researchAiProvider: settings.researchAiProvider,
    researchAiModel: settings.researchAiModel,
    draftsPerScan: settings.draftsPerScan,
    matrixRows: settings.matrixRows,
    scanCron: settings.scanCron,
    appUrl: settings.appUrl,
    threadsOAuthRedirectUri: request
      ? `${getAppBaseUrl(request, settings.appUrl)}/api/threads/oauth/callback`
      : null,
    apiKeys: getMaskedProviderApiKeys(apiKeys),
    apiKeysConfigured: getApiKeyStatus(apiKeys),
  };
}

export async function GET(request: Request) {
  try {
    const user = await requireSessionUser();
    const settings = await getOrCreateSettingsForUser(user.id);
    return NextResponse.json(toPublicSettings(settings, request));
  } catch (error) {
    return apiRouteErrorResponse(error, "settings");
  }
}

export async function PATCH(request: Request) {
  try {
    const user = await requireSessionUser();
    const body = await request.json();
    const current = await getOrCreateSettingsForUser(user.id);
    const existingKeys = parseProviderApiKeys(current.providerApiKeys);

    let providerApiKeys = existingKeys;
    if (body.apiKeys && typeof body.apiKeys === "object") {
      providerApiKeys = mergeProviderApiKeys(existingKeys, body.apiKeys as ProviderApiKeys);
    }

    const settings = await prisma.setting.update({
      where: { userId: user.id },
      data: {
        ...(body.persona !== undefined && { persona: body.persona }),
        ...(body.aiProvider !== undefined && { aiProvider: body.aiProvider }),
        ...(body.aiModel !== undefined && { aiModel: body.aiModel }),
        ...(body.researchAiProvider !== undefined && { researchAiProvider: body.researchAiProvider }),
        ...(body.researchAiModel !== undefined && { researchAiModel: body.researchAiModel }),
        ...(body.draftsPerScan !== undefined && { draftsPerScan: body.draftsPerScan }),
        ...(body.matrixRows !== undefined && { matrixRows: body.matrixRows }),
        ...(body.scanCron !== undefined && { scanCron: body.scanCron }),
        ...(body.appUrl !== undefined && {
          appUrl: (() => {
            const trimmed = body.appUrl?.trim();
            if (!trimmed) return null;
            try {
              const url = new URL(trimmed);
              if (!["http:", "https:"].includes(url.protocol)) return null;
              return `${url.protocol}//${url.host}`;
            } catch {
              return null;
            }
          })(),
        }),
        ...(body.apiKeys !== undefined && {
          providerApiKeys: serializeProviderApiKeys(providerApiKeys),
        }),
      },
    });

    return NextResponse.json(toPublicSettings(settings, request));
  } catch (error) {
    return apiRouteErrorResponse(error, "settings/update");
  }
}