import React from 'react'

import type { ViewProps } from '@tarojs/components'
import { View } from '@tarojs/components'

import type { PaddingProps, MarginProps, BackgroundProps, BorderRadiusProps, BorderProps } from '@lx-react-materiel/shared'
import { commonStyleFn } from '@lx-react-materiel/shared'

import { LxText } from '../lxText'

import { type Required as IRequired } from 'utility-types'

import './index.less'

// ViewProps 只用到的部分属性。
type PickViewProps = Pick<ViewProps, 'className' | 'style'>

// LxItem 属性合集。
interface LxItemProps extends PaddingProps, MarginProps, BackgroundProps, BorderRadiusProps, BorderProps, PickViewProps {
  // left
  label?: string
  leftColor?: string
  leftSize?: number

  // right
  value?: string | number
  rightColor?: string
  rightSize?: number
  valueOnClick?: Pick<ViewProps, 'onClick'>['onClick']

  // slot
  slotLeft?: React.ReactNode
  slotRight?: React.ReactNode
}

/**
 * 仅仅有 slot 用法
 * slotLeft & slotRight 是必备属性
 * 其他属性是可选属性
 */
export type IOnlySlot = IRequired<Pick<LxItemProps, 'slotLeft' | 'slotRight' | 'padding' | 'background' | 'borderRadius'>, 'slotLeft' | 'slotRight'>

/**
 * 传递 slotLeft 场景
 * slotLeft & value 是必备属性，其他是可选属性
 */
export type IOnlySlotLeft = IRequired<Omit<LxItemProps, 'label' | 'leftColor' | 'leftSize' | 'slotRight'>, 'slotLeft' | 'value'>

/**
 * 传递 slotRight 场景
 * slotRight & label 是必备属性，其他是可选属性
 */
export type IOnlySlotRight = IRequired<Omit<LxItemProps, 'value' | 'rightColor' | 'rightSize' | 'valueOnClick' | 'slotLeft'>, 'slotRight' | 'label'>

/**
 * 没有 slot 场景。默认
 * label & value 是必备属性，其他是可选属性
 */
export type INotSlot = IRequired<Omit<LxItemProps, 'slotLeft' | 'slotRight'>, 'label' | 'value'>

/**
 * @param props
 * @constructor
 * @example
 * // 没有 slot
 * <LxItem label='支付方式' leftColor='#666' value='微信支付' rightColor='#333' background='#fff' padding='' borderRadius={30} valueOnClick={() => console.log('click')}></LxItem>
 *
 * // 只传递了 slot left
 * <LxItem<IOnlySlotLeft> slotLeft={<Text>12312</Text>} value='微信支付' rightColor='#333' background='#fff' padding='' borderRadius={30} valueOnClick={() => console.log('click')}></LxItem>
 *
 * // 只传递了 slot right
 * <LxItem<IOnlySlotRight> label='只传递了 slot right' leftColor='#666' slotRight={<Text>slot right value</Text>}  background='#fff' padding='' borderRadius={30}></LxItem>
 *
 * // 传递了slotLeft & slotRight
 * <LxItem<IOnlySlot> slotLeft={<Text>12312</Text>} slotRight={<Text>slot right value</Text>}  background='#fff' padding='' borderRadius={30}></LxItem>
 */
export function LxItem<P extends LxItemProps = INotSlot> (props: P) { // 没有 slot
  const {
    // left props
    label = '',
    leftColor = '#12151B',
    leftSize = 26,

    // right props
    value = '',
    rightColor = '#464D5A',
    rightSize = 26,
    valueOnClick,

    // slot props
    slotLeft,
    slotRight,

    // style prop
    style = commonStyleFn(props),
    className = null,
    ...rest
  } = props

  // 基础属性。
  const mergeProps = {
    ...rest,
    className: `lx-item ${className ?? ''}`,
    style
  }

  return (
    <View { ...mergeProps }>
      { slotLeft ?? <LxText className='lx-item__left' fontSize={leftSize} color={leftColor}>{label}</LxText> }
      { slotRight ?? <LxText className='lx-item__right' onClick={valueOnClick} fontSize={rightSize} color={rightColor} >{value}</LxText> }
    </View>
  )
}

// 设置一下属性默认值
// style 属性因为需要 compose 计算，不方便在 props 上进行赋值
// 注意：style 属性不能带上 rpx 单位
LxItem.defaultProps = {
  background: '#fff',
  borderRadius: 16
}
