/// <reference path="../../lynx.d.ts" />
/**
 * InputLabel Component - Lynx 版 MUI InputLabel
 * 100% 一比一复刻 MUI InputLabel
 * 
 * 对应 MUI: packages/mui-material/src/InputLabel/InputLabel.js
 */
import './InputLabel.css'
import inputLabelClasses, { getInputLabelUtilityClass } from './inputLabelClasses'
import { useFormControl, formControlState } from '../FormControl'
export { inputLabelClasses, getInputLabelUtilityClass }

// =============================================
// 类型定义
// =============================================

export type InputLabelColor = 'primary' | 'secondary' | 'error' | 'info' | 'success' | 'warning'
export type InputLabelMargin = 'dense'
export type InputLabelSize = 'small' | 'normal'
export type InputLabelVariant = 'standard' | 'outlined' | 'filled'

export interface InputLabelProps {
  /** 子元素 */
  children?: any
  /** 自定义类名 */
  className?: string
  /** 样式类覆盖 */
  classes?: Partial<typeof inputLabelClasses>
  /** 颜色 */
  color?: InputLabelColor
  /** 是否禁用动画 */
  disableAnimation?: boolean
  /** 是否禁用 */
  disabled?: boolean
  /** 是否错误状态 */
  error?: boolean
  /** 是否聚焦 */
  focused?: boolean
  /** htmlFor */
  htmlFor?: string
  /** 边距 */
  margin?: InputLabelMargin
  /** 是否必填 */
  required?: boolean
  /** 是否收缩 */
  shrink?: boolean
  /** 尺寸 */
  size?: InputLabelSize
  /** 内联样式 */
  style?: Record<string, any>
  /** sx 属性 */
  sx?: Record<string, any>
  /** 变体 */
  variant?: InputLabelVariant
}

// =============================================
// 辅助函数
// =============================================

function capitalize(str: string): string {
  return str.charAt(0).toUpperCase() + str.slice(1)
}

function composeClasses(
  slots: Record<string, (string | boolean | null | undefined)[]>,
  getUtilityClass: (slot: string) => string,
  classes?: Record<string, string>
): Record<string, string> {
  const output: Record<string, string> = {}
  
  Object.keys(slots).forEach((slot) => {
    output[slot] = slots[slot]
      .filter(Boolean)
      .map((key) => {
        if (classes && classes[key as string]) {
          return `${getUtilityClass(key as string)} ${classes[key as string]}`
        }
        return getUtilityClass(key as string)
      })
      .join(' ')
  })
  
  return output
}

// =============================================
// useUtilityClasses
// =============================================

interface OwnerState extends InputLabelProps {
  formControl?: boolean
}

function useUtilityClasses(ownerState: OwnerState) {
  const {
    classes,
    disabled,
    error,
    focused,
    formControl,
    required,
    shrink,
    size,
    variant,
    disableAnimation,
  } = ownerState

  const slots = {
    root: [
      'root',
      formControl && 'formControl',
      !disableAnimation && 'animated',
      shrink && 'shrink',
      size && size !== 'normal' && `size${capitalize(size)}`,
      variant,
    ],
    asterisk: [required && 'asterisk'],
  }

  return composeClasses(slots, getInputLabelUtilityClass, classes)
}

// =============================================
// InputLabel 组件
// =============================================

export function InputLabel(props: InputLabelProps) {
  const {
    children,
    className,
    classes: classesProp,
    color,
    disableAnimation = false,
    disabled,
    error,
    focused,
    htmlFor,
    margin,
    required,
    shrink,
    size,
    style,
    sx,
    variant,
    ...other
  } = props

  const muiFormControl = useFormControl()

  const fcs = formControlState({
    props,
    muiFormControl,
    states: ['color', 'disabled', 'error', 'focused', 'hiddenLabel', 'required', 'size', 'variant'],
  })

  const computedShrink = shrink ?? (fcs.filled || fcs.focused || fcs.adornedStart)

  const ownerState: OwnerState = {
    ...props,
    color: fcs.color || 'primary',
    disabled: fcs.disabled,
    error: fcs.error,
    focused: fcs.focused,
    formControl: !!muiFormControl,
    required: fcs.required,
    shrink: computedShrink,
    size: fcs.size,
    variant: fcs.variant || 'outlined',
    disableAnimation,
  }

  const classes = useUtilityClasses(ownerState)

  // 构建类名
  const rootClasses = [
    classes.root,
    className,
    fcs.disabled && 'Mui-disabled',
    fcs.error && 'Mui-error',
    fcs.focused && 'Mui-focused',
    fcs.required && 'Mui-required',
  ].filter(Boolean).join(' ')

  return (
    <view
      className={rootClasses}
      style={sx ? { ...sx, ...style } : style}
      {...other}
    >
      <text className="MuiInputLabel-text">
        {children}
        {fcs.required && (
          <text className={classes.asterisk}> *</text>
        )}
      </text>
    </view>
  )
}

export default InputLabel
