import { createCatalog } from '@json-render/core'
import { z } from 'zod'

/**
 * GHL Component Catalog
 *
 * Defines the full vocabulary of UI components that an AI can use
 * to generate GoHighLevel MCP app interfaces.
 */
export const ghlCatalog = createCatalog({
  name: 'ghl-mcp',

  components: {
    // ── Layout ──────────────────────────────────────────────
    PageHeader: {
      description: 'Top-level page header with title, subtitle, status badge, and summary stats',
      props: z.object({
        title: z.string(),
        subtitle: z.string().optional(),
        status: z.string().optional(),
        statusVariant: z.enum(['active', 'complete', 'paused', 'draft', 'error', 'sent', 'paid', 'pending']).optional(),
        gradient: z.boolean().optional(),
        stats: z.array(z.object({
          label: z.string(),
          value: z.string(),
        })).optional(),
      }),
      hasChildren: true,
    },

    Card: {
      description: 'Container card with optional header and padding',
      props: z.object({
        title: z.string().optional(),
        subtitle: z.string().optional(),
        padding: z.enum(['none', 'sm', 'md', 'lg']).optional(),
        noBorder: z.boolean().optional(),
      }),
      hasChildren: true,
    },

    StatsGrid: {
      description: 'Grid of metric cards showing key numbers',
      props: z.object({
        columns: z.number().optional(),
      }),
      hasChildren: true,
    },

    SplitLayout: {
      description: 'Two-column layout for side-by-side content',
      props: z.object({
        ratio: z.enum(['50/50', '33/67', '67/33']).optional(),
        gap: z.enum(['sm', 'md', 'lg']).optional(),
      }),
      hasChildren: true,
    },

    Section: {
      description: 'Titled content section',
      props: z.object({
        title: z.string().optional(),
        description: z.string().optional(),
      }),
      hasChildren: true,
    },

    // ── Data Display ────────────────────────────────────────
    DataTable: {
      description: 'Sortable data table with column definitions and row actions. Used for contact grids, lists, etc.',
      props: z.object({
        columns: z.array(z.object({
          key: z.string(),
          label: z.string(),
          sortable: z.boolean().optional(),
          align: z.enum(['left', 'center', 'right']).optional(),
          format: z.enum(['text', 'email', 'phone', 'date', 'currency', 'tags', 'avatar', 'status']).optional(),
          width: z.string().optional(),
        })),
        rows: z.array(z.record(z.string(), z.unknown())),
        selectable: z.boolean().optional(),
        rowAction: z.string().optional(),
        emptyMessage: z.string().optional(),
        pageSize: z.number().optional(),
      }),
    },

    KanbanBoard: {
      description: 'Kanban-style board with columns and draggable cards. Used for pipeline views.',
      props: z.object({
        columns: z.array(z.object({
          id: z.string(),
          title: z.string(),
          count: z.number().optional(),
          totalValue: z.string().optional(),
          color: z.string().optional(),
          cards: z.array(z.object({
            id: z.string(),
            title: z.string(),
            subtitle: z.string().optional(),
            value: z.string().optional(),
            status: z.string().optional(),
            statusVariant: z.enum(['open', 'won', 'lost', 'abandoned']).optional(),
            date: z.string().optional(),
            avatarInitials: z.string().optional(),
          })),
        })),
      }),
    },

    MetricCard: {
      description: 'Single metric display with big number, label, and optional trend',
      props: z.object({
        label: z.string(),
        value: z.string(),
        format: z.enum(['number', 'currency', 'percent']).optional(),
        trend: z.enum(['up', 'down', 'flat']).optional(),
        trendValue: z.string().optional(),
        color: z.enum(['default', 'green', 'blue', 'purple', 'yellow', 'red']).optional(),
      }),
    },

    StatusBadge: {
      description: 'Colored badge showing entity status',
      props: z.object({
        label: z.string(),
        variant: z.enum(['active', 'complete', 'paused', 'draft', 'error', 'sent', 'paid', 'pending', 'open', 'won', 'lost']),
      }),
    },

    Timeline: {
      description: 'Chronological event list for activity feeds',
      props: z.object({
        events: z.array(z.object({
          id: z.string(),
          title: z.string(),
          description: z.string().optional(),
          timestamp: z.string(),
          icon: z.enum(['email', 'phone', 'note', 'meeting', 'task', 'system']).optional(),
          variant: z.enum(['default', 'success', 'warning', 'error']).optional(),
        })),
      }),
    },

    ProgressBar: {
      description: 'Percentage bar with label and value',
      props: z.object({
        label: z.string(),
        value: z.number(),
        max: z.number().optional(),
        color: z.enum(['green', 'blue', 'purple', 'yellow', 'red']).optional(),
        showPercent: z.boolean().optional(),
        benchmark: z.number().optional(),
        benchmarkLabel: z.string().optional(),
      }),
    },

    // ── Detail Views ────────────────────────────────────────
    DetailHeader: {
      description: 'Header for detail/preview pages with entity name, ID, status, and action buttons',
      props: z.object({
        title: z.string(),
        subtitle: z.string().optional(),
        entityId: z.string().optional(),
        status: z.string().optional(),
        statusVariant: z.enum(['active', 'complete', 'paused', 'draft', 'error', 'sent', 'paid', 'pending']).optional(),
      }),
      hasChildren: true,
    },

    KeyValueList: {
      description: 'List of label-value pairs. Used for totals, metadata, etc.',
      props: z.object({
        items: z.array(z.object({
          label: z.string(),
          value: z.string(),
          bold: z.boolean().optional(),
          variant: z.enum(['default', 'highlight', 'muted', 'success', 'danger']).optional(),
          isTotalRow: z.boolean().optional(),
        })),
        compact: z.boolean().optional(),
      }),
    },

    LineItemsTable: {
      description: 'Invoice-style table with item descriptions, quantities, prices, and totals',
      props: z.object({
        items: z.array(z.object({
          name: z.string(),
          description: z.string().optional(),
          quantity: z.number(),
          unitPrice: z.number(),
          total: z.number(),
        })),
        currency: z.string().optional(),
      }),
    },

    InfoBlock: {
      description: 'Labeled block of information (e.g. From/To on invoices)',
      props: z.object({
        label: z.string(),
        name: z.string(),
        lines: z.array(z.string()),
      }),
    },

    // ── Interactive ──────────────────────────────────────────
    SearchBar: {
      description: 'Search input with optional filter options',
      props: z.object({
        placeholder: z.string().optional(),
        valuePath: z.string().optional(),
      }),
    },

    FilterChips: {
      description: 'Toggleable filter tags for narrowing results',
      props: z.object({
        chips: z.array(z.object({
          label: z.string(),
          value: z.string(),
          active: z.boolean().optional(),
        })),
        dataPath: z.string().optional(),
      }),
    },

    TabGroup: {
      description: 'Tab navigation for switching views',
      props: z.object({
        tabs: z.array(z.object({
          label: z.string(),
          value: z.string(),
          count: z.number().optional(),
        })),
        activeTab: z.string().optional(),
        dataPath: z.string().optional(),
      }),
    },

    // ── Actions ──────────────────────────────────────────────
    ActionButton: {
      description: 'Clickable action button with variants',
      props: z.object({
        label: z.string(),
        variant: z.enum(['primary', 'secondary', 'danger', 'ghost']).optional(),
        size: z.enum(['sm', 'md', 'lg']).optional(),
        icon: z.string().optional(),
        disabled: z.boolean().optional(),
      }),
    },

    ActionBar: {
      description: 'Row of action buttons, typically at the bottom of a detail view',
      props: z.object({
        align: z.enum(['left', 'center', 'right']).optional(),
      }),
      hasChildren: true,
    },
  },

  // ── Action Definitions ──────────────────────────────────────
  actions: {
    view_contact: {
      description: 'View a contact\'s full profile',
      params: z.object({ contactId: z.string() }),
    },
    edit_contact: {
      description: 'Open contact edit form',
      params: z.object({ contactId: z.string() }),
    },
    delete_contact: {
      description: 'Delete a contact with confirmation',
      params: z.object({ contactId: z.string() }),
    },
    move_opportunity: {
      description: 'Move an opportunity to a different pipeline stage',
      params: z.object({ opportunityId: z.string(), stage: z.string() }),
    },
    send_invoice: {
      description: 'Send an invoice to the client via email',
      params: z.object({ invoiceId: z.string() }),
    },
    mark_paid: {
      description: 'Mark an invoice as paid',
      params: z.object({ invoiceId: z.string() }),
    },
    void_invoice: {
      description: 'Void/cancel an invoice',
      params: z.object({ invoiceId: z.string() }),
    },
    download_pdf: {
      description: 'Download a PDF of the invoice or report',
      params: z.object({ entityId: z.string() }),
    },
    pause_campaign: {
      description: 'Pause a running campaign',
      params: z.object({ campaignId: z.string() }),
    },
    resume_campaign: {
      description: 'Resume a paused campaign',
      params: z.object({ campaignId: z.string() }),
    },
    export_data: {
      description: 'Export current view data as CSV/PDF',
      params: z.object({ format: z.enum(['csv', 'pdf']).optional() }),
    },
    refresh_data: {
      description: 'Refresh all data in the current view',
    },
  },
})

export type GHLCatalog = typeof ghlCatalog
