---
import data from "blume:data";

import { highlightCode } from "../../markdown/index.ts";
import { exampleValue, type SchemaLike, toJson } from "./helpers.ts";
import PanelTabs from "./PanelTabs.astro";
import type { RequestSample, SampleLanguage } from "./snippets.ts";

interface MediaTypeLike {
  schema?: SchemaLike;
  example?: unknown;
}

interface ResponseLike {
  description?: string;
  content?: Record<string, MediaTypeLike>;
}

interface Props {
  sample: RequestSample;
  languages: SampleLanguage[];
  responses: Record<string, ResponseLike>;
  schemas: Record<string, SchemaLike>;
}

const { sample, languages, responses, schemas } = Astro.props;

const requestPanels = await Promise.all(
  languages.map(async (language) => ({
    html: await highlightCode(language.build(sample), language.lang, {
      icons: false,
      themes: data.config.codeThemes,
    }),
    key: language.id,
    label: language.label,
    lang: language.id,
  }))
);

const responsePanels = await Promise.all(
  Object.entries(responses).map(async ([status, response]) => {
    const media =
      Object.entries(response.content ?? {}).find(([type]) =>
        type.includes("json")
      )?.[1] ?? Object.values(response.content ?? {})[0];
    const example = media
      ? (media.example ?? exampleValue(media.schema, schemas))
      : undefined;
    const html =
      example === undefined || example === null
        ? null
        : await highlightCode(toJson(example), "json", {
            icons: false,
            themes: data.config.codeThemes,
          });
    return {
      html,
      key: status,
      label: status,
      text: response.description || "No example response.",
    };
  })
);
---

<div class="not-prose flex flex-col gap-6">
  <PanelTabs copy heading="Request" panels={requestPanels} />
  <PanelTabs heading="Response" mono panels={responsePanels} />
</div>
