import React from 'react'

import { View } from '@tarojs/components'

import type { BorderProps, SpaceProps } from '@lx-react-materiel/shared'
import type { ViewProps } from '@tarojs/components'

import { commonStyleFn } from '@lx-react-materiel/shared'

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

import './index.less'

interface ISlotBody {
  slotBody?: React.ReactNode
}

interface ISlotBodyLeftAndRight {
  slotBodyLeft?: React.ReactNode
  slotBodyRight?: React.ReactNode
}

interface ISlotCommonProps {
  slotHeader?: React.ReactNode
}

type ISlotProps = ISlotCommonProps
& ISlotBody
& ISlotBodyLeftAndRight

/**
 * 泛型支持组件 slotBody 和 slotBodyLeft & slotBodyRight 互斥的用法，更好语法提示
 *
 * CurSlotProps extends ISlotProps = ISlotProps 是为了后续不需要在在组件内通过 xx in props 判断。
 *
 * 默认为：第一种，需要传递 slotBodyLeft & slotBodyRight
 *
 * 1. 传递了 slotBody 情况下，那么 slotBodyLeft & slotBodyRight 就不能再传递了。
 * 2. 没传递 slotBody，情况下，那么 slotBodyLeft & slotBodyRight 就是必备字段
 *
 */
type ILxCardProps<CurSlotProps extends ISlotProps = ISlotProps> = CurSlotProps
& ISlotCommonProps
// ViewProps 只用到的部分属性。
& Pick<ViewProps, 'onClick' | 'children' | 'style' | 'className'>
& BorderProps
& SpaceProps

/**
 * 默认props，需要传递 slotBodyLeft & slotBodyRight
 */
export type ILxCardDefaultProps = IRequired<ILxCardProps<ISlotBodyLeftAndRight>, 'slotBodyLeft' | 'slotBodyRight'>

/**
 * 用法2 props：传递 slotBody
 */
export type ILxCardBodyProps = IRequired<ILxCardProps<ISlotBody>, 'slotBody'>

/**
 * 页面 布局 card
 *
 * 默认为：第一种，需要传递 slotBodyLeft & slotBodyRight
 *
 * 1. 传递了 slotBody 情况下，那么 slotBodyLeft & slotBodyRight 就不能再传递了。
 * 2. 没传递 slotBody，情况下，那么 slotBodyLeft & slotBodyRight 就是必备字段
 *
 * @param props
 * @constructor
 * @example
 *
 * // 正常用法
 * <LxCard slotBodyLeft={} slotBodyRight={} />
 *
 * // 传递 slotBody 用法。
 * <LxCard<ILxCardBodyProps> slotBody={} />
 */
export const LxCard = <P extends ILxCardProps = ILxCardDefaultProps>(props: P) => {
  const {
    slotHeader,
    slotBody,
    slotBodyLeft,
    slotBodyRight,
    // 外层基础 props
    style = commonStyleFn(props),
    children,
    className = null,
    ...rest
  } = props

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

  return (
    <View { ...mergeProps }>
      {/* 控制头是否显示 */}
      { slotHeader &&
        <View className='lx-card__header'>
          { slotHeader }
        </View>
      }
      <View className='lx-card__body'>
        { slotBody ?? <>
            <View className='lx-card__body--left'>
              {slotBodyLeft}
            </View>
            <View className='lx-card__body--right'>
              {slotBodyRight}
            </View>
          </>
        }
      </View>
      {/* 控制 footer 显示 */}
      {
        children &&
        <View className='lx-card__footer'>
          {children}
        </View>
      }
    </View>
  )
}
