import styles from '@/pages/order/trans-recode/trans-recode.module.styl'
import { defineComponent } from 'vue'
import Utils from '@/common/utils'
import type { TableColumnCtx } from 'element-plus'
import {
  ElCheckbox,
  ElTable,
  ElTableColumn,
} from 'element-plus'
import { type SummaryMethodProps } from '@/components/a-page/a-table-page/build-summary-method.ts'
import { summaryMethod } from '@/pages/order/constants.ts'

interface TransRecode {
  transRecodes: OrderTypes.TransRecode[]
  selectable: boolean
  disabledRowsMethod: (rows?: OrderTypes.TransRecode[]) => string[] | undefined
  moduleValue: string[]
  'onUpdate:moduleValue': (value: string[]) => void
  summaryMethod?: (data: SummaryMethodProps<OrderTypes.TransRecode>) => (string | VNode)[]
}

const component = defineComponent(
  (props: TransRecode, ctx) => {
    const transRecodes = computed(() => {
      return props.transRecodes ?? []
    })
    const selectRows = Utils.resetAble(reactive<string[]>([]))
    const disabledRows = computed(() => {
      const transRecodes_ = transRecodes.value
      return props.disabledRowsMethod(transRecodes_) ?? []
    })
    const selectHeader_indeterminate = computed(() => {
      return selectRows.length > 0 && selectRows.length < transRecodes.value.length
    })
    const selectHeader_checked = computed({
      get() {
        return selectRows.length > 0 && transRecodes.value.length > 0 && selectRows.length === transRecodes.value.length
      },
      set(val) {
        if (val) {
          const newData = transRecodes.value.map(it => it.id)
          selectRows.$reset([ ...new Set([ ...selectRows, ...newData ]) ] as string[])
        } else {
          const newData = transRecodes.value.map(it => it.id)
          selectRows.$reset(selectRows.filter(it => !newData.includes(it)))
        }
        ctx.emit('update:moduleValue', selectRows.$clone())
      },
    })

    const rowClick = (row: Record<string, any> & { id: string }, column: TableColumnCtx) => {
      if (!props.selectable || column.property === 'tableAction' || disabledRows.value.includes(row.id)) {
        return
      }
      const indexOf = selectRows.indexOf(row.id)
      if (indexOf === -1) {
        selectRows.push(row.id)
      } else {
        selectRows.splice(indexOf, 1)
      }
      ctx.emit('update:moduleValue', selectRows.$clone())
    }

    return () => (<ElTable
      cell-class-name="table-cell"
      empty-text="暂无数据"
      header-row-class-name="table-header"
      row-key="id"
      data={transRecodes.value}
      class={[ 'data-table', props.selectable ? styles.selectable : '' ]}
      summary-method={props.summaryMethod}
      show-summary={props.summaryMethod != null}
      onRow-click={rowClick}>
      {{
        default: () => {
          const columns = ctx.slots.default?.() ?? []
          if (props.selectable) {
            columns.unshift(<ElTableColumn width="50">
              {{
                default: ({row}: { row: OrderTypes.TransRecode }) => {
                  return (<ElCheckbox model-value={selectRows.includes(row.id ?? '')} disabled={disabledRows.value.includes(row.id ?? '')}/>)
                },
                header: () => {
                  return (<ElCheckbox
                    disabled={disabledRows.value.length === transRecodes.value.length}
                    modelValue={selectHeader_checked.value}
                    onUpdate:modelValue={(val) => {
                      selectHeader_checked.value = val as boolean
                    }}
                    indeterminate={selectHeader_indeterminate.value}/>)
                },
              }}
            </ElTableColumn>)
          }
          return columns
        },
      }}
    </ElTable>)
  },
  {
    name: 'TransRecode',
    props: [ 'transRecodes', 'selectable', 'disabledRowsMethod', 'summaryMethod', 'moduleValue' ],
    emits: [ 'update:moduleValue' ],
  },
)

type BuildTransRecodePropsParam = DeepPartial<Exclude<TransRecode, 'summaryMethod' | 'transRecodes'>> & {
  enableSummary?: boolean
}

export function buildTransRecodeProps({
                                        selectable,
                                        moduleValue,
                                        enableSummary = false,
                                        disabledRowsMethod,
                                        ['onUpdate:moduleValue']: onUpdateModuleValue,
                                      }: BuildTransRecodePropsParam,
) {
  const props = reactive({
    selectable: selectable ?? false,
    moduleValue: moduleValue ?? [],
    'onUpdate:moduleValue': onUpdateModuleValue ?? (value => {
      props.moduleValue = value
    }),
    disabledRowsMethod: disabledRowsMethod ?? (() => []),
    summaryMethod: enableSummary ? summaryMethod : undefined,
  })
  return props
}

export default component
