/// <reference path="../../lynx.d.ts" />
/**
 * OutlinedInput Component - Lynx 版 MUI OutlinedInput
 * 100% 一比一复刻 MUI OutlinedInput
 * 
 * 带有轮廓边框的输入框
 * 
 * 对应 MUI: packages/mui-material/src/OutlinedInput/OutlinedInput.js
 */
import './OutlinedInput.css'
import outlinedInputClasses, { getOutlinedInputUtilityClass } from './outlinedInputClasses'
import { InputBase, InputBaseProps } from '../InputBase'
import { useFormControl, formControlState } from '../FormControl'
export { outlinedInputClasses, getOutlinedInputUtilityClass }

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

export interface OutlinedInputProps extends InputBaseProps {
  /** 标签（用于计算轮廓缺口） */
  label?: any
  /** 是否显示缺口 */
  notched?: boolean
}

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

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 OutlinedInputProps {
  focused?: boolean
  hiddenLabel?: boolean
}

function useUtilityClasses(ownerState: OwnerState) {
  const { classes } = ownerState

  const slots = {
    root: ['root'],
    notchedOutline: ['notchedOutline'],
    input: ['input'],
  }

  return composeClasses(slots, getOutlinedInputUtilityClass, classes)
}

// =============================================
// OutlinedInput 组件
// =============================================

export function OutlinedInput(props: OutlinedInputProps) {
  const {
    className,
    fullWidth = false,
    label,
    multiline = false,
    notched,
    type = 'text',
    ...other
  } = props

  const classes = useUtilityClasses(props)

  const muiFormControl = useFormControl()

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

  const ownerState: OwnerState = {
    ...props,
    color: fcs.color || 'primary',
    disabled: fcs.disabled,
    error: fcs.error,
    focused: fcs.focused,
    fullWidth,
    hiddenLabel: fcs.hiddenLabel,
    multiline,
    size: fcs.size,
    type,
  }

  // 计算是否显示缺口
  const showNotch = notched ?? (fcs.focused || fcs.filled || fcs.adornedStart)

  // 构建类名
  const rootClasses = [
    classes.root,
    outlinedInputClasses.root,
    className,
    fcs.focused && outlinedInputClasses.focused,
    fcs.disabled && outlinedInputClasses.disabled,
    fcs.error && outlinedInputClasses.error,
    fcs.size === 'small' && outlinedInputClasses.sizeSmall,
    multiline && outlinedInputClasses.multiline,
    props.startAdornment && outlinedInputClasses.adornedStart,
    props.endAdornment && outlinedInputClasses.adornedEnd,
  ].filter(Boolean).join(' ')

  // 输入类名
  const inputClasses = [
    classes.input,
    outlinedInputClasses.input,
    fcs.size === 'small' && outlinedInputClasses.inputSizeSmall,
    multiline && outlinedInputClasses.inputMultiline,
    props.startAdornment && outlinedInputClasses.inputAdornedStart,
    props.endAdornment && outlinedInputClasses.inputAdornedEnd,
  ].filter(Boolean).join(' ')

  return (
    <view className={rootClasses}>
      <InputBase
        fullWidth={fullWidth}
        multiline={multiline}
        type={type}
        className={inputClasses}
        {...other}
      />
      {/* Notched Outline */}
      <view className={[
        classes.notchedOutline,
        outlinedInputClasses.notchedOutline,
        fcs.error && 'Mui-error',
        fcs.focused && 'Mui-focused',
      ].filter(Boolean).join(' ')}>
        {label && showNotch && (
          <view className="MuiOutlinedInput-legend">
            <text>
              {label}
              {fcs.required && ' *'}
            </text>
          </view>
        )}
      </view>
    </view>
  )
}

// MUI 名称标识
OutlinedInput.muiName = 'Input'

export default OutlinedInput
