import { reactive, computed, watch, ref, unref, isRef, nextTick } from 'vue'
import useFetch from '@/hooks/useFetch'
import useMainStore from '@/store/main'
import { ExtractApiResponse } from '@/api/api'
import { useRoute } from 'vue-router'
import type { Ref } from 'vue'

export interface DataModel {
  subject?: string
  question?: number | string
  group?: any
}

interface Group {
  label: string
  value: any
}

type QuestionList = ExtractApiResponse<'getMainQuestionList'>[0] & {
  label: string
  value: number
}

const useOptions = (
  types: (keyof DataModel)[],
  initModel?: DataModel | Ref<DataModel>,
  autoFill = true,
  subjectEnable: boolean | null = true,
  multGroup = false,
  isAiCheck = false,
  showAllLabel = true
) => {
  const mainStore = useMainStore()
  const route = useRoute()
  const _subjectCode = (route.query?._subjectCode || '') as string
  const _questionMainNumber = Number(route.query?._questionMainNumber || '')
  const userInfo = computed(() => {
    return mainStore?.myUserInfo
  })

  const isAdmin = computed(() => {
    return userInfo?.value?.role === 'ADMIN'
  })

  const isChief = computed(() => {
    return userInfo?.value?.role === 'CHIEF'
  })

  const isExpert = computed(() => {
    return userInfo?.value?.role === 'EXPERT'
  })

  const isLeader = computed(() => {
    return userInfo?.value?.role === 'SECTION_LEADER'
  })

  const isDeputy = computed(() => {
    return userInfo?.value?.role === 'DEPUTY'
  })

  const dataModel = reactive<DataModel>(unref(initModel) || {})

  if (isRef(initModel)) {
    watch(
      initModel,
      () => {
        Object.assign(dataModel, unref(initModel))
      },
      { deep: true }
    )
  }

  const changeModelValue = <T extends keyof DataModel>(key: T) => {
    return (v: DataModel[T]) => {
      console.log('changeModelValue', key, v)
      // dataModel[key] = v
      if (multGroup && showAllLabel && key === 'group') {
        if (v.includes(undefined)) {
          if (dataModel[key]?.length === groupListWithAll.value.length) {
            //说明了原本是全选状态，取消勾选了某个不是“全部”的选项
            dataModel[key] = v.filter((item: any) => !!item)
          } else {
            //说明原本是非全选状态，而点击后包含了“全部”选项， 那么就触发全部勾选逻辑
            dataModel[key] = groupListWithAll.value.map((item: any) => item.value)
          }
        } else {
          if (v?.length === groupListWithAll.value.length - 1 && dataModel[key]?.includes(undefined)) {
            //说明在全部勾选的情况下，点了“全部”，则要全部取消勾选;
            dataModel[key] = []
          } else if (v?.length === groupListWithAll.value.length - 1) {
            //说明了在没有点击“全部”的情况下，逐步勾选完了除了“全部”以外的所有选项，那么就要出发全部勾选逻辑，同时给“全部”自动加上勾选
            dataModel[key] = groupListWithAll.value.map((item: any) => item.value)
          } else {
            dataModel[key] = v.filter((item: any) => !!item)
          }
        }
      } else {
        dataModel[key] = v
      }
    }
  }

  const { fetch: getSubjectList, result: subjectResult } = useFetch('getSubjectList')

  const {
    fetch: getMainQuestionList,
    result: mainQuestionListResult,
    reset: resetQuestionFetch,
  } = useFetch('getMainQuestionList')

  const {
    fetch: getQuestionGroupList,
    result: groupListResult,
    reset: resetGroupList,
  } = useFetch('getQuestionGroupList')

  const subjectList = computed(() => {
    // const arr: any =
    //   subjectResult.value?.result?.map((subject) => {
    //     return { ...subject, value: subject.code, label: `${subject.code}-${subject.name}` }
    //   }) || []
    // if (isExpert.value) {
    //   arr.unshift({ label: '全部', value: void 0 })
    // }
    // return arr
    return (
      subjectResult.value?.result?.map((subject) => {
        return { ...subject, value: subject.code, label: `${subject.code}-${subject.name}` }
      }) || []
    )
  })

  const mainQuestionList = computed<any[]>(() => {
    // const arr =
    //   mainQuestionListResult.value?.map((v: any) => {
    //     return {
    //       ...v,
    //       label: `${v.mainNumber}-${v.title}`,
    //       value: v.mainNumber,
    //     }
    //   }) || []
    // if (isExpert.value || isLeader.value) {
    //   arr.unshift({ label: '全部', value: void 0 })
    // }
    // return arr

    return (
      mainQuestionListResult.value?.map((v: any) => {
        return {
          ...v,
          label: `${v.mainNumber}-${v.title}`,
          value: v.mainNumber,
        }
      }) || []
    ).filter((v: any) => {
      if (isAiCheck) {
        return !!v.relationMainNumber
      } else {
        return v
      }
    })
  })

  const groupList = computed<Group[]>(() => {
    return (
      groupListResult?.value?.map((n) => {
        return {
          value: n,
          label: `第${n}组`,
        }
      }) || []
    )
  })

  const groupListWithAll = computed(() => {
    return groupList.value?.length &&
      (isAdmin.value || isChief.value || isExpert.value || isLeader.value) &&
      showAllLabel
      ? [{ label: '全部', value: void 0 } as unknown as Group].concat(groupList.value)
      : groupList.value
  })

  watch(
    userInfo,
    () => {
      if (!dataModel.subject && userInfo.value?.subjectCode) {
        dataModel.subject = userInfo.value.subjectCode
      }
      if (!dataModel.question && userInfo.value?.mainNumber) {
        dataModel.question = userInfo.value.mainNumber
      }

      if (!dataModel.group && userInfo.value?.markingGroupNumber && !(isAdmin.value || isChief.value)) {
        dataModel.group = multGroup
          ? userInfo.value.markingGroupNumber
            ? [userInfo.value.markingGroupNumber]
            : []
          : userInfo.value.markingGroupNumber
      }
    },
    { immediate: true }
  )

  watch(
    () => dataModel.subject,
    () => {
      if (types.includes('question') && dataModel.subject) {
        // resetQuestionFetch()
        // resetGroupList()
        // changeModelValue('question')(void 0)
        // changeModelValue('group')(void 0)
        getMainQuestionList({ subjectCode: dataModel.subject })
        // dataModel.question = undefined
      }
    },
    { immediate: true }
  )

  const watchQuestionHandle = () => {
    if (types.includes('group') && dataModel.subject && dataModel.question) {
      // resetGroupList()
      // changeModelValue('group')(void 0)
      getQuestionGroupList({ subjectCode: dataModel.subject, mainNumber: dataModel.question }).then((res: any) => {
        changeModelValue('group')(
          multGroup && showAllLabel
            ? groupList.value?.length && (isAdmin.value || isChief.value || isExpert.value || isLeader.value)
              ? // ? [void 0]
                []
              : []
            : void 0
        )
      })
    }
  }
  watch(
    // [() => dataModel.question, () => dataModel.question],
    () => dataModel.question,
    () => {
      watchQuestionHandle()
    },
    { immediate: true }
  )

  if (autoFill) {
    watch(
      [subjectList, userInfo],
      () => {
        if (userInfo.value?.subjectCode && !dataModel.subject) {
          changeModelValue('subject')(userInfo.value?.subjectCode)
        }
        //如果是专家进来，则用户信息里的subjectCode是没值的，这种情况，给专家默认选择科目列表里的第一个科目
        if (userInfo.value?.role === 'EXPERT' && !userInfo.value?.subjectCode) {
          if (subjectList.value.length) {
            changeModelValue('subject')(_subjectCode || subjectList.value[0].value)
          }
        }
      },
      { deep: true }
    )
    watch(
      [mainQuestionList, userInfo],
      () => {
        if (userInfo.value?.mainNumber && !dataModel.question) {
          changeModelValue('question')(userInfo.value?.mainNumber)
        }
        if (
          (userInfo.value?.role === 'EXPERT' || userInfo.value?.role === 'SECTION_LEADER') &&
          !userInfo.value?.mainNumber
        ) {
          if (mainQuestionList.value.length) {
            const oldQuestionNumber = dataModel.question
            changeModelValue('question')(_questionMainNumber || mainQuestionList.value[0].value)
            if (oldQuestionNumber == mainQuestionList.value[0].value) {
              //防止切换科目前的大题号和切换科目后的大题号相同，watch question监听不执行
              watchQuestionHandle()
            }
          }
        }
      },
      { deep: true }
    )
    watch(
      [groupList, userInfo, isAdmin, isChief],
      () => {
        if (userInfo.value?.markingGroupNumber && !dataModel.question && !(isAdmin.value || isChief.value)) {
          changeModelValue('group')(
            multGroup
              ? userInfo.value?.markingGroupNumber
                ? [userInfo.value?.markingGroupNumber]
                : []
              : userInfo.value?.markingGroupNumber
          )
        }
      },
      { deep: true }
    )
  }

  const initFinish = ref<boolean>(false)

  const destroyInit = watch(
    [dataModel, isAdmin, isChief],
    () => {
      if (
        types.every((t) => {
          return (
            (Array.isArray(dataModel[t]) ? dataModel[t].length > 0 : !!dataModel[t]) ||
            (t === 'group' && (isAdmin.value || isChief.value || isExpert.value || isLeader.value))
          )
        })
      ) {
        nextTick(() => {
          initCallbacks.forEach((cb) => cb(dataModel))
          initFinish.value = true
          destroyInit()
        })
      }
    },
    { immediate: true }
  )

  const initCallbacks: ((d: DataModel) => void)[] = []

  const onOptionInit = (cb: (d?: DataModel) => void) => {
    initCallbacks.push(cb)
  }

  const forceRefresh = () => {
    getSubjectList({ pageNumber: 1, pageSize: 9999, enable: subjectEnable || void 0 })
  }

  if (types.includes('subject')) {
    forceRefresh()
  }

  return {
    getMainQuestionList,
    getQuestionGroupList,
    subjectList,
    mainQuestionList,
    groupList,
    groupListWithAll,
    dataModel,
    initFinish,
    onOptionInit,
    changeModelValue,
    forceRefresh,
    isExpert,
    isLeader,
    isDeputy,
  }
}

export default useOptions
