import { Injectable } from '@angular/core';
import { cnst_LoadedEntitiesExpiresInMs, EN_AppEntities, EN_AppPages, EN_HttpQueriesCount4Page } from '@app_consts';
import { EN_EntityBeforeSaveCallBackResults } from '@app_core/consts';
import { CoreUser } from '@app_core/models/coreuser';
import { RepositoryService } from '@app_core/services/http/repository.service';
import { UINotifierService } from '@app_core/services/notification/uinotifier.service';
import { CorePageService } from '@app_core/services/page.service';
import { Employee, EmployeeFilter, EmployeeFullFilter } from '@app_models/employee';
import { EmployeeToAttribute } from '@app_models/employee-to-attribute';
import { EmployeeToDepartment } from '@app_models/employee-to-department';
import { EmployeeToWebApp } from '@app_models/employee-to-webapp';
import { AppBaseEntity } from '@app_models/generic/app.baseentity';

import { User } from '@app_models/user';
import { EmployeeToWebAppFilter, WebAppToDepartment } from '@app_models/webapp-to-department';
import { WebAppToWebAppAdditionalRole } from '@app_models/webapp-to-webappadditionalrole';
import { AppBaseEntityWrapper } from '@app_services/app.baseentity.wrapper';
import { AppBaseEntityListWrapper } from '@app_services/app.baseentitylist.wrapper';
import { AppDataService } from '@app_services/app.data.service';
import { AppBaseEntityCallBack } from 'src/app/shared/app.types';


@Injectable({ providedIn: 'root' })

export class EmployeeDataService extends CorePageService {
  protected appPage: EN_AppPages = EN_AppPages.Employee;
  protected get appPageNoQueries() { return EN_HttpQueriesCount4Page.Employee; }

  // --- running data
  employeeDetails: AppBaseEntityWrapper<Employee>;
  employeeList: AppBaseEntityListWrapper<Employee> = new AppBaseEntityListWrapper<Employee>(Employee, 'Mitarbeiterliste', EN_AppEntities.Employee);
  employeeFilter: EmployeeFullFilter = new EmployeeFullFilter('EmployeeFullFilter');
  employee2AllFilter: EmployeeFilter = new EmployeeFilter('EmployeeFilter');

  employee2DepartmentList: AppBaseEntityListWrapper<EmployeeToDepartment> = new AppBaseEntityListWrapper<EmployeeToDepartment>(EmployeeToDepartment, 'Abteilungen von Mitarbeiter', EN_AppEntities.EmployeeToDepartment);

  employee2WebAppList: AppBaseEntityListWrapper<EmployeeToWebApp> = new AppBaseEntityListWrapper<EmployeeToWebApp>(EmployeeToWebApp, 'Applikationen von Mitarbeiter', EN_AppEntities.EmployeeToWebapp);

  employee2AttributeList: AppBaseEntityListWrapper<EmployeeToAttribute> = new AppBaseEntityListWrapper<EmployeeToAttribute>(EmployeeToAttribute, 'Merkmale von Mitarbeiter', EN_AppEntities.EmployeeToAttribute);

  constructor(
    private appDataService: AppDataService,
    private repositoryService: RepositoryService,
    protected uiNotificationsService: UINotifierService
  ) {
    super();

    this.employeeList.alwaysFocused = true;
    this.employeeList.focusedCallBack = this.focusCallBack.bind(this);
    this.employeeList.filter = this.employeeFilter;

    this.employeeDetails = this.employeeList.createFocusedShadowEntity(AppBaseEntityWrapper.EN_ViewMode);
    this.employeeDetails.loadedDataExpiresInMs = cnst_LoadedEntitiesExpiresInMs;

    this.activateRouting4EntityList(this.employeeList); //we are using routing
    this.baseEntityWrapperWaitLoading = this.employeeDetails;

    this.prepareDetailsList(this.employee2DepartmentList);
    this.prepareDetailsList(this.employee2WebAppList);

    this.employeeDetails.detailItems.register(this.employee2DepartmentList, null, 'employeeId', /*() => this.employee2DepartmentList.focuseFirstItem()*/);
    this.employeeDetails.detailItems.register(this.employee2WebAppList, null, 'employeeId');
    this.employeeDetails.detailItems.register(this.employee2AttributeList, null, 'employeeId');
    this.employee2WebAppList.batchInsert = false;
    this.employee2WebAppList.beforeSaveCallBack = this.beforeSaveEmployee2WebAppList.bind(this);
    this.employee2WebAppList.afterInsertCallBack = this.afterInsertEmployee2WebAppList.bind(this);
    this.employee2AttributeList.filter = this.employee2AllFilter;

    this.loadBaseData();
    this.init();
  }

  async beforeSaveEmployee2WebAppList(entities: EmployeeToWebApp[]): Promise<EN_EntityBeforeSaveCallBackResults> {
    entities.forEach((entity: EmployeeToWebApp) => {
      if (entity.entityChanged && !entity.isNew()) this.afterInsertEmployee2WebAppList(entity, null, false);
    });
    this.employee2WebAppList.deletedItems.forEach((entity: EmployeeToWebApp) => {
      entity.arExtendedDepartmentIdList = [];
      entity.arAdditionalRoleIdList = [];
      this.afterInsertEmployee2WebAppList(entity, null, false);
    });
    return EN_EntityBeforeSaveCallBackResults.Ok_Continue;
  }


  afterInsertEmployee2WebAppList(entity: EmployeeToWebApp, callback?: AppBaseEntityCallBack, reloadEntity = true) {
    if (entity) {
      const filter = new EmployeeToWebAppFilter('EmployeeToWebAppFilter');
      filter.employeeToWebAppId = entity.employeeToWebAppId;
      //to create wrapper not in the constructor we need to pass appLogsService, repositoryService, uiNotificationsService explicetely!
      const departmentList = new AppBaseEntityListWrapper<WebAppToDepartment>(WebAppToDepartment, 'Abteilungen für Mitarbeiterapplikation', EN_AppEntities.WebAppToDepartment, filter, this.appLogsService, this.repositoryService, this.uiNotificationsService);
      const addRoleList =
        new AppBaseEntityListWrapper<WebAppToWebAppAdditionalRole>(WebAppToWebAppAdditionalRole, 'Zusatzrole für Mitarbeiterapplikation', EN_AppEntities.WebAppToWebAppAdditionalRole, filter, this.appLogsService, this.repositoryService, this.uiNotificationsService);

      this._saveEmployee2WebAppSublists(entity
        , departmentList
        , 'arExtendedDepartmentIdList'
        , 'departmentId'
        , (result1) => {
          this._saveEmployee2WebAppSublists(entity
            , addRoleList
            , 'arAdditionalRoleIdList'
            , 'webAppAdditionalRoleId'
            , (result2) => { if (reloadEntity && (result1 || result2)) entity.load(this.repositoryService, callback); else if (callback) callback(); }
          );
        }
      );
    }
  }


  private _saveEmployee2WebAppSublists(entity: EmployeeToWebApp, list: AppBaseEntityListWrapper<AppBaseEntity>, idListName: string, idName: string, callback?: (entity: boolean) => void) {
    let result: boolean = false;
    list.load(() => {
      if (result = list.match2array(entity, 'employeeToWebAppId', idListName, idName)) {
        list.save(() => { if (callback) callback(true); }, (err) => { if (callback) callback(true); });
      } else if (callback) callback(false);
    });
  }


  prepareDetailsList(list: AppBaseEntityListWrapper<AppBaseEntity>) {
    list.createFocusedShadowEntity();
    list.filter = this.employee2AllFilter;
    list.focusedEntityShadowed.dontLoadEntity = true;
    list.focusedEntityShadowed.dontUpdateEntityDirectly = true;
    list.focusedEntityShadowed.dontInsertEntityDirectly = true;
  }


  loadData() {
    super.loadData();
    this.employeeList.load(null, null, () => this.pageLoadingService.updatePageLoadedCounters(this.appPage));
  }

  public loadBaseData() {
    super.loadBaseData(EN_AppPages.Login, EN_HttpQueriesCount4Page.Login);
    this.appDataService.loadData(() => this.pageLoadingService.updatePageLoadedCounters(EN_AppPages.Login));
  }


  public focusCallBack(focusedItem: Employee) {
  }


  public clearData() {
    super.clearData();
    this.employeeFilter.filterReset();
    this.employeeList.clear();
  }


  protected onLoggedInOut(user: CoreUser) {
    this.userChanged(new User(user));
    super.onLoggedInOut(user);
  }

  private userChanged(user: User) {
    if (this.authService.isLoggedIn()) {
      this.employeeDetails.canNew = user.isMaster;
      this.employeeDetails.canEdit = this.employeeDetails.canNew;
      this.employeeDetails.canDelete = this.employeeDetails.canNew;
    }
    // this.globalsService.appPages[EN_AppPages.UserConfig].hidden = !user?.isMaster;
  }

}
