import { Condition } from "../../components/table/SecondFilter/types"
import { sortFn, filterFn } from "../../utils/utils"
import { numberFormatter } from "../../utils/helper"
import { IColumn as ITableColumn } from "../table"
import { IColumn as IBiTableColumn } from "../lionBiTable"
import { DATAKEYID } from "../crud"
import union from 'lodash/union'
import intersection from 'lodash/intersection'
import { isNil } from "lodash"

type IColumn = ITableColumn | IBiTableColumn

export const CROSS_SPLIT_CHAR = '·'

export function handleSort(items: any[], columnNames: string[], orderMap: Map<string, { order?: 'asc' | 'desc', map?: object }>, modifiedData?: any) {
  if (columnNames.length > 0) {
    const name = columnNames.pop() ?? ''
    items = items.sort((pre, next) => {
      const map = orderMap.get(name)?.map
      const order = orderMap.get(name)?.order
      // 如果有编辑数据 用编辑数据排序 否则用正常的数据排序
      // 判断字段类型是否是map,是的话取map值来排序
      const preData = modifiedData?.[pre[DATAKEYID]] ? modifiedData[pre[DATAKEYID]]?.[name] : map ? map[pre[name]] : pre[name]
      const nextData = modifiedData?.[next[DATAKEYID]] ? modifiedData[next[DATAKEYID]]?.[name] : map ? map[next[name]] : next[name]
      return sortFn(preData, nextData, order)
    })
    handleSort(items, columnNames, orderMap, modifiedData)
  }
  return items
}

export function handleFilter(items: any[], columnNames: string[], filterMap: Map<string, { condition: Condition, value1?: string, value2?: string, value3?: string, relation?: 'and' | 'or' }[]>, caseSensitive = false) {
  if (columnNames.length > 0) {
    const name = columnNames.pop() ?? ''
    const filters = filterMap.get(name)
    if (filters) {
      let temps: any[] = []
      for (let i = 0; i < filters.length; i++) {
        const filter = filters[i]
        const relation = filters[i - 1]?.relation
        const arr = filterFn(items.slice(), name, filter.condition, filter.value3 ?? filter.value1, filter.value2, caseSensitive)
        if (relation == 'and') {
          temps = intersection(temps, arr)
        } else if (relation == 'or') {
          temps = union(temps, arr)
        } else {
          temps = arr
        }
      }
      items = handleFilter(temps, columnNames, filterMap)
    }
  }
  return items
}

export function getHeadRows(filtedColumns: IColumn[]) {
  if (filtedColumns.length <= 0) return []
  const groupNames = filtedColumns.map(column => column.groupName.length > 0 ? column.groupName.split(',').length : 0)
  const level = Math.max(...groupNames) + 1
  const columns = filtedColumns.map((column, index) => {
    if (column.type == '__checkme' || column.type == '__expandme' || column.type == '__pseudoColumn') {
      const name = column.type == '__checkme' ? 'SF_CHECK' : 'SF_PSEUDO'
      return { ...column, name: name, groupName: new Array(level - 1).fill(name).join(',') }
    }
    const emptyName = '空' + (index || '')
    return { ...column, name: column.name || emptyName, groupName: level >= 2 ? column.groupName || (column.name ?? emptyName) : '' }
  })
  const calc = (fieldIndex: string | number, set: Set<string>) => {
    const tr: { name: string, label: string, colspan: number, rowspan: number, column: IColumn }[] = []
    for (let i = 0; i < columns.length; i++) {
      const current = columns[i]
      const fieldValue = typeof fieldIndex == 'string' ? current.name ?? current.type : current.groupName.split(',')[fieldIndex]
      const groupLabels = current.pristine.groupLabels ?? []
      const rowspan = (current.name == fieldValue ? 1 : 0) + current.groupName.split(',').reduce((p, c) => { if (c === fieldValue) { p += 1 }; return p }, 0)
      const arr = fieldValue.split(CROSS_SPLIT_CHAR)
      const label = (groupLabels.length > 0 ? groupLabels[fieldIndex] : arr[arr.length - 1]) || arr[arr.length - 1]
      const th = { name: fieldValue, label: label, colspan: 1, rowspan: rowspan, column: current }
      for (let j = i + 1; j < columns.length; j++) {
        const next = columns[j]
        const nextFieldValue = typeof fieldIndex == 'string' ? next.name! : next.groupName.split(',')[fieldIndex]
        if (fieldValue === nextFieldValue) {
          th.colspan = th.colspan + 1
        } else {
          break
        }
      }
      const last = tr[tr.length - 1]
      if (!(last && last.name === th.name) && !set.has(th.name)) {
        tr.push(th)
      }
    }
    return tr
  }
  const fieldNames = new Array(level).fill(true).map((_, index) => index == 0 ? 'name' : index - 1).reverse()
  const rows: { name: string, label: string, colspan: number, rowspan: number, column: IColumn }[][] = []
  const alreadyFieldSet: Set<string> = new Set()
  for (const fieldName of fieldNames) {
    const th = calc(fieldName, alreadyFieldSet)
    th.forEach(item => alreadyFieldSet.add(item.name))
    rows.push(th)
  }
  return rows
}

export function getCellValue(originValue: any, column?: IColumn, clearFormat: boolean = false, isCopyCell?: boolean) {
  let value = originValue
  const prefix = column?.pristine.prefix ?? ''
  const suffix = column?.pristine.suffix ?? ''
  if (column?.type === 'mapping') {
    value = column?.map?.[originValue] ?? (originValue ?? '')
  } else if (column?.type === 'number') {
    if (isNil(value)) return ''
    // 不需要清空格式化的逻辑
    if (!clearFormat) {
      const kilobitSeparator = column?.pristine.kilobitSeparator ?? false
      const precision = column?.pristine.precision
      if (kilobitSeparator && originValue != null) {
        value = numberFormatter(originValue, precision)
      } else if (originValue != null && typeof originValue == 'number') {
        value = originValue.toFixed(precision)
      }
      return `${prefix || ''}${value}${suffix || ''}`
    } else {
      // 需要清空格式化的逻辑
      if (suffix === '%') {
        // 如果是百分比的逻辑
        value = isNil(originValue) ? originValue : originValue / 100
      }
      return value
    }
  }
  if (value != null) {
    return typeof value == 'object' ? '[文件]' : `${clearFormat ? '' : prefix}${typeof value == 'string' && !isCopyCell ? value.replace(/\n|\r|<[^>]*>/g, '') : value}${clearFormat ? '' : suffix}`
  }
  return ''
}