import Link from "next/link";
import { Code } from "@/components/code";

export const metadata = {
  title: "Specs | json-render",
};

export default function SpecsPage() {
  return (
    <article>
      <h1 className="text-3xl font-bold mb-4">Specs</h1>
      <p className="text-muted-foreground mb-8">
        A spec is a JSON document that describes your UI.
      </p>

      <h2 className="text-xl font-semibold mt-12 mb-4">What is a Spec?</h2>
      <p className="text-sm text-muted-foreground mb-4">
        A spec (specification) is the actual JSON that describes a UI. It
        conforms to a{" "}
        <Link href="/docs/schemas" className="text-foreground hover:underline">
          schema
        </Link>{" "}
        and uses components from a{" "}
        <Link href="/docs/catalog" className="text-foreground hover:underline">
          catalog
        </Link>
        . Specs can be:
      </p>
      <ul className="list-disc list-inside text-sm text-muted-foreground space-y-1 mb-4">
        <li>Generated by AI in real-time</li>
        <li>Stored in a database</li>
        <li>Streamed progressively from a server</li>
        <li>Hand-authored as JSON files</li>
      </ul>
      <p className="text-sm text-muted-foreground mb-4">
        json-render is schema-agnostic — your specs can follow any JSON
        structure you choose.
      </p>

      <h2 className="text-xl font-semibold mt-12 mb-4">Example Specs</h2>

      <h3 className="text-lg font-medium mt-8 mb-3">Simple Spec</h3>
      <p className="text-sm text-muted-foreground mb-4">
        A basic spec using the{" "}
        <code className="text-foreground">@json-render/react</code> schema. Note
        the flat structure with a <code className="text-foreground">root</code>{" "}
        key and <code className="text-foreground">elements</code> map:
      </p>
      <Code lang="json">{`{
  "root": "card-1",
  "elements": {
    "card-1": {
      "key": "card-1",
      "type": "Card",
      "props": { "title": "Welcome" },
      "children": ["text-1"],
      "parentKey": ""
    },
    "text-1": {
      "key": "text-1",
      "type": "Text",
      "props": { "content": "Hello, $data.user.name!" },
      "children": [],
      "parentKey": "card-1"
    }
  }
}`}</Code>

      <h3 className="text-lg font-medium mt-8 mb-3">Complex Spec</h3>
      <p className="text-sm text-muted-foreground mb-4">
        A more complex spec with multiple nested elements:
      </p>
      <Code lang="json">{`{
  "root": "card-1",
  "elements": {
    "card-1": {
      "key": "card-1",
      "type": "Card",
      "props": { "title": "User Profile", "padding": "md" },
      "children": ["row-1", "button-1"],
      "parentKey": ""
    },
    "row-1": {
      "key": "row-1",
      "type": "Row",
      "props": { "gap": "md" },
      "children": ["avatar-1", "stack-1"],
      "parentKey": "card-1"
    },
    "avatar-1": {
      "key": "avatar-1",
      "type": "Avatar",
      "props": { "src": "$data.user.avatar", "alt": "$data.user.name" },
      "children": [],
      "parentKey": "row-1"
    },
    "stack-1": {
      "key": "stack-1",
      "type": "Stack",
      "props": { "gap": "sm" },
      "children": ["name-text", "email-text"],
      "parentKey": "row-1"
    },
    "name-text": {
      "key": "name-text",
      "type": "Text",
      "props": { "content": "$data.user.name", "variant": "heading" },
      "children": [],
      "parentKey": "stack-1"
    },
    "email-text": {
      "key": "email-text",
      "type": "Text",
      "props": { "content": "$data.user.email", "variant": "caption" },
      "children": [],
      "parentKey": "stack-1"
    },
    "button-1": {
      "key": "button-1",
      "type": "Button",
      "props": { "label": "Edit Profile" },
      "children": [],
      "parentKey": "card-1"
    }
  }
}`}</Code>

      <h3 className="text-lg font-medium mt-8 mb-3">Block-Level Spec</h3>
      <p className="text-sm text-muted-foreground mb-4">
        A high-level spec using semantic blocks for page layouts:
      </p>
      <Code lang="json">{`{
  "root": "page",
  "elements": {
    "page": {
      "key": "page",
      "type": "Page",
      "props": {},
      "children": ["header", "hero", "features", "footer"],
      "parentKey": ""
    },
    "header": {
      "key": "header",
      "type": "Header",
      "props": { "logo": "/logo.svg", "navItems": ["Products", "Pricing", "Docs"] },
      "children": [],
      "parentKey": "page"
    },
    "hero": {
      "key": "hero",
      "type": "Hero",
      "props": {
        "title": "Build UIs with JSON",
        "subtitle": "Let AI generate your interfaces",
        "ctaLabel": "Get Started",
        "ctaHref": "/docs"
      },
      "children": [],
      "parentKey": "page"
    },
    "features": {
      "key": "features",
      "type": "Features",
      "props": { "columns": 3 },
      "children": ["feature-1", "feature-2", "feature-3"],
      "parentKey": "page"
    },
    "feature-1": {
      "key": "feature-1",
      "type": "Feature",
      "props": { "icon": "zap", "title": "Fast", "description": "Render UIs in milliseconds" },
      "children": [],
      "parentKey": "features"
    },
    "feature-2": {
      "key": "feature-2",
      "type": "Feature",
      "props": { "icon": "shield", "title": "Secure", "description": "Validate all specs against your catalog" },
      "children": [],
      "parentKey": "features"
    },
    "feature-3": {
      "key": "feature-3",
      "type": "Feature",
      "props": { "icon": "sparkles", "title": "AI-Ready", "description": "Generate prompts from your catalog" },
      "children": [],
      "parentKey": "features"
    },
    "footer": {
      "key": "footer",
      "type": "Footer",
      "props": { "copyright": "2025 Acme Inc", "links": ["Privacy", "Terms", "Contact"] },
      "children": [],
      "parentKey": "page"
    }
  }
}`}</Code>

      <h2 className="text-xl font-semibold mt-12 mb-4">Spec Anatomy</h2>

      <h3 className="text-lg font-medium mt-8 mb-3">Root and Elements</h3>
      <p className="text-sm text-muted-foreground mb-4">
        Every spec has a <code className="text-foreground">root</code> key
        pointing to the entry element, and an{" "}
        <code className="text-foreground">elements</code> map containing all
        elements:
      </p>
      <Code lang="json">{`{
  "root": "card-1",
  "elements": {
    "card-1": {
      "key": "card-1",
      "type": "Card",
      "props": { "title": "My Card" },
      "children": ["text-1"],
      "parentKey": ""
    },
    "text-1": { ... }
  }
}`}</Code>

      <h3 className="text-lg font-medium mt-8 mb-3">Element Structure</h3>
      <p className="text-sm text-muted-foreground mb-4">
        Each element in the map has a consistent shape:
      </p>
      <Code lang="json">{`{
  "key": "unique-id",
  "type": "ComponentName",
  "props": { "label": "Hello" },
  "children": ["child-1", "child-2"],
  "parentKey": "parent-id"
}`}</Code>
      <ul className="list-disc list-inside text-sm text-muted-foreground space-y-1 mt-3 mb-4">
        <li>
          <code className="text-foreground">key</code> — Unique identifier for
          this element
        </li>
        <li>
          <code className="text-foreground">type</code> — Component type from
          your catalog
        </li>
        <li>
          <code className="text-foreground">props</code> — Component properties
        </li>
        <li>
          <code className="text-foreground">children</code> — Array of child
          element keys
        </li>
        <li>
          <code className="text-foreground">parentKey</code> — Key of parent
          element (empty string for root)
        </li>
      </ul>

      <h3 className="text-lg font-medium mt-8 mb-3">Dynamic Data</h3>
      <p className="text-sm text-muted-foreground mb-4">
        Props can reference data using{" "}
        <code className="text-foreground">$data</code> paths:
      </p>
      <Code lang="json">{`{
  "key": "metric-1",
  "type": "Metric",
  "props": {
    "label": "Total Revenue",
    "value": "$data.metrics.revenue",
    "change": "$data.metrics.revenueChange"
  },
  "children": [],
  "parentKey": "dashboard"
}`}</Code>

      <h3 className="text-lg font-medium mt-8 mb-3">Conditional Visibility</h3>
      <p className="text-sm text-muted-foreground mb-4">
        Control when elements appear using the{" "}
        <code className="text-foreground">visible</code> property:
      </p>
      <Code lang="json">{`{
  "key": "alert-1",
  "type": "Alert",
  "props": {
    "message": "You have unsaved changes"
  },
  "children": [],
  "parentKey": "form",
  "visible": {
    "path": "$data.form.isDirty",
    "operator": "eq",
    "value": true
  }
}`}</Code>

      <h2 className="text-xl font-semibold mt-12 mb-4">Working with Specs</h2>

      <h3 className="text-lg font-medium mt-8 mb-3">Rendering a Spec</h3>
      <Code lang="tsx">{`import { Renderer } from '@json-render/react';

function MyApp({ spec, data }) {
  return (
    <Renderer
      spec={spec}
      data={data}
      registry={registry}
    />
  );
}`}</Code>

      <h3 className="text-lg font-medium mt-8 mb-3">Validating a Spec</h3>
      <Code lang="typescript">{`import { validate } from '@json-render/core';

const result = validate(spec, catalog);

if (!result.valid) {
  console.error('Invalid spec:', result.errors);
}`}</Code>

      <h3 className="text-lg font-medium mt-8 mb-3">Streaming Specs</h3>
      <p className="text-sm text-muted-foreground mb-4">
        Specs can be streamed incrementally for progressive rendering:
      </p>
      <Code lang="tsx">{`import { useUIStream } from '@json-render/react';

function GenerativeUI() {
  const { spec, isStreaming } = useUIStream({
    api: '/api/generate',
  });

  return (
    <Renderer
      spec={spec}
      registry={registry}
      loading={isStreaming}
    />
  );
}`}</Code>

      <h2 className="text-xl font-semibold mt-12 mb-4">Spec Sources</h2>
      <p className="text-sm text-muted-foreground mb-4">
        Specs can come from various sources:
      </p>
      <ul className="list-disc list-inside text-sm text-muted-foreground space-y-1 mb-4">
        <li>
          <strong className="text-foreground">AI Generation</strong> — LLMs
          generate specs based on prompts and catalog
        </li>
        <li>
          <strong className="text-foreground">Database</strong> — Store specs as
          JSON and load dynamically
        </li>
        <li>
          <strong className="text-foreground">API Response</strong> — Server
          returns specs based on user/context
        </li>
        <li>
          <strong className="text-foreground">Static Files</strong> — Pre-built
          specs for known UI patterns
        </li>
      </ul>

      <h2 className="text-xl font-semibold mt-12 mb-4">Next</h2>
      <p className="text-sm text-muted-foreground">
        Learn about{" "}
        <Link href="/docs/catalog" className="text-foreground hover:underline">
          catalogs
        </Link>{" "}
        — the vocabulary of components available in your specs.
      </p>
    </article>
  );
}
