export type AnyObject = {
  [propName: string]: string | number | boolean | undefined | unknown
}
type IdType = string | number

function itemIsArray(obj: AnyObject): boolean {
  for (const key in obj) {
    if (Array.isArray(obj[key])) {
      return true
    }
  }
  return false
}

function isChange(arr: AnyObject[], arr1: AnyObject[]): boolean {
  if (!arr1) return true
  if (arr.length !== arr1.length) return true
  for (const iterator of arr) {
    const item = arr1.find((item) => item.id === iterator.id)
    if (!item) return true
  }
  return false
}

/**
 * 更新参数处理 只提交更新的
 * @param {UpdateParams} newParams 新的数据
 * @param {UpdateParams} oldParams 旧的数据
 * @param {string} id 数组唯一值
 * @param {Record<string, string>} other 其他属性
 * @param {boolean} bool 是否为布尔值
 * @param {boolean} isBackKeyName 是否将结果返回到xxChange里，针对只有一个list的情况
 */
export function checkUpdateParams(
  newParams: AnyObject,
  oldParams: AnyObject,
  id: string = 'id',
  other: Record<string, string> = {},
  bool: boolean = false,
  isBackKeyName: boolean = true,
): AnyObject | null {
  oldParams = JSON.parse(JSON.stringify(oldParams))
  if (!oldParams) return newParams
  if (newParams[id] !== oldParams?.[id]) return newParams
  const params: AnyObject = {
    [id]: newParams[id],
  }
  for (const key in newParams) {
    if (typeof newParams[key] === 'object') {
      if (Array.isArray(newParams[key])) {
        const arr = newParams[key] as AnyObject[]
        const arr1 = (oldParams[key] as AnyObject[]) || []
        const addList: AnyObject[] = []
        const updateList: AnyObject[] = []
        let removeList: IdType[] = []
        const list: AnyObject[] = []

        const keyname = other[key] || id
        for (const iterator of arr) {
          const obj: AnyObject = {}

          const index = arr1.findIndex(
            (item: AnyObject) => item[keyname] === iterator[keyname],
          )
          const isArray = itemIsArray(iterator)
          if (index !== -1) {
            const item = arr1[index]
            arr1.splice(index, 1)
            for (const key1 in iterator) {
              if (key1 === keyname) continue
              if (Array.isArray(iterator[key1])) {
                if (
                  isChange(
                    iterator[key1] as AnyObject[],
                    item[key1] as AnyObject[],
                  )
                ) {
                  obj[key1] = iterator[key1]
                }
              } else if (iterator[key1] !== item[key1]) {
                obj[key1] = iterator[key1]
              }
            }
            if (Object.keys(obj).length > 0) {
              if (isArray && !bool) {
                list.push({
                  [keyname]: iterator[keyname],
                  ...obj,
                  id: item.id,
                })
              } else {
                updateList.push({
                  [keyname]: iterator[keyname],
                  ...obj,
                  id: item.id,
                })
              }
            }
          } else {
            if (isArray && !bool) {
              list.push(iterator)
            } else {
              addList.push(iterator)
            }
          }
        }
        if (arr1.length > 0) {
          removeList = arr1.map((item) => item['id'] as IdType)
        }
        if (isBackKeyName) {
          // 将列表直接添加到 params 顶层
          if (addList.length > 0) params['addList'] = addList || undefined
          if (updateList.length > 0)
            params['updateList'] = updateList || undefined
          if (removeList.length > 0)
            params['removeList'] = removeList || undefined
          if (list.length > 0) params['list'] = list || undefined
        } else {
          const key_name = key.replace('List', 'Change')
          params[key_name] = {}
          if (addList.length > 0) {
            ;(params[key_name] as AnyObject).addList = addList
          }
          if (updateList.length > 0) {
            ;(params[key_name] as AnyObject).updateList = updateList
          }
          if (removeList.length > 0) {
            ;(params[key_name] as AnyObject).removeList = removeList
          }
          if (list.length > 0) {
            params[key_name] = list
          }
          if (Object.keys(params[key_name] as object).length === 0) {
            delete params[key_name]
          }
        }
      }
    } else {
      // 基础信息
      params[key] = newParams[key]
    }
  }
  if (Object.keys(params).length === 1) {
    return null
  }
  return params
}
