import type { Component, InjectionKey } from 'vue'
import type { UiGridStatusMap } from '../gridStatus'

export type UiSeverity = 'primary' | 'secondary' | 'success' | 'info' | 'warning' | 'danger'
export type UiButtonType = 'button' | 'submit' | 'reset'
export type UiAdapterId = 'primevue-aggrid' | 'native-accessible'
export type UiAdapterContractVersion = '4.0'
export type UiAdapterCapability =
  | 'button'
  | 'text-field'
  | 'text-area'
  | 'select'
  | 'multi-select'
  | 'checkbox'
  | 'date-field'
  | 'number-field'
  | 'dialog'
  | 'status-tag'
  | 'inline-message'
  | 'paginator'
  | 'tabs'
  | 'data-grid'

export interface UiSelectOption {
  label: string
  value: string | number | boolean | null
  disabled?: boolean
}

export interface UiTabItem {
  id: string
  label: string
  disabled?: boolean
  badge?: string | number
}

export type UiGridSortDirection = 'asc' | 'desc'
export interface UiGridSort { field: string; direction: UiGridSortDirection }
export interface UiGridFilter { field: string; operator: string; value: unknown }
export interface UiGridQuery {
  page: number
  pageSize: number
  sorts: UiGridSort[]
  filters: UiGridFilter[]
  search?: string
}

export interface UiGridColumn {
  field: string
  header: string
  width?: number
  minWidth?: number
  sortable?: boolean
  filterable?: boolean
  sensitive?: boolean
  formatter?: (value: unknown, row: unknown) => string
  statusMap?: UiGridStatusMap
}

export type UiTextFieldType = 'text' | 'email' | 'password' | 'number' | 'date'

export interface UiAdapterDescriptor {
  readonly id: UiAdapterId
  readonly version: string
  readonly contractVersion: UiAdapterContractVersion
  readonly vendor: string
  readonly capabilities: ReadonlySet<UiAdapterCapability>
  readonly productionEligible: boolean
  readonly accessibilityBaseline: 'WCAG_2_2_AA_TARGET'
}

export interface UiAdapter {
  readonly descriptor: UiAdapterDescriptor
  readonly components: {
    Button: Component
    TextField: Component
    TextArea: Component
    Select: Component
    MultiSelect: Component
    Checkbox: Component
    DateField: Component
    NumberField: Component
    Dialog: Component
    StatusTag: Component
    InlineMessage: Component
    Paginator: Component
    Tabs: Component
    DataGrid: Component
  }
}

export const requiredUiAdapterCapabilities: readonly UiAdapterCapability[] = Object.freeze([
  'button', 'text-field', 'text-area', 'select', 'multi-select', 'checkbox', 'date-field',
  'number-field', 'dialog', 'status-tag', 'inline-message', 'paginator', 'tabs', 'data-grid'
])

export function assertUiAdapterContract(adapter: UiAdapter): void {
  if (adapter.descriptor.contractVersion !== '4.0') {
    throw new Error(`Unsupported UI adapter contract: ${adapter.descriptor.contractVersion}`)
  }
  const missing = requiredUiAdapterCapabilities.filter(x => !adapter.descriptor.capabilities.has(x))
  if (missing.length > 0) {
    throw new Error(`UI adapter ${adapter.descriptor.id} is missing capabilities: ${missing.join(', ')}`)
  }
  const componentNames = [
    'Button', 'TextField', 'TextArea', 'Select', 'MultiSelect', 'Checkbox', 'DateField',
    'NumberField', 'Dialog', 'StatusTag', 'InlineMessage', 'Paginator', 'Tabs', 'DataGrid'
  ] as const
  for (const name of componentNames) {
    if (!adapter.components[name]) throw new Error(`UI adapter ${adapter.descriptor.id} has no component for ${name}`)
  }
}

export const uiAdapterKey: InjectionKey<UiAdapter> = Symbol('KArtSellUiAdapterV4')
