import "dotenv/config";
import cors from "cors";
import express from "express";
import { PORT, PRESETS_DIR, TRACES_DIR, EVAL_CASES_DIR, REPORTS_DIR, TIMEZONE, ASSISTANT_SESSIONS_DIR } from "./config";
import { buildAccountingAgentRouter } from "./routes/accountingAgent";
import { buildAssistantRouter } from "./routes/assistant";
import { buildEvalRouter } from "./routes/eval";
import { buildHistoryRouter } from "./routes/history";
import { buildNormalizeRouter } from "./routes/normalize";
import { buildPresetsRouter } from "./routes/presets";
import { buildTestConnectionRouter } from "./routes/testConnection";
import { InMemoryRuntimeAdapter } from "./runtime/inMemoryRuntimeAdapter";
import { AssistantService } from "./services/assistantService";
import { AssistantSessionStore } from "./services/assistantSessionStore";
import { EvalService } from "./services/evalService";
import { NormalizerService } from "./services/normalizerService";
import { OpenAIResponsesClient } from "./services/openaiResponsesClient";
import type { AppServices } from "./serverContext";
import { ensureDir } from "./utils/files";
import { errorMiddleware, ok } from "./utils/http";
import { logJson } from "./utils/log";

export function createApp(): express.Express {
  ensureDir(TRACES_DIR);
  ensureDir(PRESETS_DIR);
  ensureDir(EVAL_CASES_DIR);
  ensureDir(REPORTS_DIR);
  ensureDir(ASSISTANT_SESSIONS_DIR);

  const app = express();
  app.use(cors());
  app.use(express.json({ type: ["application/json", "application/*+json"], limit: "2mb" }));

  const openaiClient = new OpenAIResponsesClient();
  const normalizerService = new NormalizerService(openaiClient);
  const evalService = new EvalService(normalizerService);
  const assistantSessionStore = new AssistantSessionStore();
  const assistantService = new AssistantService(normalizerService, assistantSessionStore);
  const runtimeAdapter = new InMemoryRuntimeAdapter();

  const services: AppServices = {
    normalizerService,
    evalService,
    assistantService,
    runtimeAdapter
  };

  app.get("/api/health", (_req, res) => {
    ok(res, {
      ok: true,
      service: "llm-normalizer-backend",
      status: "RUNNING",
      timezone: TIMEZONE,
      now: new Date().toISOString()
    });
  });

  app.use(buildTestConnectionRouter(openaiClient));
  app.use(buildNormalizeRouter(services));
  app.use(buildEvalRouter(services));
  app.use(buildAssistantRouter(services));
  app.use(buildHistoryRouter());
  app.use(buildPresetsRouter());
  app.use(buildAccountingAgentRouter(services));
  app.use(errorMiddleware);

  return app;
}

if (require.main === module) {
  const app = createApp();
  app.listen(PORT, () => {
    logJson({
      timestamp: new Date().toISOString(),
      level: "info",
      service: "llm_normalizer_backend",
      message: `Backend started on http://localhost:${PORT}`
    });
  });
}
