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

setGlobalConfig({
  modelAutoTypeChecking: ModelAutoTypeCheckingMode.AlwaysOn,
});
@model('keystone/Remote/Acs01List')
export default class Acs01List extends Model({
  acs01s: tProp(types.array(types.model<Acs01>(Acs01)), () => []),
  configured: tProp(types.boolean, false),
  defaultAcs01: tProp(types.maybe(types.model<Acs01>(Acs01))),
  defaultAcs01LoginOk: tProp(types.boolean, false),
  localStatus: tProp(types.number, -1),
  remoteStatus: tProp(types.number, -1),
  websocketStatus: tProp(types.boolean, false),
  websocketFails: tProp(types.number, -1),
  resultStatus: tProp(types.boolean, false),
  discoverStatus: tProp(types.number, 0),
  loginStatus: tProp(types.number, 0), // Increment every time we do succesfull login
  cookie: tProp(types.string, ''),
  acs01AutoDiscoverList: tProp(
    types.array(
      types.object(() => ({
        addresses: types.array(types.string),
        ip: types.string,
        name: types.string,
        hostname: types.string,
        port: types.number,
        type: types.string,
        protocol: types.string,
        domain: types.string,
      }))
    ),
    () => []
  ),
  defaultApp: tProp(
    types.maybe(
      types.object(() => ({
        addresses: types.array(types.string),
        ip: types.string,
        name: types.string,
        appType: types.string,
        hostname: types.string,
        port: types.number,
        type: types.string,
        protocol: types.string,
        domain: types.string,
      }))
    )
  ),
  appAutoDiscoverList: tProp(
    types.array(
      types.object(() => ({
        addresses: types.array(types.string),
        ip: types.string,
        name: types.string,
        hostname: types.string,
        port: types.number,
        type: types.string,
        protocol: types.string,
        domain: types.string,
      }))
    ),
    () => []
  ),
}) {
  onInit = () => {
    this.setResultStatus(false);
  };

  @modelAction
  setWebsocketFails() {
    this.websocketFails += 1;
  }

  @modelAction
  setWebsocketStatus(websocketStatus: boolean) {
    this.websocketStatus = websocketStatus;
  }

  @modelAction
  setLoginStatus(loginStatus: number) {
    this.loginStatus = loginStatus;
  }

  @modelAction
  setCookie(cookie: string) {
    this.cookie = cookie;
  }

  @modelAction
  getAcs01ById(id: string) {
    return this.acs01s.find((x) => x.id === id);
  }

  @modelAction
  getAcs01AutoDiscoverByName(name: string | undefined) {
    const found = this.acs01AutoDiscoverList.find((x) => x.name === name);
    if (found) return found;
    return { name: 'nothing selected', ip: 'no ip' };
  }

  @modelAction
  getSiteById(id: string) {
    let foundSite;
    for (let i = 0; i < this.acs01s.length; i += 1) {
      foundSite = this.acs01s[i].sitesList.find((x) => x.id === id);
    }
    return foundSite;
  }

  @modelAction
  getSiteNameById(id: string) {
    let foundSite: any = 'not found';
    for (let i = 0; i < this.acs01s.length; i += 1) {
      foundSite = this.acs01s[i].sitesList.find((x) => x.id === id)?.name;
    }
    return foundSite;
  }

  @modelAction
  add(acs01: Acs01) {
    this.acs01s.push(acs01);
  }

  @modelAction
  remove(acs01: Acs01 | undefined) {
    if (typeof acs01 === 'undefined') return;
    const index = this.acs01s.indexOf(acs01);
    if (index >= 0) {
      this.acs01s.splice(index, 1);
    }
  }

  @modelAction
  getAcs01IndexById(id: string) {
    const elementPos = this.acs01s
      .map(function getId(a: Acs01) {
        return a.id;
      })
      .indexOf(id);
    return elementPos;
  }

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

  @modelAction
  setConfigured(configured: boolean) {
    this.configured = configured;
  }

  @modelAction
  setDefaultAcs01(defaultAcs01: Acs01 | number) {
    if (typeof defaultAcs01 === 'number') {
      if (defaultAcs01 === 0) {
        const rootStore = getRootStore<RootStore>(this);
        let user;
        if (typeof rootStore?.userList.loggedInUser === 'undefined') {
          user = 'No user';
        } else {
          user = rootStore?.userList.loggedInUser.name;
        }
        rootStore?.logs.addLog(
          new Log({
            type: 'Model',
            subType: 'ACS01',
            name: 'Default ACS01 removed',
            reason: `${user} removed ACS01 default configuration.`,
            user,
          })
        );
      }
      this.defaultAcs01 = undefined;
      ipcRenderer.sendToHost('mainWindow->main-keystoneSync', [
        [
          { key: 'username', value: undefined },
          { key: 'password', value: undefined },
        ],
      ]);
    } else {
      const rootStore = getRootStore<RootStore>(this);
      let user;
      if (typeof rootStore?.userList.loggedInUser === 'undefined') {
        user = 'No user';
      } else {
        user = rootStore?.userList.loggedInUser.name;
      }
      rootStore?.logs.addLog(
        new Log({
          type: 'Model',
          subType: 'ACS01',
          name: 'Default ACS01 set',
          reason: `${user} has set the ACS01 default configuration.`,
          user,
        })
      );
      ipcRenderer.sendToHost('mainWindow->main-keystoneSync', [
        [
          { key: 'username', value: defaultAcs01.username },
          { key: 'password', value: defaultAcs01.password },
        ],
      ]);
      this.defaultAcs01 = defaultAcs01;
    }
  }

  @modelAction
  removeAcs01List(acs01autodiscover: any) {
    const index = this.acs01AutoDiscoverList.indexOf(acs01autodiscover);
    if (index >= 0) {
      this.acs01AutoDiscoverList.splice(index, 1);
    }
  }

  @modelAction
  addAcs01List(acs01autodiscover: any) {
    if (typeof acs01autodiscover === 'undefined') {
      // console.log("ACS01List, autodiscover is undefined. ", acs01autodiscover);
      return;
    }
    if (
      acs01autodiscover?.name === this.defaultAcs01?.localName &&
      acs01autodiscover?.ip !== this.defaultAcs01?.localUrl
    ) {
      // console.log("THERE IS A NEW IP FOR THE DEFAULT: ", acs01autodiscover.ip);
      this.defaultAcs01?.setLocalUrl(acs01autodiscover.ip);
    } else if (
      acs01autodiscover?.name === this.defaultAcs01?.localName &&
      acs01autodiscover?.ip === this.defaultAcs01?.localUrl
    ) {
      // console.log("DEFAULT IS ONLINE NOW: ", acs01autodiscover.ip);
      this.setDiscoverStatus((this.discoverStatus += 1));
    }
    this.removeAcs01List(
      this.acs01AutoDiscoverList.find((x) => x.name === acs01autodiscover.name)
    );
    this.acs01AutoDiscoverList.push(acs01autodiscover);
  }

  @modelAction
  setDefaultApp(defaultApp: any) {
    if (typeof defaultApp === 'number') {
      if (defaultApp === 0) {
        const rootStore = getRootStore<RootStore>(this);
        let user;
        if (typeof rootStore?.userList.loggedInUser === 'undefined') {
          user = 'No user';
        } else {
          user = rootStore?.userList.loggedInUser.name;
        }
        rootStore?.logs.addLog(
          new Log({
            type: 'Model',
            subType: 'APP',
            name: 'Default APP removed',
            reason: `${user} removed APP default configuration.`,
            user,
          })
        );
      }
      this.defaultApp = undefined;
    } else {
      const rootStore = getRootStore<RootStore>(this);
      let user;
      if (typeof rootStore?.userList.loggedInUser === 'undefined') {
        user = 'No user';
      } else {
        user = rootStore?.userList.loggedInUser.name;
      }
      rootStore?.logs.addLog(
        new Log({
          type: 'Model',
          subType: 'APP',
          name: 'Default APP added',
          reason: `${user} has set the APP default configuration.`,
          user,
        })
      );
      this.defaultApp = defaultApp;
    }
  }

  @modelAction
  removeAppList(appAutodiscover: any) {
    const index = this.appAutoDiscoverList.indexOf(appAutodiscover);
    if (index >= 0) {
      this.appAutoDiscoverList.splice(index, 1);
    }
  }

  @modelAction
  addAppList(appAutodiscover: any) {
    if (typeof appAutodiscover === 'undefined') {
      console.log('AppList, autodiscover is undefined. ', appAutodiscover);
      return;
    }
    if (
      appAutodiscover?.name === this.defaultApp?.name &&
      appAutodiscover?.ip !== this.defaultApp?.ip
    ) {
      console.log(
        'THERE IS A NEW IP FOR THE DEFAULT APP: ',
        appAutodiscover.ip
      );

      this.defaultApp = {
        addresses: appAutodiscover.addresses,
        ip: appAutodiscover.ip,
        name: appAutodiscover.string,
        appType: appAutodiscover.string,
        hostname: appAutodiscover.string,
        port: appAutodiscover.number,
        type: appAutodiscover.string,
        protocol: appAutodiscover.string,
        domain: appAutodiscover.string,
      };
    } else if (
      appAutodiscover?.name === this.defaultApp?.name &&
      appAutodiscover?.ip === this.defaultApp?.ip
    ) {
      console.log('DEFAULT IS ONLINE NOW: ', appAutodiscover.ip);
      // this.setDiscoverStatus((this.discoverStatus += 1));
    }
    this.removeAppList(
      this.appAutoDiscoverList.find((x) => x.name === appAutodiscover.name)
    );
    this.appAutoDiscoverList.push(appAutodiscover);
  }

  @modelAction
  setDiscoverStatus(discoverStatus: any) {
    this.discoverStatus = discoverStatus;
  }

  @modelAction
  setAcs01List(acs01List: any) {
    this.acs01AutoDiscoverList = acs01List;
  }

  @modelAction
  setDefaultAcs01LoginOk(defaultAcs01LoginOk: boolean) {
    this.defaultAcs01LoginOk = defaultAcs01LoginOk;
  }

  @modelAction
  setResultStatus(resultStatus: boolean) {
    this.resultStatus = resultStatus;
  }

  @modelAction
  setLocalStatus(localStatus: number) {
    if (this.remoteStatus === 1 && localStatus === 1) {
      setTimeout(() => {
        if (this.remoteStatus === 1 && localStatus === 1) {
          this.setResultStatus(true);
        } else {
          this.setResultStatus(false);
        }
      }, 3000);
    } else {
      this.setResultStatus(false);
    }
    this.localStatus = localStatus;
  }

  @modelAction
  setRemoteStatus(remoteStatus: number) {
    if (remoteStatus === 1 && this.localStatus === 1) {
      setTimeout(() => {
        if (remoteStatus === 1 && this.localStatus === 1) {
          this.setResultStatus(true);
        } else {
          this.setResultStatus(false);
        }
      }, 3000);
    } else {
      this.setResultStatus(false);
    }
    this.remoteStatus = remoteStatus;
  }

  get all() {
    const all = [];
    for (let i = 0; i < this.acs01s.length; i += 1) {
      all.push(this.acs01s[i]);
    }
    return all;
  }

  @modelAction
  allCounters(siteId: string) {
    const all = [];
    for (let i = 0; i < this.acs01s.length; i += 1) {
      if (this.acs01s[i].getSiteBySiteId(siteId)?.counterList !== [])
        all.push(this.acs01s[i]);
    }
    return all;
  }

  get allKeystone() {
    return this.acs01s;
  }
}
