import { BasicTableProps, ColumnProps, Pagination } from '@/types/table'
import type { ComputedRef } from 'vue'
import { computed, Ref, ref, reactive, toRaw, unref, watch } from 'vue'
import { checkPermi } from '@/utils/permission'
import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
import { isArray, isBoolean, isFunction } from '@/utils/is'
import { cloneDeep } from 'lodash-es'

import { DEFAULT_ALIGN, INDEX_COLUMN_FLAG, PAGE_SIZE } from '../src/const'


const { wsCache } = useCache()
//生成序号列
function handleIndexColumn(
  propsRef: ComputedRef<BasicTableProps>,
  getPaginationRef: ComputedRef<Pagination>,
  columns: ColumnProps[]
) {
  const { showIndexColumn, indexColumnProps, reserveSelection, headerAlign } = unref(propsRef)

  let pushIndexColumns = false, indIndex;

  columns.forEach(() => {
    indIndex = columns.findIndex((column) => column.type === INDEX_COLUMN_FLAG)
    if (showIndexColumn) {
      pushIndexColumns = indIndex === -1
    } else if (!showIndexColumn && indIndex !== -1) {
      columns.splice(indIndex, 1)
    }
  })

  if (!pushIndexColumns) return

  const isFixedLeft = columns.some((item) => item.fixed === 'left')
  const getPagination = unref(getPaginationRef)
  const { currentPage = 1, pageSize = PAGE_SIZE } = getPagination

  columns.unshift({
    type: INDEX_COLUMN_FLAG,
    width: 70,
    label: '序号',
    align: 'center',
    reserveSelection,
    headerAlign,
    index: columns[indIndex]?.index ? columns[indIndex].index : (index: number) => ((currentPage < 1 ? 1 : currentPage) - 1) * pageSize + index + 1,
    ...(isFixedLeft
      ? {
        fixed: 'left'
      }
      : {}),
    ...indexColumnProps
  })

  //找到type='selection'的在插入到序号前面
  const selectionIdx = columns.findIndex((item) => item?.type === 'selection');
  let selectionColunm = columns.splice(selectionIdx, 1)
  if (selectionIdx >= 0) {
    columns.unshift({
      prop: '',
      type: 'selection',
      selectable: selectionColunm[0].selectable,
      reserveSelection: selectionColunm[0].reserveSelection,
      label: '全选',
      fixed: 'left'
    })

  }


}


function sortFixedColumn(columns: ColumnProps[]) {
  const fixedLeftColumns: ColumnProps[] = []
  const fixedRightColumns: ColumnProps[] = []
  const defColumns: ColumnProps[] = []
  for (const column of columns) {
    if (column.fixed === 'left') {
      fixedLeftColumns.push(column)
      continue
    }
    if (column.fixed === 'right') {
      fixedRightColumns.push(column)
      continue
    }
    defColumns.push(column)
  }
  return [...fixedLeftColumns, ...defColumns, ...fixedRightColumns].filter((item) => !item.defaultHidden)
}


export function useColumns(propsRef: ComputedRef<BasicTableProps>, getPaginationRef: ComputedRef<boolean | Pagination>) {
  const columnsRef = ref(unref(propsRef).columns) as unknown as Ref<ColumnProps[]>
  let cacheColumns = unref(propsRef).columns;
  let localColumns = ref<any[] | null>(null)




  const getColumnsRef = computed(() => {
    const columns = cloneDeep(unref(columnsRef))

    handleIndexColumn(propsRef, getPaginationRef as ComputedRef<Pagination>, columns)
    if (!columns) {
      return []
    }

    columns.forEach((item) => {
      item.align = item.align || DEFAULT_ALIGN;
    })

    return columns
  })

  const getCacheColumnsRef = computed(() => {
    const columns = cloneDeep(unref(localColumns))
    if (!columns) {
      return []
    }
    handleIndexColumn(propsRef, getPaginationRef as ComputedRef<Pagination>, columns)

    columns.forEach((item) => {
      item.align = item.align || DEFAULT_ALIGN;
    })
    return columns
  })

  //判断是否可见
  function isIfShow(column: ColumnProps): boolean {
    const ifShow = column.ifShow

    let isIfShow = true

    if (isBoolean(ifShow)) {
      isIfShow = ifShow
    }
    if (isFunction(ifShow)) {
      isIfShow = ifShow(column)
    }
    return isIfShow
  }

  const getViewColumns = computed(() => {
    const viewColumns = localColumns.value ? sortFixedColumn(unref(getCacheColumnsRef)) : sortFixedColumn(unref(getColumnsRef))

    const columns = cloneDeep(viewColumns);

    return columns.filter(column => isIfShow(column) && checkPermi(column.auth))

  })


  //监听columns改变
  watch(
    () => unref(propsRef).columns,
    (columns) => {
      columnsRef.value = columns
      cacheColumns = columns
      //cacheColumns = columns?.filter((item) => !item.type && item.prop!='action') ?? []
    }
  )

  watch(
    () => unref(propsRef).tableKey,
    () => {
      const temColumn = wsCache.get(CACHE_KEY.COLUMNS);
      if (temColumn && temColumn[unref(propsRef).tableKey] && Array.isArray(temColumn[unref(propsRef).tableKey])) {
        localColumns.value = temColumn[unref(propsRef).tableKey]
      } else {
        localColumns.value = null
      }
    }
  )

  //设置列
  function setColumns(columnList: Partial<ColumnProps>[] | (string | string[])[]) {
    const columns = cloneDeep(columnList)
    if (!isArray(columns)) return
    if (columns.length <= 0) {
      columnsRef.value = []
      return
    }
    columnsRef.value = columns as ColumnProps[]
  }

  function setLocalColumns(columns: ColumnProps[]) {
    if (!isArray(columns)) return
    localColumns.value = columns
  }

  //获取列
  function getColumns() {
    let columns = toRaw(unref(getColumnsRef))
    return columns
  }
  function getCacheColumns() {
    return cacheColumns.filter(column => isIfShow(column) && checkPermi(column.auth))
  }
  function setCacheColumns(columns: ColumnProps[]) {
    if (!isArray(columns)) return
    //cacheColumns = columns.filter((item) => !item.type)
    cacheColumns = columns
  }

  return {
    getColumnsRef,
    getCacheColumns,
    getColumns,
    setColumns,
    getViewColumns,
    setCacheColumns,
    setLocalColumns
  }

}

