import { config as loadDotenv } from "dotenv";
import { existsSync } from "node:fs";
import path from "node:path";
for (const candidate of [".env", "../.env", "../../.env"]) {
  const p = path.resolve(process.cwd(), candidate);
  if (existsSync(p)) {
    loadDotenv({ path: p });
    break;
  }
}

import { schema } from "@app/database";
import { createContext } from "../context.js";
import { EVAL_CASES } from "./cases.js";

/**
 * Kör AAMOS-utvärderingssviten (spec §40).
 *
 *   pnpm --filter @app/worker eval          # mot AAMOS_MODE i .env (mock i dev)
 *   AAMOS_MODE=http AAMOS_API_URL=… pnpm --filter @app/worker eval   # mot riktig AAMOS
 *
 * Resultatet skrivs till ai_eval_runs (syns i adminpanelen) och processen
 * avslutas med exitkod 1 om någon kontroll faller – körbar som CI-grind
 * inför varje modell-/promptbyte i AAMOS.
 */
async function main() {
  const ctx = createContext();
  const mode = process.env.AAMOS_MODE ?? "mock";
  console.log(`[eval] AAMOS-utvärdering – läge: ${mode}, ${EVAL_CASES.length} fall\n`);

  let totalChecks = 0;
  let failedChecks = 0;

  for (const evalCase of EVAL_CASES) {
    const started = Date.now();
    let checks: { name: string; passed: boolean }[] = [];
    let error: string | null = null;
    try {
      const result = await ctx.aamos.runTask(evalCase.taskType, evalCase.input as never);
      if (result.status !== "ok" || !result.output) {
        error = `status=${result.status}`;
        checks = [{ name: "AAMOS svarade ok", passed: false }];
      } else {
        checks = [
          { name: "AAMOS svarade ok", passed: true },
          ...evalCase.verify(result.output as never),
        ];
      }
    } catch (err) {
      error = (err as Error).message;
      checks = [{ name: "AAMOS svarade ok", passed: false }];
    }
    const ms = Date.now() - started;
    const passed = checks.every((c) => c.passed);
    totalChecks += checks.length;
    failedChecks += checks.filter((c) => !c.passed).length;

    console.log(`${passed ? "✓" : "✗"} ${evalCase.id} (${evalCase.taskType}, ${ms} ms)`);
    for (const c of checks) if (!c.passed) console.log(`    ✗ ${c.name}`);
    if (error) console.log(`    fel: ${error}`);

    await ctx.db.insert(schema.aiEvalRuns).values({
      taskType: evalCase.taskType,
      modelVersion: `aamos-${mode}`,
      promptVersion: "eval-suite-v1",
      metrics: {
        caseId: evalCase.id,
        durationMs: ms,
        checks,
        ...(error ? { error } : {}),
      },
      passed,
      notes: evalCase.descriptionSv,
    });
  }

  const failedCases = failedChecks > 0;
  console.log(
    `\n[eval] ${EVAL_CASES.length} fall, ${totalChecks} kontroller, ${failedChecks} fallerade.`,
  );
  console.log(
    failedCases
      ? "[eval] UNDERKÄND – åtgärda innan modell-/promptbytet tas i produktion (spec §40)."
      : "[eval] GODKÄND – resultatet är loggat i ai_eval_runs.",
  );
  await ctx.close();
  process.exit(failedCases ? 1 : 0);
}

main().catch((err) => {
  console.error("[eval] KRASCH:", err);
  process.exit(1);
});
