import { adminProcedure, createTRPCRouter } from "../trpc.js";
import { isAiConfigured } from "../ai-client.js";
import { DEFAULT_SUMMARY_PROMPT } from "./resource.js";
import { testSmtpConnection } from "../lib/email.js";
import { createAuditEntry } from "../lib/audit.js";
import { getRuntimeSecretStatuses, RUNTIME_SECRET_FIELDS, resolveSystemSettingsRuntime } from "../lib/system-settings-runtime.js";
import {
  buildSystemSettingsViewModel,
  buildSettingsUpdatePayload,
  sanitizeSettingsAuditSnapshot,
  settingsUpdateInputSchema,
  testRuntimeAiConnection,
} from "./settings-support.js";

export const settingsRouter = createTRPCRouter({
  getSystemSettings: adminProcedure.query(async ({ ctx }) => {
    const settings = await ctx.db.systemSettings.findUnique({
      where: { id: "singleton" },
    });
    const runtimeSettings = resolveSystemSettingsRuntime(settings);
    const runtimeSecrets = getRuntimeSecretStatuses(settings);
    return buildSystemSettingsViewModel({
      settings,
      runtimeSettings,
      runtimeSecrets,
      defaultSummaryPrompt: DEFAULT_SUMMARY_PROMPT,
    });
  }),

  updateSystemSettings: adminProcedure
    .input(settingsUpdateInputSchema)
    .mutation(async ({ ctx, input }) => {
      const { data, ignoredSecretFields } = buildSettingsUpdatePayload(input);

      if (Object.keys(data).length === 0) {
        return {
          ok: true,
          ignoredSecretFields,
          secretStorageMode: "environment-only" as const,
        };
      }

      // Fetch current settings for before-snapshot
      const before = await ctx.db.systemSettings.findUnique({ where: { id: "singleton" } });

      await ctx.db.systemSettings.upsert({
        where: { id: "singleton" },
        create: { id: "singleton", ...data },
        update: data,
      });

      const sanitizedBefore = before ? sanitizeSettingsAuditSnapshot(before as unknown as Record<string, unknown>) : undefined;
      const sanitizedAfter = sanitizeSettingsAuditSnapshot(data);

      void createAuditEntry({
        db: ctx.db,
        entityType: "SystemSettings",
        entityId: "singleton",
        entityName: "System Settings",
        action: before ? "UPDATE" : "CREATE",
        userId: ctx.dbUser?.id,
        ...(sanitizedBefore !== undefined ? { before: sanitizedBefore } : {}),
        after: sanitizedAfter,
        source: "ui",
      });

      return {
        ok: true,
        ignoredSecretFields,
        secretStorageMode: "environment-only" as const,
      };
    }),

  clearStoredRuntimeSecrets: adminProcedure.mutation(async ({ ctx }) => {
    const existing = await ctx.db.systemSettings.findUnique({
      where: { id: "singleton" },
      select: Object.fromEntries(
        RUNTIME_SECRET_FIELDS.map((field) => [field, true]),
      ) as Record<(typeof RUNTIME_SECRET_FIELDS)[number], true>,
    });

    const clearedFields = RUNTIME_SECRET_FIELDS.filter((field) => !!existing?.[field]);

    if (clearedFields.length === 0) {
      return { ok: true, clearedFields: [] as string[] };
    }

    await ctx.db.systemSettings.update({
      where: { id: "singleton" },
      data: Object.fromEntries(clearedFields.map((field) => [field, null])),
    });

    void createAuditEntry({
      db: ctx.db,
      entityType: "SystemSettings",
      entityId: "singleton",
      entityName: "Runtime Secrets",
      action: "UPDATE",
      userId: ctx.dbUser?.id,
      after: { clearedFields },
      source: "ui",
      summary: `Cleared ${clearedFields.length} legacy runtime secret field(s) from database storage`,
    });

    return { ok: true, clearedFields };
  }),

  testAiConnection: adminProcedure.mutation(async ({ ctx }) => {
    const settings = resolveSystemSettingsRuntime(await ctx.db.systemSettings.findUnique({
      where: { id: "singleton" },
    }));
    return testRuntimeAiConnection(settings);
  }),

  testSmtpConnection: adminProcedure.mutation(async ({ ctx }) => {
    const result = await testSmtpConnection();

    void createAuditEntry({
      db: ctx.db,
      entityType: "SystemSettings",
      entityId: "singleton",
      entityName: "SMTP Connection Test",
      action: "UPDATE",
      userId: ctx.dbUser?.id,
      after: { testResult: result.ok ? "success" : "failed" },
      source: "ui",
      summary: result.ok ? "SMTP connection test succeeded" : "SMTP connection test failed",
    });

    return result;
  }),

  testGeminiConnection: adminProcedure.mutation(async ({ ctx }) => {
    const settings = resolveSystemSettingsRuntime(await ctx.db.systemSettings.findUnique({
      where: { id: "singleton" },
      select: { geminiApiKey: true, geminiModel: true },
    }));

    if (!settings?.geminiApiKey) {
      return { ok: false, error: "Gemini API key is not configured." };
    }

    try {
      const { generateGeminiImage } = await import("../gemini-client.js");
      const model = settings.geminiModel ?? "gemini-2.5-flash-image";

      // Generate a tiny test image with a simple prompt
      const dataUrl = await generateGeminiImage(
        settings.geminiApiKey,
        "A simple blue circle on white background, minimal, 256x256",
        model,
      );

      const hasImage = dataUrl.startsWith("data:image/");

      void createAuditEntry({
        db: ctx.db,
        entityType: "SystemSettings",
        entityId: "singleton",
        entityName: "Gemini Connection Test",
        action: "UPDATE",
        userId: ctx.dbUser?.id,
        after: { testResult: hasImage ? "success" : "failed" },
        source: "ui",
        summary: hasImage ? "Gemini image generation test succeeded" : "Gemini test returned no image",
      });

      return { ok: hasImage, model, preview: hasImage ? dataUrl.slice(0, 100) + "..." : undefined };
    } catch (err) {
      const { parseGeminiError } = await import("../gemini-client.js");
      return { ok: false, error: parseGeminiError(err) };
    }
  }),

  getAiConfigured: adminProcedure.query(async ({ ctx }) => {
    const settings = resolveSystemSettingsRuntime(await ctx.db.systemSettings.findUnique({
      where: { id: "singleton" },
      select: {
        aiProvider: true,
        azureOpenAiEndpoint: true,
        azureOpenAiDeployment: true,
        azureOpenAiApiKey: true,
      },
    }));
    return { configured: isAiConfigured(settings) };
  }),
});
