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

// =============================================
// 类型定义 - 对应 MUI Button.d.ts
// =============================================

export type ButtonVariant = 'text' | 'outlined' | 'contained'
export type ButtonColor = 'inherit' | 'primary' | 'secondary' | 'success' | 'error' | 'info' | 'warning'
export type ButtonSize = 'small' | 'medium' | 'large'
export type ButtonLoadingPosition = 'start' | 'end' | 'center'

export interface ButtonProps {
  /** 子元素 */
  children?: any
  /** 自定义类名 */
  className?: string
  /** 样式类覆盖 */
  classes?: Partial<typeof buttonClasses>
  /** 颜色 */
  color?: ButtonColor
  /** 是否禁用 */
  disabled?: boolean
  /** 是否禁用阴影 */
  disableElevation?: boolean
  /** 是否禁用焦点涟漪 */
  disableFocusRipple?: boolean
  /** 是否禁用涟漪 */
  disableRipple?: boolean
  /** 结束图标 */
  endIcon?: any
  /** 焦点可见时的类名 */
  focusVisibleClassName?: string
  /** 是否占满宽度 */
  fullWidth?: boolean
  /** 链接地址 */
  href?: string
  /** ID */
  id?: string
  /** 是否加载中 */
  loading?: boolean | null
  /** 加载指示器 */
  loadingIndicator?: any
  /** 加载指示器位置 */
  loadingPosition?: ButtonLoadingPosition
  /** 尺寸 */
  size?: ButtonSize
  /** 开始图标 */
  startIcon?: any
  /** 内联样式 */
  style?: Record<string, any>
  /** sx 属性 */
  sx?: Record<string, any>
  /** 按钮类型 */
  type?: 'button' | 'submit' | 'reset'
  /** 变体 */
  variant?: ButtonVariant
  /** 点击事件 */
  bindtap?: (event?: any) => void
  onClick?: (event?: any) => void
}

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

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 - 对应 MUI 实现
// =============================================

interface OwnerState extends ButtonProps {
  loading?: boolean | null
}

function useUtilityClasses(ownerState: OwnerState) {
  const { 
    color = 'primary', 
    disableElevation, 
    fullWidth, 
    size = 'medium', 
    variant = 'text', 
    loading,
    loadingPosition = 'center',
    classes 
  } = ownerState

  const slots = {
    root: [
      'root',
      loading && 'loading',
      variant,
      `${variant}${capitalize(color)}`,
      `size${capitalize(size)}`,
      `${variant}Size${capitalize(size)}`,
      `color${capitalize(color)}`,
      disableElevation && 'disableElevation',
      fullWidth && 'fullWidth',
      loading && `loadingPosition${capitalize(loadingPosition)}`,
    ],
    startIcon: ['icon', 'startIcon', `iconSize${capitalize(size)}`],
    endIcon: ['icon', 'endIcon', `iconSize${capitalize(size)}`],
    loadingIndicator: ['loadingIndicator'],
    loadingWrapper: ['loadingWrapper'],
  }

  return composeClasses(slots, getButtonUtilityClass, classes)
}

// =============================================
// Button 组件 - 完整实现
// =============================================

export function Button(props: ButtonProps) {
  const {
    children,
    className,
    classes: classesProp,
    color = 'primary',
    disabled = false,
    disableElevation = false,
    disableFocusRipple = false,
    disableRipple = false,
    endIcon: endIconProp,
    focusVisibleClassName,
    fullWidth = false,
    id,
    loading = null,
    loadingIndicator: loadingIndicatorProp,
    loadingPosition = 'center',
    size = 'medium',
    startIcon: startIconProp,
    style,
    sx,
    type = 'button',
    variant = 'text',
    bindtap,
    onClick,
    ...other
  } = props

  // 加载指示器
  const loadingIndicator = loadingIndicatorProp ?? (
    <view className="MuiButton-loadingIndicatorDefault">
      <view className="MuiCircularProgress-root MuiCircularProgress-indeterminate MuiCircularProgress-colorInherit" style={{ width: 16, height: 16 }}>
        <view className="MuiCircularProgress-spinner" />
      </view>
    </view>
  )

  const ownerState: OwnerState = {
    ...props,
    color,
    disabled,
    disableElevation,
    disableFocusRipple,
    fullWidth,
    loading,
    loadingIndicator,
    loadingPosition,
    size,
    type,
    variant,
  }

  const classes = useUtilityClasses(ownerState)

  // 开始图标
  const startIcon = (startIconProp || (loading && loadingPosition === 'start')) && (
    <view className={classes.startIcon}>
      {startIconProp || <view className="MuiButton-loadingIconPlaceholder" style={{ width: '1em', height: '1em' }} />}
    </view>
  )

  // 结束图标
  const endIcon = (endIconProp || (loading && loadingPosition === 'end')) && (
    <view className={classes.endIcon}>
      {endIconProp || <view className="MuiButton-loadingIconPlaceholder" style={{ width: '1em', height: '1em' }} />}
    </view>
  )

  // 加载器
  const loader = typeof loading === 'boolean' ? (
    <view className={classes.loadingWrapper} style={{ display: 'contents' }}>
      {loading && (
        <view className={classes.loadingIndicator}>
          {loadingIndicator}
        </view>
      )}
    </view>
  ) : null

  // 构建最终类名
  const rootClasses = [
    classes.root,
    className,
    disabled && buttonClasses.disabled,
  ].filter(Boolean).join(' ')

  // 处理点击
  const handleTap = (event?: any) => {
    if (disabled || loading) return
    if (bindtap) bindtap(event)
    if (onClick) onClick(event)
  }

  return (
    <view
      className={rootClasses}
      style={sx ? { ...sx, ...style } : style}
      bindtap={handleTap}
      accessibility-element={true}
      {...other}
    >
      {startIcon}
      {loadingPosition !== 'end' && loader}
      {loading && loadingPosition === 'center' ? (
        <text className="MuiButton-label" style={{ visibility: 'hidden' }}>{children}</text>
      ) : (
        <text className="MuiButton-label">{children}</text>
      )}
      {loadingPosition === 'end' && loader}
      {endIcon}
    </view>
  )
}

export default Button
