import { writeFileSync } from "node:fs";
import { resolve } from "node:path";
import { extendZodWithOpenApi, OpenApiGeneratorV31, OpenAPIRegistry } from "@asteasolutions/zod-to-openapi";
import { z } from "zod";
import {
  Channel,
  ChannelIdParam,
  ChannelsListResponse,
  CreateChannelRequest,
  CreateWorkspaceRequest,
  HealthResponse,
  Message,
  ScrollbackQuery,
  ScrollbackResponse,
  Workspace,
} from "./index";

/**
 * Generates OpenAPI 3.1 from the Zod contracts that are the single source of
 * truth (§3, ADR-002). Run via `pnpm --filter @slackwsh/contracts run openapi:generate`.
 */
extendZodWithOpenApi(z);

const registry = new OpenAPIRegistry();

registry.register("Workspace", Workspace);
registry.register("Channel", Channel);
registry.register("Message", Message);

registry.registerPath({
  method: "get",
  path: "/health",
  summary: "Liveness check",
  responses: {
    200: {
      description: "Service is healthy",
      content: { "application/json": { schema: HealthResponse } },
    },
  },
});

registry.registerPath({
  method: "post",
  path: "/workspaces",
  summary: "Create a workspace",
  request: {
    body: { content: { "application/json": { schema: CreateWorkspaceRequest } } },
  },
  responses: {
    201: {
      description: "Workspace created",
      content: { "application/json": { schema: Workspace } },
    },
  },
});

registry.registerPath({
  method: "post",
  path: "/workspaces/{workspaceId}/channels",
  summary: "Create a channel",
  request: {
    body: { content: { "application/json": { schema: CreateChannelRequest } } },
  },
  responses: {
    201: {
      description: "Channel created",
      content: { "application/json": { schema: Channel } },
    },
  },
});

registry.registerPath({
  method: "get",
  path: "/workspaces/{workspaceId}/channels",
  summary: "List channels visible to the caller",
  responses: {
    200: {
      description: "Channel list",
      content: { "application/json": { schema: ChannelsListResponse } },
    },
  },
});

registry.registerPath({
  method: "get",
  path: "/channels/{channelId}/messages",
  summary: "Scrollback page (§5.3 catch-up mechanism)",
  request: {
    params: ChannelIdParam,
    query: ScrollbackQuery,
  },
  responses: {
    200: {
      description: "Message page ordered by seq",
      content: { "application/json": { schema: ScrollbackResponse } },
    },
  },
});

const generator = new OpenApiGeneratorV31(registry.definitions);
const document = generator.generateDocument({
  openapi: "3.1.0",
  info: {
    title: "slackwsh API",
    version: "0.1.0",
    description: "Generated from libs/contracts — do not hand-edit.",
  },
  servers: [{ url: "/api" }],
});

const outPath = resolve(__dirname, "../openapi.json");
writeFileSync(outPath, JSON.stringify(document, null, 2));
console.log(`Wrote ${outPath}`);
