import { Commit, Dispatch } from './index'
import {
  useFetchOrg,
  useFetchMember,
  useFetchAuth,
  useFetchUser,
  useFetchOrgAuth,
  useFetchMenus,
  useFetchBuilding,
  useFetchRoom,
} from '@/hooks/useFetch'
import dayjs from '@/util/dayjs'
import state from './state'

interface Method {
  commit: Commit
  dispatch: Dispatch
}

export default {
  /** 获取权限编码 */
  async getAuth({ commit }: Method) {
    if (process.env.NODE_ENV !== 'production') {
      /* 开发环境、测试环境用 */
      commit('SET_AUTH', {
        userid: 91541,
        orgid: '000001',
        code: '001.001.031.014.205', // 最高权限
        // code: '001.001.031.014.205.001', // 行政党组
        // code: '001.001.031.014.205.002', // 社区党委
        // code: '001.001.031.014.205.002.001', //牡丹社区委员会
        // code: '001.001.031.014.205.002.001.601', // 牡丹第一居民区总支部委员会
        // code: '001.001.031.014.205.002.007', // 杉杉控股
        // code: '001.001.031.014.205.002.804', // 钦洋投资管理中心总支委员会
        // code: '001.001.031.014.205.003', // 机关事业单位
        // code: '001.001.031.014.205.003.701', // 机关第一支部委员会
      })
      return
    }

    const userid: number | null = (await useFetchAuth())?.customer?.id || null
    if (!userid) return
    const orgid: string =
      (
        await useFetchUser({
          keys: '所在组织,
          q: `paths @ "userid" && string == "${userid}"`,
        })
      )?.[0]?.['所在组织]?.[0] || ''

    const code: string =
      (
        await useFetchOrgAuth({
          keys: '权限编码',
          q: `paths @ "组织id" && string == "${orgid}"`,
        })
      )?.[0]?.['权限编码'] || ''

    commit('SET_AUTH', { userid, orgid, code })
  },

  /** 根据地理标签获取基本情况数据 */
  async getBasicInfo({ commit }: Method, query?: string) {
    commit('SET_BASIC_INFO', {
      sum: await getSum(query),
      member: await getMember(query),
      organization: await getOrganization(query),
      age: await getAge(query),
    })
    commit('SET_FILTER_PATH', query)
  },

  async getMenus({ commit }: Method) {
    const res = (await useFetchMenus())?.map((item: any) => item.extra)
    const result = res
      .filter((item: any) => item['父编码'] == '0')
      .map((item: any) => ({
        key: item['编码'],
        name: item['名称'],
        children: [],
      }))
    result.forEach((item: any) => {
      const level2 = res.filter(
        (e: any) => e['父编码'] == item.key && e['级别'] == '2',
      )
      if (level2 && level2.length > 0) {
        item.children = level2.map((e: any) => ({
          name: e['名称'],
          list: res
            .filter((child: any) => child?.['父编码'] == e['编码'])
            .map((child: any) => ({
              name: child['名称'],
              id: child?.url || null,
            })),
        }))
      } else {
        item.children = res
          .filter((child: any) => child?.['父编码']?.startsWith(item.key))
          .map((child: any) => ({
            name: child['名称'],
            id: child?.url || null,
          }))
      }
    })
    commit('SET_MENUS', result)
  },

  /** 地图直接点击楼栋获取数据 */
  async getBuildingDetail({ commit }: Method, id: string) {
    if (state.showFilterDrawer) return
    commit('SET_SHOW_BUILDING_DETAIL', false)
    commit('SET_LOADING', true)
    const building =
      (
        await useFetchBuilding({
          q: `paths @ "OBJECTID" && string == "${id}"`,
        })
      )?.[0]?.extra || null
    if (!building) {
      commit('SET_LOADING', false)
      return
    }
    const floors = await getFloors(building)
    commit('SET_BUILDING_DETAIL', { building, floors })
    commit('SET_SHOW_BUILDING_DETAIL', true)
    commit('SET_LOADING', false)
  },
}

async function getSum(query?: string) {
  if (query && query.includes('所属小区')) {
    let communityQuery = query.split(',').find((e) => e.includes('所属小区'))
    if (query.includes('所属楼宇')) {
      communityQuery = [
        communityQuery,
        query.split(',').find((e) => e.includes('所属楼宇')),
      ].join(',')
    }
    const member1 =
      (
        await useFetchMember({
          a: 'id,count',
          q: `${communityQuery},paths @ "党员身份" && string == "正式党员"`,
        })
      )?.[0]?.__aggregate__ || 0
    const member2 =
      (
        await useFetchMember({
          a: 'id,count',
          q: `${communityQuery},paths @ "党员身份" && string == "预备党员"`,
        })
      )?.[0]?.__aggregate__ || 0
    return [
      {
        name: query.includes('所属楼宇') ? '楼内党员总数' : '居住在该小区党员',
        value: member1 + member2,
        unit: '位',
      },
      { name: '正式党员', value: member1, unit: '位' },
      { name: '预备党员', value: member2, unit: '位' },
    ]
  }
  const orgNum =
    (
      await useFetchOrg({
        a: 'id,count',
        keys: '是否虚拟组织',
        q: query,
      })
    )?.find((e: any) => !e['是否虚拟组织'])?.__aggregate__ || 0
  const member = await useFetchMember({
    a: 'id,count',
    keys: '是否居住在花木街道',
    q: query,
  })
  const inHuamu =
    member?.find((e: any) => e['是否居住在花木街道'])?.__aggregate__ || 0
  const notInHuamu =
    member?.find((e: any) => !e['是否居住在花木街道'])?.__aggregate__ || 0

  return [
    { name: '党组织', value: orgNum, unit: '个' },
    { name: '关系在街道内党员', value: inHuamu + notInHuamu, unit: '位' },
    { name: '街道居民党员', value: inHuamu, unit: '位' },
  ]
}

async function getMember(query?: string) {
  const result = { ...state.basicInfo.member }
  const res = await useFetchMember({
    a: 'id,count',
    keys: '党员类型',
    q: query,
  })
  const total = res.reduce(
    (acc: number, cur: any) => acc + (cur.__aggregate__ || 0),
    0,
  )
  result.source.forEach((item) => {
    const value =
      res.find((e: any) => item.name === e['党员类型'])?.__aggregate__ || 0
    item.value = value
    item.ratio = (value / total) * 100
  })
  return result
}

async function getOrganization(query?: string) {
  const result = { ...state.basicInfo.organization }
  if (query && query.includes('所属小区')) {
    result.source = []
    return result
  }
  result.source = [
    { name: '党委', value: 0, ratio: 0 },
    { name: '党总支', value: 0, ratio: 0 },
    { name: '党支部', value: 0, ratio: 0 },
    { name: '联合党支部', value: 0, ratio: 0 },
  ]
  const res = (
    await useFetchOrg({
      a: 'id,count',
      keys: '等级',
      q: query,
    })
  )?.filter((e: any) => result.source.some((n) => n.name === e['等级']))
  const total = res.reduce(
    (acc: number, cur: any) => acc + (cur.__aggregate__ || 0),
    0,
  )
  result.source.forEach((item) => {
    const value =
      res.find((e: any) => item.name === e['等级'])?.__aggregate__ || 0
    item.value = value
    item.ratio = (value / total) * 100
  })
  return result
}

async function getAge(query?: string) {
  const result = { ...state.basicInfo.age }
  const source = [
    {
      name: '18-25岁',
      range: [
        dayjs().subtract(25, 'year').format('YYYY-MM-DD'),
        dayjs().subtract(18, 'year').format('YYYY-MM-DD'),
      ],
    },
    {
      name: '26-35岁',
      range: [
        dayjs().subtract(35, 'year').format('YYYY-MM-DD'),
        dayjs().subtract(26, 'year').format('YYYY-MM-DD'),
      ],
    },
    {
      name: '36-50岁',
      range: [
        dayjs().subtract(50, 'year').format('YYYY-MM-DD'),
        dayjs().subtract(36, 'year').format('YYYY-MM-DD'),
      ],
    },
    {
      name: '50-70岁',
      range: [
        dayjs().subtract(70, 'year').format('YYYY-MM-DD'),
        dayjs().subtract(50, 'year').format('YYYY-MM-DD'),
      ],
    },
    {
      name: '70岁以上',
      range: [null, dayjs().subtract(71, 'year').format('YYYY-MM-DD')],
    },
  ]
  const res = await Promise.all(
    source.map(({ range }) => {
      const ageQuery = range[0]
        ? `paths @ "出生日期" && string >= "${range[0]}",paths @ "出生日期" && string <= "${range[1]}"`
        : `paths @ "出生日期" && string <= "${range[1]}"`
      return useFetchMember({
        a: 'id,count',
        q: query ? `${ageQuery},${query}` : ageQuery,
      })
    }),
  )
  result.source.forEach(
    (item, i) => (item.value = res[i]?.[0].__aggregate__ || 0),
  )
  return result
}

async function getFloors(data: any) {
  return Promise.all(
    (
      await useFetchRoom({
        a: 'id,count',
        keys: '层数',
        q: `paths @ "所属小区" && string == "${data?.['小区名称']}", paths @ "所属楼宇"  string @ "${data?.['号']}"`,
      })
    ).map(async (item: any) => {
      const rooms = await getRooms(
        `paths @ "所属小区" && string == "${data?.['小区名称']}", paths @ "所属楼宇"  && string @ "${data?.['号']}",paths @ "层数" && number == ${item['层数']}`,
      )
      let memberAmount = 0
      rooms.forEach((item: any) => (memberAmount += item.members.length))
      return {
        floor: `${item['层数']}F`,
        room: item.__aggregate__ || 0,
        member: memberAmount,
        rooms,
      }
    }),
  )
}
async function getRooms(query: string) {
  return Promise.all(
    (
      await useFetchRoom({
        q: query,
      })
    ).map(async (item: any) => {
      return {
        ...item.extra,
        members: await getMembers(item.extra),
      }
    }),
  )
}
async function getMembers(data: any) {
  return Promise.all(
    (
      await useFetchMember({
        q: `paths @ "所属小区" && string == "${data['所属小区']}", paths @ "所属楼宇"  && string @ "${data['所属楼宇']}",paths @ "所属房间" && string == ${data['房间号']}`,
      })
    ).map((item: any) => item.extra),
  )
}
