import { USER_SCOPES } from '@constants/entities/Scope';
import { isEmpty } from 'lodash';
import difference from 'lodash/difference';

export const allUserScopes = USER_SCOPES;

export enum ScopesMode {
  and,
  or,
}

export interface Scope {
  list: USER_SCOPES[];
  mode: ScopesMode;
}

// ----------------------------------------------------------------------
// Deprecated
// Все это поведение не используется нигде кроме card

const scopes: {
  [key: string]: Scope;
} = {
  accounts: {
    list: [
      USER_SCOPES.MILITARY_COMMISSARIAT_ADMINISTRATOR,
      USER_SCOPES.SECURITY_ADMINISTRATOR,
    ],
    mode: ScopesMode.or,
  },
  dashboard: {
    list: [USER_SCOPES.CLOUD_ADMIN],
    mode: ScopesMode.or,
  },
  performancePanel: {
    list: [USER_SCOPES.CLOUD_ADMIN],
    mode: ScopesMode.or,
  },
  envelopes: {
    list: [USER_SCOPES.CLOUD_ADMIN],
    mode: ScopesMode.or,
  },
  microws: {
    list: [USER_SCOPES.CLOUD_ADMIN],
    mode: ScopesMode.and,
  },
  organizations: {
    list: [
      USER_SCOPES.MILITARY_COMMISSARIAT_ADMINISTRATOR,
      USER_SCOPES.SECURITY_ADMINISTRATOR,
    ],
    mode: ScopesMode.or,
  },
  printTemplates: {
    list: [USER_SCOPES.CLOUD_ADMIN],
    mode: ScopesMode.or,
  },
  directory: {
    list: [USER_SCOPES.CLOUD_ADMIN],
    mode: ScopesMode.or,
  },
  army: {
    list: [USER_SCOPES.CLOUD_ADMIN],
    mode: ScopesMode.or,
  },
  processes: {
    list: [],
    mode: ScopesMode.or,
  },
  regions: {
    list: [USER_SCOPES.CLOUD_ADMIN],
    mode: ScopesMode.or,
  },
  reports: {
    list: [USER_SCOPES.CLOUD_ADMIN],
    mode: ScopesMode.or,
  },
  resources: {
    list: [USER_SCOPES.CLOUD_ADMIN],
    mode: ScopesMode.or,
  },
  solutions: {
    list: [USER_SCOPES.CLOUD_ADMIN],
    mode: ScopesMode.or,
  },
  scopes: {
    list: [USER_SCOPES.CLOUD_ADMIN],
    mode: ScopesMode.or,
  },
  statements: {
    list: [
      USER_SCOPES.SPECIALIST,
      USER_SCOPES.MILITARY_APPLICATION_SPECIALIST,
      USER_SCOPES.CLOUD_ADMIN,
      USER_SCOPES.MILITARY_COMMISSAR,
    ],
    mode: ScopesMode.or,
  },
  statementDrafts: {
    list: [USER_SCOPES.CLOUD_ADMIN],
    mode: ScopesMode.or,
  },
  signedApplications: {
    list: [USER_SCOPES.CLOUD_ADMIN],
    mode: ScopesMode.or,
  },
  tasks: {
    list: [USER_SCOPES.CLOUD_ADMIN],
    mode: ScopesMode.or,
  },
  userTasks: {
    list: [],
    mode: ScopesMode.or,
  },
  criteriaDirectory: {
    list: [USER_SCOPES.CLOUD_ADMIN],
    mode: ScopesMode.or,
  },
  registries: {
    list: [USER_SCOPES.CLOUD_ADMIN],
    mode: ScopesMode.or,
  },
  refistryOrder: {
    list: [USER_SCOPES.CLOUD_ADMIN],
    mode: ScopesMode.or,
  },
  registryPayment: {
    list: [USER_SCOPES.CLOUD_ADMIN],
    mode: ScopesMode.or,
  },
  registryUnloading: {
    list: [USER_SCOPES.CLOUD_ADMIN],
    mode: ScopesMode.or,
  },
  registryUkranianRefugeePayment: {
    list: [USER_SCOPES.CLOUD_ADMIN],
    mode: ScopesMode.or,
  },
  tickets: {
    list: [USER_SCOPES.CLOUD_ADMIN],
    mode: ScopesMode.or,
  },
  services: {
    list: [],
    mode: ScopesMode.or,
  },
  backgroundInfo: {
    list: [USER_SCOPES.CLOUD_ADMIN],
    mode: ScopesMode.or,
  },
  debugCode: {
    list: [USER_SCOPES.CLOUD_ADMIN],
    mode: ScopesMode.or,
  },
  notifications: {
    list: [USER_SCOPES.CLOUD_ADMIN],
    mode: ScopesMode.or,
  },
  administration: {
    list: [USER_SCOPES.CLOUD_ADMIN],
    mode: ScopesMode.or,
  },
  all: {
    list: [USER_SCOPES.CLOUD_ADMIN],
    mode: ScopesMode.and,
  },
  personalReception: {
    list: [USER_SCOPES.CLOUD_ADMIN],
    mode: ScopesMode.or,
  },
  incidents: {
    list: [USER_SCOPES.CLOUD_ADMIN],
    mode: ScopesMode.or,
  },
  payments: {
    list: [USER_SCOPES.CLOUD_ADMIN],
    mode: ScopesMode.or,
  },
  departments: {
    list: [
      USER_SCOPES.MILITARY_COMMISSARIAT_ADMINISTRATOR,
      USER_SCOPES.SECURITY_ADMINISTRATOR,
    ],
    mode: ScopesMode.or,
  },
  personalAccounts: {
    list: [USER_SCOPES.CLOUD_ADMIN],
    mode: ScopesMode.or,
  },
  interagencyRequests: {
    list: [USER_SCOPES.CLOUD_ADMIN],
    mode: ScopesMode.or,
  },
  additionalSettings: {
    list: [USER_SCOPES.CLOUD_ADMIN],
    mode: ScopesMode.or,
  },
  notificationTemplates: {
    list: [USER_SCOPES.CLOUD_ADMIN],
    mode: ScopesMode.or,
  },
  recruitsToCall: {
    list: [
      // есть
      USER_SCOPES.MILITARY_COMMISSAR,
      USER_SCOPES.MILITARY_RECRUIT_SPECIALIST,
      // USER_SCOPES.MILITARY_CONSCRIPTION_SPECIALIST,
      USER_SCOPES.SYSTEM_ADMINISTRATOR,
    ],
    mode: ScopesMode.or,
  },
  recruit: {
    list: [
      // есть
      USER_SCOPES.MILITARY_COMMISSAR,
      USER_SCOPES.SYSTEM_ADMINISTRATOR,
    ],
    mode: ScopesMode.or,
  },
  registered: {
    list: [
      // есть
      USER_SCOPES.MILITARY_COMMISSAR,
      USER_SCOPES.GOMU_SPECIALIST,
      USER_SCOPES.MILITARY_RECRUIT_SPECIALIST,
      // USER_SCOPES.MILITARY_CONSCRIPTION_SPECIALIST,
      USER_SCOPES.MILITARY_APPLICATION_SPECIALIST,
      USER_SCOPES.SYSTEM_ADMINISTRATOR,
    ],
    mode: ScopesMode.or,
  },
  // Внешний обмен
  interagency: {
    list: [
      // есть
      USER_SCOPES.MILITARY_COMMISSAR,
      USER_SCOPES.GOMU_SPECIALIST,
      USER_SCOPES.SYSTEM_ADMINISTRATOR,
    ],
    mode: ScopesMode.or,
  },
  summon: {
    list: [
      // есть
      USER_SCOPES.MILITARY_COMMISSAR,
      USER_SCOPES.GOMU_SPECIALIST,
      USER_SCOPES.MILITARY_RECRUIT_SPECIALIST,
      // USER_SCOPES.MILITARY_CONSCRIPTION_SPECIALIST,
      USER_SCOPES.SYSTEM_ADMINISTRATOR,
    ],
    mode: ScopesMode.or,
  },
  summonCard: {
    list: [
      // есть
      USER_SCOPES.MILITARY_COMMISSAR,
      USER_SCOPES.GOMU_SPECIALIST,
      USER_SCOPES.MILITARY_RECRUIT_SPECIALIST,
      // USER_SCOPES.MILITARY_CONSCRIPTION_SPECIALIST,
      USER_SCOPES.SYSTEM_ADMINISTRATOR,
    ],
    mode: ScopesMode.or,
  },
  summonLists: {
    list: [
      // есть
      USER_SCOPES.MILITARY_COMMISSAR,
      USER_SCOPES.GOMU_SPECIALIST,
      USER_SCOPES.MILITARY_RECRUIT_SPECIALIST,
      // USER_SCOPES.MILITARY_CONSCRIPTION_SPECIALIST,
      USER_SCOPES.SYSTEM_ADMINISTRATOR,
    ],
    mode: ScopesMode.or,
  },
  summonLogs: {
    list: [
      // есть
      USER_SCOPES.MILITARY_COMMISSAR,
      USER_SCOPES.GOMU_SPECIALIST,
      USER_SCOPES.SYSTEM_ADMINISTRATOR,
    ],
    mode: ScopesMode.or,
  },
  summonExtracts: {
    list: [
      // есть
      USER_SCOPES.MILITARY_COMMISSAR,
      USER_SCOPES.GOMU_SPECIALIST,
      USER_SCOPES.SYSTEM_ADMINISTRATOR,
    ],
    mode: ScopesMode.or,
  },
  summonEdits: {
    list: [
      // есть
      USER_SCOPES.MILITARY_COMMISSAR,
      USER_SCOPES.GOMU_SPECIALIST,
      USER_SCOPES.SYSTEM_ADMINISTRATOR,
    ],
    mode: ScopesMode.or,
  },
  callListsImportCsv: {
    list: [
      USER_SCOPES.MILITARY_RECRUIT_SPECIALIST,
      // USER_SCOPES.MILITARY_CONSCRIPTION_SPECIALIST,
      USER_SCOPES.SYSTEM_ADMINISTRATOR,
    ],
    mode: ScopesMode.or,
  },
  // Поиск повесток
  summonsSearch: {
    list: [
      // есть
      USER_SCOPES.MILITARY_COMMISSAR,
      USER_SCOPES.MILITARY_RECRUIT_SPECIALIST,
      // USER_SCOPES.MILITARY_CONSCRIPTION_SPECIALIST,
      USER_SCOPES.SYSTEM_ADMINISTRATOR,
    ],
    mode: ScopesMode.or,
  },
  // Поиск по гражданину
  summonsPersonSearch: {
    list: [
      // есть
      USER_SCOPES.MILITARY_COMMISSAR,
      USER_SCOPES.MILITARY_RECRUIT_SPECIALIST,
      // USER_SCOPES.MILITARY_CONSCRIPTION_SPECIALIST,
      USER_SCOPES.SYSTEM_ADMINISTRATOR,
    ],
    mode: ScopesMode.or,
  },
  // Эталонные данные
  standardData: {
    list: [
      // есть
      USER_SCOPES.MILITARY_COMMISSAR,
      USER_SCOPES.MILITARY_RECRUIT_SPECIALIST,
      // USER_SCOPES.MILITARY_CONSCRIPTION_SPECIALIST,
      USER_SCOPES.SYSTEM_ADMINISTRATOR,
    ],
    mode: ScopesMode.or,
  },
  conversion: {
    list: [
      // есть
      USER_SCOPES.MILITARY_COMMISSAR,
      USER_SCOPES.GOMU_SPECIALIST,
      USER_SCOPES.MILITARY_RECRUIT_SPECIALIST,
      USER_SCOPES.SYSTEM_ADMINISTRATOR,
    ],
    mode: ScopesMode.or,
  },
  conscription: {
    list: [
      // есть
      USER_SCOPES.GOMU_SPECIALIST,
      // USER_SCOPES.MILITARY_CONSCRIPTION_SPECIALIST,
      USER_SCOPES.SYSTEM_ADMINISTRATOR,
    ],
    mode: ScopesMode.or,
  },
  records: {
    list: [
      // есть
      USER_SCOPES.MILITARY_COMMISSAR,
      USER_SCOPES.GOMU_SPECIALIST,
      USER_SCOPES.MILITARY_RECRUIT_SPECIALIST,
      // USER_SCOPES.MILITARY_CONSCRIPTION_SPECIALIST,
      USER_SCOPES.MILITARY_APPLICATION_SPECIALIST,
      USER_SCOPES.SYSTEM_ADMINISTRATOR,
    ],
    mode: ScopesMode.or,
  },
  registration: {
    list: [
      // есть
      USER_SCOPES.MILITARY_COMMISSAR,
      USER_SCOPES.MILITARY_RECRUIT_SPECIALIST,
      USER_SCOPES.SYSTEM_ADMINISTRATOR,
    ],
    mode: ScopesMode.or,
  },
  cancelRegistration: {
    list: [
      // есть
      USER_SCOPES.MILITARY_COMMISSAR,
      USER_SCOPES.MILITARY_RECRUIT_SPECIALIST,
      USER_SCOPES.SYSTEM_ADMINISTRATOR,
    ],
    mode: ScopesMode.or,
  },
  personalFileRequests: {
    list: [
      // есть
      USER_SCOPES.MILITARY_COMMISSAR,
      USER_SCOPES.MILITARY_RECRUIT_SPECIALIST,
      USER_SCOPES.SYSTEM_ADMINISTRATOR,
    ],
    mode: ScopesMode.or,
  },
  approval: {
    list: [
      // есть
      USER_SCOPES.MILITARY_COMMISSAR,
      USER_SCOPES.SYSTEM_ADMINISTRATOR,
    ],
    mode: ScopesMode.or,
  },
  recordsNotifications: {
    list: [
      // есть
      USER_SCOPES.MILITARY_COMMISSAR,
      USER_SCOPES.MILITARY_RECRUIT_SPECIALIST,
      USER_SCOPES.SYSTEM_ADMINISTRATOR,
    ],
    mode: ScopesMode.or,
  },
  recordsArchive: {
    list: [
      // есть
      USER_SCOPES.MILITARY_COMMISSAR,
      USER_SCOPES.GOMU_SPECIALIST,
      USER_SCOPES.MILITARY_RECRUIT_SPECIALIST,
      USER_SCOPES.SYSTEM_ADMINISTRATOR,
    ],
    mode: ScopesMode.or,
  },
  records_archive: {
    list: [
      // есть
      USER_SCOPES.MILITARY_COMMISSAR,
      USER_SCOPES.GOMU_SPECIALIST,
      USER_SCOPES.MILITARY_RECRUIT_SPECIALIST,
      USER_SCOPES.SYSTEM_ADMINISTRATOR,
    ],
    mode: ScopesMode.or,
  },
  control: {
    list: [
      // есть
      USER_SCOPES.GOMU_SPECIALIST,
      USER_SCOPES.SYSTEM_ADMINISTRATOR,
    ],
    mode: ScopesMode.or,
  },
  analytics: {
    list: [
      // есть
      USER_SCOPES.GOMU_SPECIALIST,
      USER_SCOPES.SYSTEM_ADMINISTRATOR,
    ],
    mode: ScopesMode.or,
  },
  dataquality: {
    list: [
      // есть
      USER_SCOPES.GOMU_SPECIALIST,
      USER_SCOPES.SYSTEM_ADMINISTRATOR,
    ],
    mode: ScopesMode.or,
  },
  gomu: {
    list: [
      // есть
      USER_SCOPES.GOMU_SPECIALIST,
      USER_SCOPES.SYSTEM_ADMINISTRATOR,
    ],
    mode: ScopesMode.or,
  },
  gomuAndCommisar: {
    list: [
      // есть
      USER_SCOPES.GOMU_SPECIALIST,
      USER_SCOPES.SYSTEM_ADMINISTRATOR,
    ],
    mode: ScopesMode.or,
  },
  ervuReports: {
    list: [
      // есть
      USER_SCOPES.GOMU_SPECIALIST,
      USER_SCOPES.MILITARY_RECRUIT_SPECIALIST,
      USER_SCOPES.SYSTEM_ADMINISTRATOR,
    ],
    mode: ScopesMode.or,
  },
};

const paths: {
  [key: string]: string;
} = {
  statements: 'statements',
  'registry-object': 'registries',
  processes: 'processes',
  accounts: 'accounts',
  departments: 'departments',
  organizations: 'organizations',
  regions: 'regions',
  payments: 'payments',
  services: 'services',
  backgroundinfo: 'backgroundinfo',
  'debug-code': 'debugCode',
  'additional-settings': 'additionalSettings',
  schemas: 'services',
  reports: USER_SCOPES.REPORTS,
  inter_requests: 'statements',
  solutions: 'solutions',
  scopes: 'scopes',
  tasks: 'tasks',
  tickets: 'tickets',
  notifications: 'notifications',
  administration: 'administration',
  performancePanel: 'performancePanel',
  'personal-accounts': 'personalAccounts',
  'criteria-directory': 'criteriaDirectory',
  directory: 'directory',
  army: 'army',
  roles: 'roles',
  'notification-templates': 'notificationTemplates',
  'recruits-to-call': 'recruitsToCall',
  recruit: 'recruit',
};

export function comparePaths(path: string): boolean {
  const listName: string = paths[path];
  return matchScopes(scopes[listName].list, ScopesMode.or);
}

// ----------------------------------------------------------------------

export function getScopes(
  list: Scope['list'],
  mode: ScopesMode = ScopesMode.or
): Scope | undefined {
  if (isEmpty(list)) return;
  return {
    list,
    mode,
  };
}

/* @deprecated instead use $AC */
export function matchScopes(
  list: string[] = [],
  mode = ScopesMode.and
): boolean {
  // eslint-disable-next-line @typescript-eslint/no-var-requires
  const store = require('@state/store').default;
  // Костыль, лечащий кейс с поломкой редиректа
  // Если в src/router/cards/routes.js заимпорчен этот метот
  // + в модуле глобально заимпорчен стор, то oidc ломается на вызове метода signinRedirect
  const scopes = (store?.getters['oidcClient/currentUser']?.scope || '').split(
    ' '
  );
  const distinction = difference(list, scopes);
  let isMatched = false;
  switch (mode) {
    case ScopesMode.and:
      isMatched = !distinction.length;

      break;
    case ScopesMode.or:
      isMatched = distinction.length < list.length;

      break;
  }

  return isMatched;
}

export default scopes;
