import { HttpError } from "@batch-cooking/error-tools";
import { wrapAsyncHandler } from "@batch-cooking/express-tools";
import { browseSourceSchema, createRecipeSchema, ErrorCode } from "@batch-cooking/shared";
import { Router } from "express";
import { type AuthLocals, requireAuth } from "../../middlewares/require-auth.js";
import { browseSource, importSourceItem, previewSourceItem } from "./sources.service.js";

/**
 * Router mounted at `/sources` in app.ts — browsing/previewing a
 * household's *enabled* external recipe sources (see `sources.service.ts`).
 * Every route requires a session, same posture as `/recipes`/`/house`: this
 * is app content scoped to the viewer's household, not signup-time
 * reference data (contrast `/reference/sources`, which just lists what
 * exists, public, no auth needed).
 */
export const sourcesRouter = Router();

/** Route params are typed `string | undefined` by Express even for a segment that always matches when the route does — this just satisfies TS, the branch is unreachable in practice. */
function requireParam(value: string | undefined): string {
  if (value === undefined) {
    throw new HttpError(400, ErrorCode.VALIDATION_ERROR, "Missing route parameter");
  }
  return value;
}

sourcesRouter.get(
  "/:sourceKey/browse",
  requireAuth,
  wrapAsyncHandler<unknown, AuthLocals>(async (req, res) => {
    const input = browseSourceSchema.parse(req.query);
    const { houseId } = res.locals.userProfile;
    res.status(200).json(await browseSource(requireParam(req.params.sourceKey), houseId, input));
  }),
);

sourcesRouter.get(
  "/:sourceKey/preview/:externalId",
  requireAuth,
  wrapAsyncHandler<unknown, AuthLocals>(async (req, res) => {
    const { houseId } = res.locals.userProfile;
    res
      .status(200)
      .json(
        await previewSourceItem(
          requireParam(req.params.sourceKey),
          requireParam(req.params.externalId),
          houseId,
        ),
      );
  }),
);

sourcesRouter.post(
  "/:sourceKey/import/:externalId",
  requireAuth,
  wrapAsyncHandler<unknown, AuthLocals>(async (req, res) => {
    const input = createRecipeSchema.parse(req.body);
    const { id: authorId, houseId } = res.locals.userProfile;
    res
      .status(201)
      .json(
        await importSourceItem(
          requireParam(req.params.sourceKey),
          requireParam(req.params.externalId),
          input,
          authorId,
          houseId,
        ),
      );
  }),
);
