import {
  getRootStore,
  model,
  Model,
  modelAction,
  ModelAutoTypeCheckingMode,
  setGlobalConfig,
  tProp,
  types,
} from 'mobx-keystone';
import Log from '../Logs/Log';
import type { RootStore } from '../root-store';
import User from './User';

setGlobalConfig({
  modelAutoTypeChecking: ModelAutoTypeCheckingMode.AlwaysOn,
});
@model('keystone/Application/UserList')
export default class UserList extends Model({
  users: tProp(types.array(types.model<User>(User)), () => [
    new User({
      name: 'superuser',
      pincode: '8890',
      userlevel: 0,
      hidden: true,
      removable: false,
    }),
    new User({
      name: 'admin',
      pincode: '2580',
      userlevel: 1,
      removable: false,
    }),
  ]),
  loggedIn: tProp(types.boolean, false),
  loggedInUser: tProp(types.maybe(types.model<User>(User))),
}) {
  @modelAction
  add(user: User) {
    this.users.push(user);
  }

  @modelAction
  remove(user: any) {
    if (user === undefined) {
      return;
    }
    if (!user.removable) {
      return;
    }
    const index = this.users.indexOf(user);
    if (index >= 2) {
      this.users.splice(index, 1);
    }
  }

  @modelAction
  getUserIndexById(id: string) {
    const elementPos = this.users
      .map(function getId(u: User) {
        return u.id;
      })
      .indexOf(id);
    return elementPos;
  }

  @modelAction
  removeByIds(arrayOfIds: any) {
    arrayOfIds.map((id: string) => {
      return this.remove(this.users.find((x: { id: string }) => x.id === id));
    });
  }

  @modelAction
  checkCode(pincode: string) {
    if (this.users.find((o: { pincode: string }) => o.pincode === pincode)) {
      return true;
    }
    return false;
  }

  @modelAction
  checkCodeForLogin(pincode: string) {
    if (this.users.find((o: { pincode: string }) => o.pincode === pincode)) {
      // this.loggedIn = true;

      const rootStore = getRootStore<RootStore>(this);
      rootStore?.logs.addLog(
        new Log({
          type: 'Model',
          subType: 'Login',
          name: 'Login succesful',
          reason: `Pincode from ${
            this.checkCodeReturnUser(pincode).name
          } found.`,
          user: this.checkCodeReturnUser(pincode).name,
        })
      );
      return true;
    }
    // this.loggedIn = false;
    const rootStore = getRootStore<RootStore>(this);
    rootStore?.logs.addLog(
      new Log({
        type: 'Model',
        subType: 'Login',
        name: 'Login failed',
        reason: `Pincode: ${pincode} not found.`,
        user: 'No User',
      })
    );
    return false;
  }

  @modelAction
  checkCodeReturnUser(pincode: string) {
    const elementPos = this.users
      .map(function getPin(u: User) {
        return u.pincode;
      })
      .indexOf(pincode);
    return this.users[elementPos];
  }

  @modelAction
  checkCodeWithoutElement(id: string, pincode: string) {
    let result = false;
    for (let i = 0; i < this.users.length; i += 1) {
      if (this.users[i].id !== id) {
        if (this.users[i].pincode === pincode) {
          result = true;
        }
      }
    }
    return result;
  }

  @modelAction
  setLoggedIn(loggedIn: boolean) {
    this.loggedIn = loggedIn;
  }

  @modelAction
  setLoggedInUser(loggedInUser: User | number) {
    if (typeof this.loggedInUser === 'undefined' && loggedInUser === 0) {
      return;
    }
    if (typeof loggedInUser === 'number') {
      if (loggedInUser === 0) {
        const rootStore = getRootStore<RootStore>(this);
        let user;
        if (typeof this.loggedInUser === 'undefined') {
          user = 'No user';
        } else {
          user = this.loggedInUser?.name;
        }
        rootStore?.logs.addLog(
          new Log({
            type: 'Model',
            subType: 'Logout',
            name: 'Logout succesful',
            reason: `Logout from ${user}.`,
            user,
          })
        );
      }
      this.loggedInUser = undefined;
    } else {
      this.loggedInUser = loggedInUser;
    }
  }

  get all() {
    const withoutSuper = [];
    for (let i = 1; i < this.users.length; i += 1) {
      // i staat op 1, geen bug maar feature! hidden key voor device recovery.
      withoutSuper.push(this.users[i]);
    }
    return withoutSuper;
  }

  get allAndHidden() {
    return this.users;
  }

  get loggedInStatus() {
    return this.loggedIn;
  }
}
