import { Service, LMConfig } from '@zenview/micro-basic-library';
import { cache } from '@zenview/micro-utils';
import { flatten, last } from 'lodash';

function catchPromise(fn) {
  return new Promise((resolve) => {
    fn.then(
      (res) => resolve(res),
      (err) => {
        console.error(err);
        resolve();
      }
    );
  });
}

const method = 'post';
export async function initialization() {
  const headers = {
    Authorization: cache.getCache('token', 'session'),
  };
  const result = await Service.$http({ url: '/api/user/v1/getUserByToken', method, headers, requestId: 'getUserInfo' });
  const userInfo = result.data;
  const userId = userInfo.id;
  const operationCenterId = userInfo.operationCenterId;
  const data = { id: userId };
  const data2 = { id: operationCenterId };
  const centerUrl = `/api/user/operationCenter/v1/operationCenters/${operationCenterId}`;
  const centerInfo = await Service.$http({ data: data2, method, url: centerUrl, headers, requestId: 'operationCenterInfo' });

  if (centerInfo.data.hues) {
    const themeUrl = `/api/micro/configure/v1/queryConfigureByConfigureId/${centerInfo.data.hues}`;
    const themeRes = await Service.$http({ data: data2, method: 'get', url: themeUrl, headers });
    try {
      LMConfig.registerThemeConfig(themeRes.data?.info);
    } catch (e) { }
  }

  const userPrivilegesUrl = `/api/user/role/v1/queryUserRoles/${userId}`;
  const centerPrivilegesUrl = `/api/micro/applicationSystemScene/v1/queryAllFunctionByApplicationSystemId/${operationCenterId}`;
  const allPrivilegesUrl = `/api/micro/function/v1/queryFunctionList`;
  const systemInfoUrl = `/api/user/v1/systemInfo/${userId}`;

  const [userPrivileges = { data: [] }, centerPrivileges = { data: [] }, allPrivileges = { data: [] }, systemInfo] = await Promise.all([
    catchPromise(Service.$http({ data, method, url: userPrivilegesUrl, headers })),
    catchPromise(Service.$http({ data: data2, method: 'get', url: centerPrivilegesUrl, headers })),
    catchPromise(Service.$http({ method: 'get', url: allPrivilegesUrl, headers })),
    catchPromise(Service.$http({ data, method, url: systemInfoUrl, headers })), //获取用户系统信息
  ]);

  return { userInfo, userPrivileges, centerPrivileges, allPrivileges, centerInfo, systemInfo };
}

export function queryOrganizationsList(options) {
  const headers = {
    Authorization: cache.getCache('token', 'session'),
  };
  const url = '/api/user/v1/organization/queryChildOrganizationsById';
  return catchPromise(Service.$http({ headers, url, method: 'post', data: { selectChildOrganization: true, ...options } }));
}

export function queryPlacesList(orgId) {
  const headers = {
    Authorization: cache.getCache('token', 'session'),
  };

  const url2 = '/api/user/v1/organization/queryPlacesByOrganizationId';
  const url4 = '/api/place/places/v1/config/filter';
  const data = { organizationId: orgId, includeSubOrgIds: true };
  return Service.$http({ url: url4, headers }).then(res => {
    if (res.code === 0) {
      const administrativeDivisionsRequestData = res?.data
      const administrativeDivisionsRequestArr = administrativeDivisionsRequestData.split(',').map(v => catchPromise(Service.$http({ url: `/micro-apps/micro-dep-librarys/administrativeDivisions/${v}.json`, headers })))
      return Promise.all([
        ...administrativeDivisionsRequestArr,
        catchPromise(Service.$http({ method, url: url2, headers, data })),
      ]).then((resArr) => {
        let dataArr = resArr.map(j => j?.data || [])
        let initPlaceData = flatten(administrativeDivisionsRequestArr.map((v, k) => {
          return dataArr[k]
        }))
        return [initPlaceData, last(dataArr)]
      });
    } else {
      return [[]]
    }
  }).catch(() => {
    return [[]]
  })
}

function queryUserDevicesNew(data) {
  const headers = {
    Authorization: cache.getCache('token', 'session'),
  };
  const url = '/api/device/v1/queryDevices4User';
  return Service.$http({ url, method: 'post', data, headers });
}

function queryUserDevicesStatusNew(data) {
  const headers = {
    Authorization: cache.getCache('token', 'session'),
  };
  const url = '/api/device/v1/queryDeviceStatus4User';
  return Service.$http({ url, method: 'post', data, headers });
}

function queryDeviceLocalRecordAbilityList(data) {
  const headers = {
    Authorization: cache.getCache('token', 'session'),
  };
  const url = '/api/device/v1/queryDeviceLocalRecordAbilityList';
  return Service.$http({ url, method: 'post', data, headers });
}

function emptyPromise() {
  return new Promise((resolve) => resolve(false));
}

export function formatDeviceMap(data = [], groupLibs = {}, deviceState = {}, deviceFrontEnd = {}, deviceStorage = {}) {
  const deviceList = [];
  data.forEach((item) => {
    let [
      cid,
      deviceName, //deviceStatus
      ,
      deviceType,
      id,
      latitude,
      longitude,
      lygroupIndex,
      manufacturerDeviceId,
      manufacturerDeviceType,
      organizationIds,
      pathId,
      placeId,
      sn,
      boxNum,
      cameraType,
      villageLocationType,
      placeTags,
      parentId,
      accessType,
      createTime,
    ] = item.split('|');
    try {
      organizationIds = JSON.parse(organizationIds).map((v) => v.toString());
    } catch (e) {
      organizationIds = [];
    }
    try {
      pathId = JSON.parse(pathId);
    } catch (e) {
      pathId = [];
    }
    try {
      placeTags = JSON.parse(placeTags).map((v) => v.toString());
    } catch (e) {
      placeTags = [];
    }
    try {
      cameraType = JSON.parse(cameraType);
    } catch (e) {
      cameraType = null;
    }
    deviceList.push({
      cid,
      deviceName,
      deviceStatus: deviceState[id],
      deviceType,
      id,
      latitude,
      longitude,
      lygroupId: groupLibs[lygroupIndex],
      manufacturerDeviceId,
      manufacturerDeviceType,
      organizationIds,
      pathId,
      placeId,
      sn,
      boxNum,
      cameraType,
      hasFrontEnd: +deviceFrontEnd[id] !== 0,
      hasStorage: +deviceStorage[id] !== 0,
      parentId,
      accessType,
      villageLocationType,
      placeTags,
      createTime,
    });
  });

  return deviceList;
}

export function queryUserDevice(options, needDeviceLocalRecordAbility = true) {
  return Promise.all([
    queryUserDevicesNew(options ? options : { offset: 0, limit: 100000 }),
    queryUserDevicesStatusNew(options ? options : { offset: 0, limit: 100000 }),
    needDeviceLocalRecordAbility ? queryDeviceLocalRecordAbilityList(options ? options : { queryType: 2 }) : emptyPromise(),
  ]).then((devices) => {
    const [listRes, statusRes, frontEndRes] = devices;
    let deviceState = {};
    statusRes.data.split('|').forEach((res) => {
      const [id, state] = res.split(',');
      deviceState[id] = `${state}`;
    });
    let deviceFrontEnd = {};
    let deviceStorage = {};
    frontEndRes &&
      frontEndRes.data.split('|').forEach((res) => {
        const [id, state, storage] = res.split(',');
        deviceFrontEnd[id] = state;
        deviceStorage[id] = storage;
      });
    return formatDeviceMap(listRes.data.list, listRes.data.other, deviceState, deviceFrontEnd, deviceStorage);
  });
}

export function authFormat(userRoles = [], systemFeatures = [], userType) {
  const features = [];
  /* prettier-ignore */
  const appIds = Object.values(LMConfig.AppConfig).filter((v) => v.appType === 0).map((v) => v.id);
  userRoles = userRoles.map((v) => `${v}`);
  systemFeatures.forEach((item) => {
    if (Array.isArray(item.extJson?.relations) && userRoles.includes(`${item.code}`)) {
      /* prettier-ignore */
      const relationCodes = item.extJson.relations.map((v) => systemFeatures.find((v2) => v2.alias === v)).filter((v) => !!v).map((v) => `${v.code}`);
      userRoles.push(...relationCodes);
    }
    if (appIds.includes(item.microApplicationId)) {
      userRoles.push(`${item.code}`);
    }
    if (userRoles.includes(`${item.code}`) || (+userType === 100702 && userRoles.includes(item.parentCode))) {
      if (item.groups && item.groups.group1) {
        features.push({
          id: item.groups.group1.key,
          name: item.groups.group1.label,
          code: item.groups.group1.key,
          alias: item.groups.group1.key,
          sort: item.groups.group1.sort,
          icon: item.groups.group1.icon,
          isMenu: 1,
          level: 1,
          microApplicationId: item.microApplicationId,
        });

        if (item.groups.group2) {
          features.push({
            id: item.groups.group2.key,
            name: item.groups.group2.label,
            code: item.groups.group2.key,
            alias: item.groups.group2.key,
            sort: item.groups.group2.sort,
            icon: item.groups.group2.icon,
            isMenu: 1,
            level: 2,
            microApplicationId: item.microApplicationId,
            parentCode: item.groups.group1.key,
          });
          item.parentCode = item.groups.group2.key;
        } else {
          features.push({
            id: item.groups.group1.key + 'lv2',
            name: item.groups.group1.label,
            code: item.groups.group1.key + 'lv2',
            alias: item.groups.group1.key + 'lv2',
            sort: item.groups.group1.sort,
            isMenu: 1,
            level: 2,
            microApplicationId: item.microApplicationId,
            parentCode: item.groups.group1.key,
          });
          item.parentCode = item.groups.group1.key + 'lv2';
        }
      }
      item.level = item.isMenu === 1 ? 3 : 4;
      features.push(item);
    }
  });

  (window._HOT_FEATURES_ || []).forEach((item) => {
    if (item.groups && item.groups.group1) {
      features.push({
        id: item.groups.group1.key,
        name: item.groups.group1.label,
        code: item.groups.group1.key,
        alias: item.groups.group1.key,
        sort: item.groups.group1.sort,
        icon: item.groups.group1.icon,
        isMenu: 1,
        microApplicationId: item.microApplicationId,
      });
      if (item.groups.group2) {
        features.push({
          id: item.groups.group2.key,
          name: item.groups.group2.label,
          code: item.groups.group2.key,
          sort: item.groups.group2.sort,
          alias: item.groups.group2.key,
          icon: item.groups.group2.icon,
          isMenu: 1,
          microApplicationId: item.microApplicationId,
          parentCode: item.groups.group1.key,
        });
        item.parentCode = item.groups.group2.key;
      } else {
        features.push({
          id: item.groups.group1.key + 'lv2',
          name: item.groups.group1.label,
          code: item.groups.group1.key + 'lv2',
          alias: item.groups.group1.key + 'lv2',
          sort: item.groups.group1.sort,
          icon: item.groups.group1.icon,
          isMenu: 1,
          level: 2,
          microApplicationId: item.microApplicationId,
          parentCode: item.groups.group1.key,
        });
        item.parentCode = item.groups.group1.key + 'lv2';
      }
    }
    item.level = 3;
    features.push(item);
  });

  return features;
}
