import { HttpError } from "@batch-cooking/error-tools";
import { wrapAsyncHandler } from "@batch-cooking/express-tools";
import {
  ErrorCode,
  listCorrectionsQuerySchema,
  listSuggestionsQuerySchema,
  retrainRequestSchema,
  trainingDataSnippetQuerySchema,
  updateTrainingSuggestionSchema,
} from "@batch-cooking/shared";
import { Router } from "express";
import { requireAdmin } from "../../middlewares/require-admin.js";
import {
  getTrainingDataSnippet,
  listCorrections,
  listSuggestions,
  runRetrain,
  updateSuggestion,
} from "./admin-tech-steps.service.js";

/** Router mounted at `/admin/tech-steps` (via `admin.routes.ts`) — every route behind {@link requireAdmin}. Correction/suggestion triage + the retrain trigger. */
export const adminTechStepsRouter = Router();

adminTechStepsRouter.get(
  "/suggestions",
  requireAdmin,
  wrapAsyncHandler(async (req, res) => {
    res.status(200).json(await listSuggestions(listSuggestionsQuerySchema.parse(req.query)));
  }),
);

adminTechStepsRouter.get(
  "/corrections",
  requireAdmin,
  wrapAsyncHandler(async (req, res) => {
    res.status(200).json(await listCorrections(listCorrectionsQuerySchema.parse(req.query)));
  }),
);

adminTechStepsRouter.get(
  "/training-data-snippet",
  requireAdmin,
  wrapAsyncHandler(async (req, res) => {
    res
      .status(200)
      .json(await getTrainingDataSnippet(trainingDataSnippetQuerySchema.parse(req.query)));
  }),
);

adminTechStepsRouter.patch(
  "/suggestions/:id",
  requireAdmin,
  wrapAsyncHandler(async (req, res) => {
    const id = Number(req.params.id);
    if (!Number.isInteger(id) || id <= 0) {
      throw new HttpError(
        400,
        ErrorCode.VALIDATION_ERROR,
        `Not a valid suggestion id: ${req.params.id}`,
      );
    }
    const input = updateTrainingSuggestionSchema.parse(req.body);
    res.status(200).json(await updateSuggestion(id, input));
  }),
);

/**
 * Runs the F1 regression gate then (if it passes) the full step backfill,
 * and marks the given suggestion ids — see {@link runRetrain}. Long-running
 * and process-locked: `409 RETRAIN_ALREADY_RUNNING` if one is already
 * underway.
 */
adminTechStepsRouter.post(
  "/retrain",
  requireAdmin,
  wrapAsyncHandler(async (req, res) => {
    const input = retrainRequestSchema.parse(req.body);
    res.status(200).json(await runRetrain(input));
  }),
);
