import type { MjModalProps } from '../mj-table/const'

import str from '#/utils/str'

import { mj_table_select } from '../mj-table/const'

export type SetSelectedItems = {
  items: any
  valueKey?: any
}

export type MjTableSelectMethods = {
  getSelectedItems: () => any[]
  reset: (val?: any, force?: boolean) => any
  setSelectedItems: (val: SetSelectedItems) => void
  show: () => void
  updateProps: (val: any) => void
}

export type MjTableSelectItemProps = {
  _methods?: MjTableSelectMethods
  cmp: any
  cmpProps?: any
  disabled?: any
  modal: MjModalProps
  multiSelectable?: any
  selectChange?: (items: any, value: any, label: any) => void
  selectedItems?: any
  title?: (item: any) => any
}

export type MjTableSelectRenderOpts = {
  // 修改外面的props，内部属性会实时更新
  props: MjTableSelectItemProps
}

// 设置数据
type SetDataFn = (data: any, items: any, value: any, label: any) => void
export type RenderChange = (items: any, value: any, label: any) => void

type PrepareParams = {
  fixedName?: any
  gridRef: any
  props?: any
}

export type ItemRenderParams = {
  change?: RenderChange
  cmp?: any
  getData?: () => any
  nextRender?: any
  prepare?: PrepareParams
  props?: any
  setData?: SetDataFn
}

function fixedNameProps(fixedName: any, props: any) {
  const id = props[`${fixedName}Id`]
  const name = props[`${fixedName}Name`]
  const obj = {} as any
  if (id) {
    obj.selectedItems = {
      id,
      name,
    }
  }
  const disabled = props[`fixed${str.capitalize(fixedName)}`]
  if (disabled !== undefined) {
    obj.disabled = disabled
  }
  return obj
}

function refreshFixedProps(props: any, fixedName: any) {
  let obj = undefined as any
  if (props && fixedName) {
    if (Array.isArray(fixedName)) {
      // 数组
      obj = [] as any
      for (const item of fixedName) {
        obj.push(fixedNameProps(item, props))
      }
    } else {
      // 非数组
      obj = fixedNameProps(fixedName, props)
    }
  }
  return obj
}

export function parsePrepareParams(params?: ItemRenderParams) {
  if (!params?.prepare) {
    return
  }
  const data = params.prepare
  let { gridRef } = data
  if (typeof gridRef === 'function') {
    gridRef = gridRef()
  }
  const res = {
    getData: () => gridRef.value.getEditFormData(),
    change: () => gridRef.value.reload(),
    props: refreshFixedProps(data.props, data.fixedName),
  }

  // 预备参数
  params.getData = params.getData || res.getData
  params.change = params.change || res.change
  params.props = {
    ...params.props,
    ...res.props,
  }
}

// 刷新下一个关联的渲染器
export function refreshNextRender(render: any, setDataFn: any, value: any) {
  if (!Array.isArray(render)) {
    render = [render]
  }
  for (const item of render) {
    // 设置参数
    setDataFn && setDataFn(item.props.cmpProps)
    item.props.disabled = !value
    // 清空选择框
    item.props._methods?.reset()
  }
}

export function useItemRender(params: ItemRenderParams) {
  let { change, cmp, getData, nextRender, props, setData } = params
  const render = {
    name: mj_table_select,
    props: {
      cmp: markRaw(cmp),
      selectChange(items: any, value: any, label: any) {
        if (getData && setData) {
          const data = getData()
          if (Array.isArray(data)) {
            data.forEach((item) => setData(item, items, value, label))
          } else {
            setData(data, items, value, label)
          }
        }

        change && change(items, value, label)

        if (nextRender) {
          if (!Array.isArray(nextRender)) {
            nextRender = [nextRender]
          }
          for (const render of nextRender) {
            // 下一个渲染器
            refreshNextRender(
              render,
              (item: any) => {
                setData && setData(item, items, value, label)
              },
              value,
            )
            // // 设置参数
            // setDataFn && setDataFn(render.props.cmpProps, items, value, label)
            // render.props.disabled = !value
            // // 清空选择框
            // render.props._methods?.reset()
          }
        }
      },
      ...props,
      modal: { title: '请选择', height: 800, ...props?.modal },
    } as MjTableSelectItemProps,
  }

  // 监听外面的props
  if (params.prepare?.fixedName) {
    watch(
      () => params.prepare?.props,
      (val) => {
        if (!val) return
        const fn = render.props._methods?.updateProps
        if (fn) {
          fn(refreshFixedProps(val, params.prepare?.fixedName))
        }
      },
      {
        deep: true,
      },
    )
  }
  return render
}
