/**
 * GenUI Component Registry
 * =========================
 * Phase 19.4a - 動態 UI 組件註冊表
 *
 * ADR-032: Pre-compiled Registry Pattern
 * - 所有 GenUI 組件必須在此註冊
 * - 支援 Lazy Loading (React.lazy)
 * - Props 類型驗證 (Zod Schema)
 *
 * Phase 19 首席架構師審查 P1 改進:
 * - 升級 Props Schema 為 Zod 驗證
 * - 支援格式驗證 (如百分比、時間單位)
 * - 錯誤分類便於聚合分析
 *
 * @see ADR-032 GenUI Dynamic Rendering
 * @author Claude Code (首席架構師)
 * @version 1.1.0 - Zod Schema 升級
 * @date 2026-03-28 (台北時間)
 */

import { lazy, type ComponentType } from 'react'
import { z, type ZodSchema } from 'zod'

// =============================================================================
// Zod Schemas (Phase 19 首席架構師審查 P1)
// =============================================================================

/** ApprovalCard Props Schema */
export const ApprovalCardSchema = z.object({
  approvalId: z.string().min(1),
  riskLevel: z.enum(['low', 'medium', 'high', 'critical']),
  kubectl: z.string().optional(),
})

/** MetricsSummaryCard Props Schema */
export const MetricsSummaryCardSchema = z.object({
  rps: z.number().min(0),
  errorRate: z.string().regex(/^\d+(\.\d+)?%$/, 'Must be percentage format (e.g., "0.05%")'),
  p99Latency: z.string().regex(/^\d+(\.\d+)?(ms|s)$/, 'Must be time format (e.g., "450ms")'),
  status: z.enum(['healthy', 'warning', 'critical']),
})

/** SentryErrorCard Props Schema */
export const SentryErrorCardSchema = z.object({
  errorId: z.string().min(1),
  title: z.string().min(1),
  count: z.number().int().min(0),
  lastSeen: z.string(), // ISO date string
})

/** IncidentTimelineCard Props Schema */
export const IncidentTimelineCardSchema = z.object({
  incidentId: z.string().min(1),
  events: z.array(z.object({
    timestamp: z.string(),
    message: z.string(),
    type: z.string().optional(),
  })),
  status: z.enum(['active', 'resolved', 'acknowledged']),
})

/** K8sPodStatusCard Props Schema */
export const K8sPodStatusCardSchema = z.object({
  namespace: z.string().min(1),
  pods: z.array(z.object({
    name: z.string(),
    status: z.string(),
    ready: z.boolean().optional(),
  })),
  summary: z.object({
    total: z.number().int().min(0),
    running: z.number().int().min(0),
    failed: z.number().int().min(0).optional(),
  }),
})

/** TraceWaterfallCard Props Schema */
export const TraceWaterfallCardSchema = z.object({
  traceId: z.string().min(1),
  spans: z.array(z.object({
    spanId: z.string(),
    name: z.string(),
    duration: z.number().min(0),
    startTime: z.number().optional(),
  })),
  duration: z.number().min(0),
})

/** NuclearKeyButton Props Schema */
export const NuclearKeyButtonSchema = z.object({
  label: z.string().min(1),
  riskLevel: z.enum(['low', 'medium', 'high', 'critical']),
  approvalId: z.string().optional(),
})

// =============================================================================
// Registry Types
// =============================================================================

/** 組件 Props 基礎類型 */
export interface BaseGenUIProps {
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  data: any
}

/** GenUI 組件定義 */
export interface GenUIComponentDef {
  /** 組件名稱 (唯一識別符) */
  name: string
  /** 組件描述 */
  description: string
  /** React 組件 (支援 lazy loading) */
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  component: ComponentType<any>
  /** Props Schema (Zod 驗證) */
  zodSchema?: ZodSchema
  /** Legacy Props Schema (向後相容) */
  propsSchema?: Record<string, 'string' | 'number' | 'boolean' | 'object' | 'array'>
  /** 是否允許在 Terminal 中渲染 */
  allowInTerminal: boolean
  /** 風險等級 (決定是否需要確認) */
  riskLevel?: 'low' | 'medium' | 'high'
}

// =============================================================================
// Lazy Component Imports
// =============================================================================

// 核心 GenUI 組件 (lazy loaded)
const ApprovalCard = lazy(() =>
  import('./ApprovalCard').then(m => ({ default: m.ApprovalCard }))
)

const MetricsSummaryCard = lazy(() =>
  import('./MetricsSummaryCard').then(m => ({ default: m.MetricsSummaryCard }))
)

const SentryErrorCard = lazy(() =>
  import('./SentryErrorCard').then(m => ({ default: m.SentryErrorCard }))
)

const IncidentTimelineCard = lazy(() =>
  import('./IncidentTimelineCard').then(m => ({ default: m.IncidentTimelineCard }))
)

const K8sPodStatusCard = lazy(() =>
  import('./K8sPodStatusCard').then(m => ({ default: m.K8sPodStatusCard }))
)

const TraceWaterfallCard = lazy(() =>
  import('./TraceWaterfallCard').then(m => ({ default: m.TraceWaterfallCard }))
)

const NuclearKeyButton = lazy(() =>
  import('./NuclearKeyButton').then(m => ({ default: m.NuclearKeyButton }))
)

// =============================================================================
// Component Registry
// =============================================================================

/**
 * GenUI 組件註冊表
 *
 * ADR-032: 所有可動態渲染的組件必須在此註冊
 */
export const GENUI_REGISTRY: Record<string, GenUIComponentDef> = {
  // -------------------------------------------------------------------------
  // 核心卡片 (6 張)
  // -------------------------------------------------------------------------

  ApprovalCard: {
    name: 'ApprovalCard',
    description: '核鑰授權卡 - 顯示待簽核操作',
    component: ApprovalCard,
    zodSchema: ApprovalCardSchema,
    propsSchema: {
      approvalId: 'string',
      riskLevel: 'string',
      kubectl: 'string',
    },
    allowInTerminal: true,
    riskLevel: 'high',
  },

  MetricsSummaryCard: {
    name: 'MetricsSummaryCard',
    description: '指標摘要卡 - 顯示 SignOz 即時指標',
    component: MetricsSummaryCard,
    zodSchema: MetricsSummaryCardSchema,
    propsSchema: {
      rps: 'number',
      errorRate: 'string',
      p99Latency: 'string',
      status: 'string',
    },
    allowInTerminal: true,
    riskLevel: 'low',
  },

  SentryErrorCard: {
    name: 'SentryErrorCard',
    description: '錯誤追蹤卡 - 顯示 Sentry 錯誤詳情',
    component: SentryErrorCard,
    zodSchema: SentryErrorCardSchema,
    propsSchema: {
      errorId: 'string',
      title: 'string',
      count: 'number',
      lastSeen: 'string',
    },
    allowInTerminal: true,
    riskLevel: 'low',
  },

  IncidentTimelineCard: {
    name: 'IncidentTimelineCard',
    description: '事件時間軸卡 - 顯示 Incident 歷程',
    component: IncidentTimelineCard,
    zodSchema: IncidentTimelineCardSchema,
    propsSchema: {
      incidentId: 'string',
      events: 'array',
      status: 'string',
    },
    allowInTerminal: true,
    riskLevel: 'low',
  },

  K8sPodStatusCard: {
    name: 'K8sPodStatusCard',
    description: 'Pod 狀態卡 - 顯示 K8s Pod 健康狀態',
    component: K8sPodStatusCard,
    zodSchema: K8sPodStatusCardSchema,
    propsSchema: {
      namespace: 'string',
      pods: 'array',
      summary: 'object',
    },
    allowInTerminal: true,
    riskLevel: 'low',
  },

  TraceWaterfallCard: {
    name: 'TraceWaterfallCard',
    description: '追蹤瀑布圖卡 - 顯示 SignOz Trace 詳情',
    component: TraceWaterfallCard,
    zodSchema: TraceWaterfallCardSchema,
    propsSchema: {
      traceId: 'string',
      spans: 'array',
      duration: 'number',
    },
    allowInTerminal: true,
    riskLevel: 'low',
  },

  // -------------------------------------------------------------------------
  // 核鑰 UX 組件
  // -------------------------------------------------------------------------

  NuclearKeyButton: {
    name: 'NuclearKeyButton',
    description: '核鑰授權按鈕 - 長按確認高風險操作',
    component: NuclearKeyButton,
    zodSchema: NuclearKeyButtonSchema,
    propsSchema: {
      label: 'string',
      riskLevel: 'string',
    },
    allowInTerminal: true,
    riskLevel: 'high',
  },
}

// =============================================================================
// Registry API
// =============================================================================

/**
 * 取得組件定義
 */
export function getComponent(name: string): GenUIComponentDef | undefined {
  return GENUI_REGISTRY[name]
}

/**
 * 檢查組件是否已註冊
 */
export function isRegistered(name: string): boolean {
  return name in GENUI_REGISTRY
}

/**
 * 取得所有已註冊的組件名稱
 */
export function getRegisteredComponents(): string[] {
  return Object.keys(GENUI_REGISTRY)
}

/**
 * 取得適合 Terminal 渲染的組件
 */
export function getTerminalComponents(): GenUIComponentDef[] {
  return Object.values(GENUI_REGISTRY).filter(c => c.allowInTerminal)
}

/** 驗證結果類型 (Phase 19 首席架構師審查 P1) */
export interface ValidationResult {
  valid: boolean
  errors: string[]
  /** 錯誤分類碼 (便於 Sentry 聚合) */
  errorCode?: 'UNKNOWN_COMPONENT' | 'ZOD_VALIDATION_FAILED' | 'LEGACY_TYPE_MISMATCH'
}

/**
 * 驗證 Props (Zod + Legacy 雙模式)
 *
 * Phase 19 首席架構師審查 P1 改進:
 * - 優先使用 Zod Schema 驗證 (更精確的格式檢查)
 * - 回退到 Legacy propsSchema (向後相容)
 * - 返回錯誤分類碼便於 Sentry 聚合
 */
export function validateProps(
  componentName: string,
  props: Record<string, unknown>
): ValidationResult {
  const def = GENUI_REGISTRY[componentName]
  if (!def) {
    return {
      valid: false,
      errors: [`Unknown component: ${componentName}`],
      errorCode: 'UNKNOWN_COMPONENT',
    }
  }

  // 優先使用 Zod Schema 驗證 (Phase 19 P1)
  if (def.zodSchema) {
    const result = def.zodSchema.safeParse(props)
    if (!result.success) {
      const errors = result.error.errors.map(e =>
        `${e.path.join('.')}: ${e.message}`
      )
      return {
        valid: false,
        errors,
        errorCode: 'ZOD_VALIDATION_FAILED',
      }
    }
    return { valid: true, errors: [] }
  }

  // Legacy propsSchema 回退驗證
  if (!def.propsSchema) {
    return { valid: true, errors: [] }
  }

  const errors: string[] = []

  for (const [key, expectedType] of Object.entries(def.propsSchema)) {
    const value = props[key]

    if (value === undefined) {
      // Optional props are OK
      continue
    }

    const actualType = Array.isArray(value) ? 'array' : typeof value

    if (actualType !== expectedType) {
      errors.push(`${key}: expected ${expectedType}, got ${actualType}`)
    }
  }

  return {
    valid: errors.length === 0,
    errors,
    errorCode: errors.length > 0 ? 'LEGACY_TYPE_MISMATCH' : undefined,
  }
}
