import type { FastifyInstance } from 'fastify';
import { authenticate, requireRole } from '../middleware/auth.js';
import { auditService } from '../services/auditService.js';
import { getPlatformSettings, updatePlatformSettings } from '../services/platformSettingsService.js';
import {
  invalidateOpenAiCredentialsCache,
  listOpenAiModels,
} from '../services/openaiService.js';
import {
  invalidateOpenRouterCredentialsCache,
  listOpenRouterModels,
  OPENROUTER_BUDGET_MODELS,
  resolveOpenRouterCredentials,
} from '../services/openrouterService.js';

const adminGuard = [authenticate, requireRole('admin')];

export async function settingsRoutes(fastify: FastifyInstance) {
  // GET /api/v1/settings/platform — never returns the raw API key
  fastify.get('/platform', { preHandler: adminGuard }, async (_req, reply) => {
    const row = await getPlatformSettings();
    const hasDbKey = Boolean(row?.openai_api_key?.trim());
    const hasEnvKey = Boolean(process.env.OPENAI_API_KEY?.trim());
    let openai_key_source: 'database' | 'environment' | 'none' = 'none';
    if (hasDbKey) openai_key_source = 'database';
    else if (hasEnvKey) openai_key_source = 'environment';

    const hasOpenRouterDbKey = Boolean(row?.openrouter_api_key?.trim());
    const hasOpenRouterEnvKey = Boolean(process.env.OPENROUTER_API_KEY?.trim());
    let openrouter_key_source: 'database' | 'environment' | 'none' = 'none';
    if (hasOpenRouterDbKey) openrouter_key_source = 'database';
    else if (hasOpenRouterEnvKey) openrouter_key_source = 'environment';

    return reply.send({
      has_openai_key: hasDbKey || hasEnvKey,
      openai_key_source,
      openai_base_url: row?.openai_base_url ?? process.env.OPENAI_BASE_URL ?? null,
      has_openrouter_key: hasOpenRouterDbKey || hasOpenRouterEnvKey,
      openrouter_key_source,
      openrouter_model_id:
        row?.openrouter_model_id?.trim() ||
        process.env.OPENROUTER_MODEL_ID?.trim() ||
        OPENROUTER_BUDGET_MODELS[0],
      openrouter_budget_models: [...OPENROUTER_BUDGET_MODELS],
    });
  });

  // PATCH /api/v1/settings/platform — set or clear key / base URL (admin)
  fastify.patch('/platform', { preHandler: adminGuard }, async (req, reply) => {
    const body = req.body as {
      openai_api_key?: string;
      openai_base_url?: string;
      openrouter_api_key?: string;
      openrouter_model_id?: string;
    };
    const patch: {
      openai_api_key?: string | null;
      openai_base_url?: string | null;
      openrouter_api_key?: string | null;
      openrouter_model_id?: string | null;
    } = {};
    if (body.openai_api_key !== undefined) patch.openai_api_key = body.openai_api_key;
    if (body.openai_base_url !== undefined) patch.openai_base_url = body.openai_base_url;
    if (body.openrouter_api_key !== undefined) patch.openrouter_api_key = body.openrouter_api_key;
    if (body.openrouter_model_id !== undefined) patch.openrouter_model_id = body.openrouter_model_id;
    if (Object.keys(patch).length === 0) {
      return reply.status(400).send({
        error: 'openai_api_key, openai_base_url, openrouter_api_key, and/or openrouter_model_id required',
      });
    }
    await updatePlatformSettings(patch);
    invalidateOpenAiCredentialsCache();
    invalidateOpenRouterCredentialsCache();
    await auditService.log(req.user!.sub, 'user', 'platform.settings_updated', 'platform', req.user!.sub, {
      fields: Object.keys(patch),
    });
    return reply.send({ ok: true });
  });

  // GET /api/v1/settings/openai/models — uses resolved key (DB then env)
  fastify.get('/openai/models', { preHandler: adminGuard }, async (_req, reply) => {
    try {
      const models = await listOpenAiModels();
      return reply.send({ models });
    } catch (err: unknown) {
      const msg = err instanceof Error ? err.message : String(err);
      return reply.status(400).send({ error: msg });
    }
  });

  // GET /api/v1/settings/openrouter/models — curated budget models (+ live list when key is set)
  fastify.get('/openrouter/models', { preHandler: adminGuard }, async (_req, reply) => {
    try {
      const c = await resolveOpenRouterCredentials();
      const models = await listOpenRouterModels(c?.key);
      return reply.send({ models });
    } catch (err: unknown) {
      const msg = err instanceof Error ? err.message : String(err);
      return reply.status(400).send({ error: msg });
    }
  });
}
