/// <reference path="../../lynx.d.ts" />
/**
 * Slider Component - Lynx 版 MUI Slider
 * 100% 一比一复刻 MUI Slider (简化版)
 * 
 * 滑块组件，支持点击轨道调整数值
 * 在 Lynx 环境下使用点击交互替代拖动交互
 * 
 * 对应 MUI: packages/mui-material/src/Slider/Slider.js
 */
import './Slider.css'
import sliderClasses, { getSliderUtilityClass } from './sliderClasses'
export { sliderClasses, getSliderUtilityClass }

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

export type SliderOrientation = 'horizontal' | 'vertical'
export type SliderSize = 'small' | 'medium'
export type SliderColor = 'primary' | 'secondary' | 'error' | 'info' | 'success' | 'warning'

export interface SliderMark {
  value: number
  label?: string
}

export interface SliderProps {
  /** 自定义类名 */
  className?: string
  /** 样式类覆盖 */
  classes?: Partial<typeof sliderClasses>
  /** 默认值 */
  defaultValue?: number
  /** 是否禁用 */
  disabled?: boolean
  /** 标记点 */
  marks?: boolean | SliderMark[]
  /** 最大值 */
  max?: number
  /** 最小值 */
  min?: number
  /** 方向 */
  orientation?: SliderOrientation
  /** 尺寸 */
  size?: SliderSize
  /** 步长 */
  step?: number
  /** 轨轨反转 */
  track?: 'normal' | 'inverted' | false
  /** 当前值 */
  value?: number
  /** 是否显示值标签 */
  valueLabelDisplay?: 'on' | 'auto' | 'off'
  /** 值标签格式化 */
  valueLabelFormat?: string | ((value: number) => string)
  /** 内联样式 */
  style?: Record<string, any>
  /** sx 属性 */
  sx?: Record<string, any>
  /** 变化事件 */
  onChange?: (event: any, value: number) => void
  onChangeCommitted?: (event: any, value: number) => 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
}

function clamp(value: number, min: number, max: number): number {
  return Math.min(Math.max(value, min), max)
}

function roundValueToPrecision(value: number, precision: number): number {
  if (precision === 0) return value
  const nearest = Math.round(value / precision) * precision
  return Number(nearest.toFixed(10))
}

function valueToPercent(value: number, min: number, max: number): number {
  return ((value - min) * 100) / (max - min)
}

function percentToValue(percent: number, min: number, max: number): number {
  return min + (max - min) * percent
}

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

interface OwnerState extends SliderProps {
  marked?: boolean
}

function useUtilityClasses(ownerState: OwnerState) {
  const { 
    classes, 
    disabled, 
    marked, 
    orientation, 
    track 
  } = ownerState

  const slots = {
    root: [
      'root',
      disabled && 'disabled',
      marked && 'marked',
      orientation,
      track === 'inverted' && 'trackInverted',
      track === false && 'trackFalse',
    ],
    rail: ['rail'],
    track: ['track'],
    thumb: ['thumb'],
    valueLabel: ['valueLabel'],
    mark: ['mark'],
    markActive: ['markActive'],
    markLabel: ['markLabel'],
    markLabelActive: ['markLabelActive'],
  }

  return composeClasses(slots, getSliderUtilityClass, classes)
}

// =============================================
// Slider 组件
// =============================================

export function Slider(props: SliderProps) {
  const {
    className,
    classes: classesProp,
    defaultValue = 0,
    disabled = false,
    marks = false,
    max = 100,
    min = 0,
    orientation = 'horizontal',
    size = 'medium',
    step = 1,
    track = 'normal',
    value: valueProp,
    valueLabelDisplay = 'off',
    valueLabelFormat,
    style,
    sx,
    onChange,
    onChangeCommitted,
    ...other
  } = props

  // 在 Lynx 环境下，组件必须是受控的
  // 如果没有提供 value 属性，使用默认值
  const value = valueProp !== undefined ? valueProp : defaultValue

  const ownerState: OwnerState = {
    ...props,
    value,
    disabled,
    marks,
    orientation,
    track,
  }

  const classes = useUtilityClasses(ownerState)

  // 处理轨道点击
  const handleTrackTap = (event: any) => {
    if (disabled) return

    // 在 Lynx 环境下，简化处理：点击轨道时跳转到最近的步长值
    // 这里使用简化的逻辑，实际应用中可能需要根据点击位置计算
    const newValue = roundValueToPrecision(value, step)
    const clampedValue = clamp(newValue, min, max)

    if (onChange) {
      onChange(event, clampedValue)
    }
    if (onChangeCommitted) {
      onChangeCommitted(event, clampedValue)
    }
  }

  // 处理滑块点击
  const handleThumbTap = (event: any) => {
    if (disabled) return

    // 在 Lynx 环境下，简化处理：点击滑块时增加一个步长
    const newValue = roundValueToPrecision(value + step, step)
    const clampedValue = clamp(newValue, min, max)

    if (onChange) {
      onChange(event, clampedValue)
    }
    if (onChangeCommitted) {
      onChangeCommitted(event, clampedValue)
    }
  }

  // 格式化值标签
  const formatValueLabel = (val: number): string => {
    if (typeof valueLabelFormat === 'function') {
      return valueLabelFormat(val)
    }
    if (typeof valueLabelFormat === 'string') {
      return valueLabelFormat.replace('{value}', val.toString())
    }
    return val.toString()
  }

  // 计算滑块位置百分比
  const percent = valueToPercent(value, min, max)
  const trackPercent = track === 'inverted' ? 100 - percent : percent

  // 渲染标记点
  const renderMarks = () => {
    if (!marks) return null

    const marksArray = Array.isArray(marks) ? marks : []
    const markElements: any[] = []

    marksArray.forEach((mark, index) => {
      const markPercent = valueToPercent(mark.value, min, max)
      const isActive = mark.value <= value

      markElements.push(
        <view
          key={`mark-${index}`}
          className={[
            classes.mark,
            sliderClasses.mark,
            isActive && sliderClasses.markActive,
          ].filter(Boolean).join(' ')}
          style={{
            [orientation === 'horizontal' ? 'left' : 'bottom']: `${markPercent}%`,
          }}
        />
      )

      if (mark.label) {
        markElements.push(
          <text
            key={`mark-label-${index}`}
            className={[
              classes.markLabel,
              sliderClasses.markLabel,
              isActive && sliderClasses.markLabelActive,
            ].filter(Boolean).join(' ')}
            style={{
              [orientation === 'horizontal' ? 'left' : 'bottom']: `${markPercent}%`,
            }}
          >
            {mark.label}
          </text>
        )
      }
    })

    return markElements
  }

  // 构建类名
  const rootClasses = [
    classes.root,
    sliderClasses.root,
    className,
    disabled && sliderClasses.disabled,
    marks && sliderClasses.marked,
    orientation === 'vertical' && sliderClasses.vertical,
    track === 'inverted' && sliderClasses.trackInverted,
    track === false && sliderClasses.trackFalse,
  ].filter(Boolean).join(' ')

  return (
    <view
      className={rootClasses}
      style={sx ? { ...sx, ...style } : style}
      {...other}
    >
      {/* 轨道 */}
      <view
        className={[classes.rail, sliderClasses.rail].join(' ')}
        bindtap={handleTrackTap}
      />
      
      {/* 已填充轨道 */}
      <view
        className={[classes.track, sliderClasses.track].join(' ')}
        style={{
          [orientation === 'horizontal' ? 'width' : 'height']: `${trackPercent}%`,
        }}
      />
      
      {/* 标记点 */}
      {renderMarks()}
      
      {/* 滑块 */}
      <view
        className={[classes.thumb, sliderClasses.thumb].join(' ')}
        style={{
          [orientation === 'horizontal' ? 'left' : 'bottom']: `${percent}%`,
        }}
        bindtap={handleThumbTap}
        accessibility-element={true}
        accessibility-role="slider"
        accessibility-value={value}
        accessibility-min={min}
        accessibility-max={max}
        accessibility-disabled={disabled}
      />
      
      {/* 值标签 */}
      {valueLabelDisplay !== 'off' && (
        <view
          className={[
            classes.valueLabel,
            sliderClasses.valueLabel,
            valueLabelDisplay === 'on' && sliderClasses.valueLabelOpen,
          ].filter(Boolean).join(' ')}
          style={{
            [orientation === 'horizontal' ? 'left' : 'bottom']: `${percent}%`,
          }}
        >
          <view className={sliderClasses.valueLabelCircle}>
            <text className={sliderClasses.valueLabelLabel}>
              {formatValueLabel(value)}
            </text>
          </view>
        </view>
      )}
    </view>
  )
}

export default Slider
