import { schema } from "@json-render/svelte/schema";
import { z } from "zod";

/**
 * json-render + AI SDK Example Catalog (Svelte)
 *
 * Components for rendering data dashboards generated by the ToolLoopAgent.
 * Data flows in through tools (weather, GitHub, crypto, HN), not user actions.
 */
export const explorerCatalog = schema.createCatalog({
  components: {
    // Layout
    Stack: {
      props: z.object({
        direction: z.enum(["horizontal", "vertical"]).nullable(),
        gap: z.enum(["sm", "md", "lg"]).nullable(),
        wrap: z.boolean().nullable(),
      }),
      slots: ["default"],
      description: "Flex layout container",
      example: { direction: "vertical", gap: "md", wrap: null },
    },

    Card: {
      props: z.object({
        title: z.string().nullable(),
        description: z.string().nullable(),
      }),
      slots: ["default"],
      description: "Card container with optional title and description",
      example: { title: "Weather", description: "Current conditions" },
    },

    Grid: {
      props: z.object({
        columns: z.enum(["1", "2", "3", "4"]).nullable(),
        gap: z.enum(["sm", "md", "lg"]).nullable(),
      }),
      slots: ["default"],
      description: "Responsive grid layout container",
      example: { columns: "3", gap: "md" },
    },

    // Typography
    Heading: {
      props: z.object({
        text: z.string(),
        level: z.enum(["h1", "h2", "h3", "h4"]).nullable(),
      }),
      description: "Section heading",
      example: { text: "Data Explorer", level: "h1" },
    },

    Text: {
      props: z.object({
        content: z.string(),
        muted: z.boolean().nullable(),
      }),
      description: "Text content",
      example: { content: "Here is your data overview." },
    },

    // Data display
    Badge: {
      props: z.object({
        text: z.string(),
        variant: z
          .enum(["default", "secondary", "destructive", "outline"])
          .nullable(),
      }),
      description: "Status badge",
      example: { text: "Live", variant: "default" },
    },

    Alert: {
      props: z.object({
        variant: z.enum(["default", "destructive"]).nullable(),
        title: z.string(),
        description: z.string().nullable(),
      }),
      description: "Alert or info message",
    },

    Separator: {
      props: z.object({}),
      description: "Visual divider",
    },

    Metric: {
      props: z.object({
        label: z.string(),
        value: z.string(),
        detail: z.string().nullable(),
        trend: z.enum(["up", "down", "neutral"]).nullable(),
      }),
      description:
        "Single metric display with label, value, and optional trend indicator",
      example: {
        label: "Temperature",
        value: "72F",
        detail: "Feels like 68F",
        trend: "up",
      },
    },

    Table: {
      props: z.object({
        data: z.array(z.record(z.string(), z.unknown())),
        columns: z.array(
          z.object({
            key: z.string(),
            label: z.string(),
          }),
        ),
        emptyMessage: z.string().nullable(),
      }),
      description:
        'Data table. Use { "$state": "/path" } to bind read-only data from state.',
      example: {
        data: { $state: "/stories" },
        columns: [
          { key: "title", label: "Title" },
          { key: "score", label: "Score" },
        ],
      },
    },

    Link: {
      props: z.object({
        text: z.string(),
        href: z.string(),
      }),
      description: "External link that opens in a new tab",
      example: { text: "View on GitHub", href: "https://github.com" },
    },

    // Charts
    BarChart: {
      props: z.object({
        title: z.string().nullable(),
        data: z.array(z.record(z.string(), z.unknown())),
        xKey: z.string(),
        yKey: z.string(),
        aggregate: z.enum(["sum", "count", "avg"]).nullable(),
        color: z.string().nullable(),
        height: z.number().nullable(),
      }),
      description:
        'Bar chart visualization. Use { "$state": "/path" } to bind read-only data. xKey is the category field, yKey is the numeric value field.',
    },

    LineChart: {
      props: z.object({
        title: z.string().nullable(),
        data: z.array(z.record(z.string(), z.unknown())),
        xKey: z.string(),
        yKey: z.string(),
        aggregate: z.enum(["sum", "count", "avg"]).nullable(),
        color: z.string().nullable(),
        height: z.number().nullable(),
      }),
      description:
        'Line chart visualization. Use { "$state": "/path" } to bind read-only data. xKey is the x-axis field, yKey is the numeric value field.',
    },

    // Interactive
    Tabs: {
      props: z.object({
        defaultValue: z.string().nullable(),
        tabs: z.array(
          z.object({
            value: z.string(),
            label: z.string(),
          }),
        ),
      }),
      slots: ["default"],
      description: "Tabbed content container",
    },

    TabContent: {
      props: z.object({
        value: z.string(),
      }),
      slots: ["default"],
      description: "Content for a specific tab",
    },

    Progress: {
      props: z.object({
        value: z.number(),
        max: z.number().nullable(),
      }),
      description: "Progress bar",
    },

    Skeleton: {
      props: z.object({
        width: z.string().nullable(),
        height: z.string().nullable(),
      }),
      description: "Loading placeholder",
    },

    // Educational / Rich content
    Callout: {
      props: z.object({
        type: z.enum(["info", "tip", "warning", "important"]).nullable(),
        title: z.string().nullable(),
        content: z.string(),
      }),
      description:
        "Highlighted callout box for tips, warnings, notes, or key information",
      example: {
        type: "tip",
        title: "Did you know?",
        content: "The sun is about 93 million miles from Earth.",
      },
    },

    Accordion: {
      props: z.object({
        items: z.array(
          z.object({
            title: z.string(),
            content: z.string(),
          }),
        ),
        type: z.enum(["single", "multiple"]).nullable(),
      }),
      description:
        "Collapsible accordion sections for organizing detailed content",
      example: {
        items: [{ title: "Overview", content: "A brief introduction." }],
        type: "multiple",
      },
    },

    Timeline: {
      props: z.object({
        items: z.array(
          z.object({
            title: z.string(),
            description: z.string().nullable(),
            date: z.string().nullable(),
            status: z.enum(["completed", "current", "upcoming"]).nullable(),
          }),
        ),
      }),
      description:
        "Vertical timeline showing ordered events, steps, or historical milestones",
      example: {
        items: [
          {
            title: "Discovery",
            description: "Initial breakthrough",
            date: "1905",
            status: "completed",
          },
        ],
      },
    },

    PieChart: {
      props: z.object({
        title: z.string().nullable(),
        data: z.array(z.record(z.string(), z.unknown())),
        nameKey: z.string(),
        valueKey: z.string(),
        height: z.number().nullable(),
      }),
      description:
        'Pie/donut chart for proportional data. Use { "$state": "/path" } to bind read-only data. nameKey is the label field, valueKey is the numeric value field.',
    },

    // Interactive / Input
    RadioGroup: {
      props: z.object({
        label: z.string().nullable(),
        value: z.string().nullable(),
        options: z.array(
          z.object({
            value: z.string(),
            label: z.string(),
          }),
        ),
      }),
      description:
        'Radio button group for single selection. Use { "$bindState": "/path" } for two-way binding.',
      example: {
        label: "Choose one",
        value: { $bindState: "/answer" },
        options: [
          { value: "a", label: "Option A" },
          { value: "b", label: "Option B" },
        ],
      },
    },

    SelectInput: {
      props: z.object({
        label: z.string().nullable(),
        value: z.string().nullable(),
        placeholder: z.string().nullable(),
        options: z.array(
          z.object({
            value: z.string(),
            label: z.string(),
          }),
        ),
      }),
      description:
        'Dropdown select input. Use { "$bindState": "/path" } for two-way binding.',
      example: {
        label: "Country",
        value: { $bindState: "/selectedCountry" },
        placeholder: "Select a country",
        options: [
          { value: "us", label: "United States" },
          { value: "uk", label: "United Kingdom" },
        ],
      },
    },

    TextInput: {
      props: z.object({
        label: z.string().nullable(),
        value: z.string().nullable(),
        placeholder: z.string().nullable(),
        type: z.enum(["text", "email", "number", "password", "url"]).nullable(),
      }),
      description:
        'Text input field. Use { "$bindState": "/path" } for two-way binding.',
      example: {
        label: "Your name",
        value: { $bindState: "/userName" },
        placeholder: "Enter your name",
        type: "text",
      },
    },

    Button: {
      props: z.object({
        label: z.string(),
        variant: z
          .enum(["default", "secondary", "destructive", "outline", "ghost"])
          .nullable(),
        size: z.enum(["default", "sm", "lg"]).nullable(),
        disabled: z.boolean().nullable(),
      }),
      description:
        "Clickable button. Use with on.press to trigger actions like setState.",
      example: {
        label: "Submit",
        variant: "default",
        size: "default",
        disabled: null,
      },
    },
  },

  actions: {},
});
