import { Injectable } from '@angular/core';
import { SessionStore } from 'src/app/store/session.service';
import { v4 as uuidv4 } from 'uuid'
import { BackgroundService } from '../background.service';
import { environment } from 'src/environments/environment';
import { EventTrigger } from '../eventTrigger.service'

export interface wss {

  url: string,
  type: 'reflect' | 'emit'
  header: {
    id: string
    bluePrint: string,
    jwt: string
  }

}

@Injectable({
  providedIn: 'root'
})
class SynchroService {
 /*  [x: string]: any;

  private connection!: WebSocket;
  private id: string = uuidv4();
  public conected = false
  private url: string = ''
  callback = function () { }
  private _connected = false;
  private eventtrigger: EventTrigger;
  private BackgroundService = new BackgroundService()
  callBacks: {
    type: 'Offline' | 'Online' | 'Onmessage' | 'Chat' | 'Notification' | 'Notifications' | '',
    object?: string
    funx: Function
  }[] = []
  private msgQueue = []

  constructor() {
    // alert(SessionStore.user.FullName)
  }

  get connected() {
    return this._connected
  }

  setUrl() {

    let header = {
      id: '1234',
      bluePrint: '12312123',
      jwt: uuidv4()
    }

    let wss: wss = {
      header,
      url: 'wss://sychro-offline.herokuapp.com/ws/some_url/',
      type: 'reflect'
    }

    this.url = `${wss.url}${wss.header.id}/${wss.header.jwt}/${wss.header.bluePrint}/${this.id}/`
  }

  registerCallback(type: 'Offline' | 'Online' | 'Onmessage' | 'Chat' | 'Notifications' | 'Notification', funx: Function, object = '') {
    this.callBacks.push({
      type,
      funx,
      object
    })
  }

  connect() {

    this.connection = new WebSocket(this.url);
    // bind function
    this.connection.onopen = this.onopen;
    this.connection.onmessage = this.onmessage;
    this.connection.onclose = this.onclose;
    this.connection.onerror = this.onerror;
  }

  private onopen = () => {



    //if (this._connected === true) {
      //this.BackgroundService.online()
      console.log('Online', this._connected)
      this.callBacks.forEach((e) => {
        if (e.type == 'Online') {
          e.funx()
        }
      })
    //}

    console.log('open ======================= welcome to socket server')

    this._connected = true

    // send all saved data due to internet connection
    this.msgQueue.forEach((item, index, object) => {
      this.$send(item);
      object.splice(index, 1);
    })

  }

  public $send(object: any) {

    if (!this._connected) { // save data to send when back online
      this.msgQueue.push(object)
    }

    let payload = {
      message: JSON.stringify(object) || '{"person.adress.country":"1Angola"}',
      username: SessionStore.user.FullName,
      idConnection: this.id
    }


    let sendData = JSON.stringify(payload);
    console.log(sendData)

    this.connection.send(sendData);
  }

  private onmessage = async (event: any) => {


    let data = JSON.parse(event.data)
    let payload = JSON.parse(data.message)
    payload.message = JSON.parse(payload.message)
    const idConnection = payload.idConnection
    const username = payload.username

    if (idConnection != this.id) {

      if (window['platform'].is('desktop') || this.platform.is('mobileweb')) { }
      else return false

      if (environment.production) return false

      this.callBacks.forEach((e) => {

        if (payload.message[0]) {
          if (payload.message[0].Service && payload.message[0].Object && payload.message[0].IdObject) {
            if (e.type == '' && !e.object) {
              if (username == SessionStore.user.FullName) {
                e.funx(payload.message, data)
              }
            }

            if (e.type == 'Notifications') {
              e.funx(payload.message, data)
            }

          }
        } else if (payload.message.Service && payload.message.Object && payload.message.IdObject) {
          if (e.type == 'Notification' && e.object == payload.message.Object || e.type == 'Notification' && e.object == 'any') {
            e.funx(payload.message, data)
          }
        }

      })

    }
    this.callback()
  }

  private onclose = (event: any) => {
    console.log('Websocket close')
    setTimeout(() => {
      if (event.wasClean) {
        console.log(`[close] Connection closed cleanly, code=${event.code} reason=${event.reason}`);
      } else {
        // e.g. server process killed or network down
        // event.code is usually 1006 in this case
        console.log('[close] Connection died');
        console.log('Reconnect')



       // if (this._connected === false) {
         // this.BackgroundService.offline();
          console.log('Offline', this._connected)
          this.callBacks.forEach((e) => {
            if (e.type == 'Offline') {
              e.funx()
            }
          })
        //}


        // status
        this._connected = false
        // reconnect
        this.connect()

      }
    }, 100);
  }

  private onerror = (event: any) => {
    console.log(`[error] ${event.message}`);
  } */
}


/* export const synchro = new SynchroService()
synchro.setUrl()
synchro.connect()

window['synchro'] = synchro */