/**
 * `GET /api/v1/weather` — for a place, not for the box.
 *
 * `?city=sf`, or `?lat=&lng=` which resolves to whichever configured region
 * claims the point, or neither, which answers for the default region. The
 * validation and the refusal both live in `regions.ts`; the paragraph there on
 * why this is an allowlist rather than a lookup is the one worth reading before
 * touching this file.
 *
 * Two kinds of answer, and the split is deliberate:
 *
 * - **A bad request is a 400.** `?lat=banana`, or a coordinate in a city this
 *   deployment does not serve, is a client bug, and a 200 full of clear sky
 *   would hide it until somebody wondered why the fog never rolled in.
 * - **Everything else is a 200 with a body.** A source that is down,
 *   misconfigured or absent produces `synthetic: true` and a clear day. There is
 *   no failure mode in which the caller has to decide what to render, because
 *   the answer to "what is the sky doing" is never allowed to be a 503.
 */

import type { FastifyInstance } from "fastify";
import { publicCache } from "../cache.ts";
import { resolveRegion, type RegionQuery } from "../regions.ts";
import type { ErrorBody } from "../../../src/server/wire.ts";
import type { Services } from "../services.ts";

export function registerWeather(app: FastifyInstance, services: Services): void {
  app.get<{ Querystring: RegionQuery }>("/api/v1/weather", async (req, reply) => {
    const resolved = resolveRegion(services.config.regions, req.query);
    if (!resolved.ok) {
      const error: ErrorBody = { error: "bad_request", message: resolved.message };
      return reply.code(400).send(error);
    }

    const body = await services.weather.current(resolved.region);
    // Query strings are part of a shared cache's key, so two regions cannot
    // collide here and no extra `Vary` is owed.
    publicCache(req, reply, services.config.weather.ttlSeconds);
    return body;
  });
}
