import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http';
import { Observable, BehaviorSubject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class ControllerService {

  constructor(public httpClient: HttpClient) {
  }
  
  // Connection
  APIEndpoint: String = "86.87.42.42:1337";
  APIAuthToken: String = "f8c85565-ece7-471e-999f-9bb6a7b61a4c";
  public echoConnectionError: BehaviorSubject<Boolean> = new BehaviorSubject<Boolean>(false);

  // Data
  public echoDevices: BehaviorSubject<Object> = new BehaviorSubject<Object>({});
  public echoClimateLog: BehaviorSubject<Object> = new BehaviorSubject<Object>({});
  public echoLightLog: BehaviorSubject<Object> = new BehaviorSubject<Object>({});

  // Devices
  public echoDeviceUUIDS: Object = {
    'Main Light' : '9472-4f60',
    'Main Sun Blinds': 'b039-471a',
    'Main Air Conditioner': '70c4-40d2',

    'Main Climate Sensor': 'aa50-48fd',
    'Main Movement Sensor': 'a328-4229',
    'Main Light Sensor': 'be0c-4bc7',
    'Main Bed LED Lights': '34gr-54jf'
  }

  updateAllData = async () => {
    await this.updateEchoDeviceData();
    await this.updateEchoClimateLog();
    await this.updateEchoLightLog();
    return true;
  }

  updateEchoDeviceData = async () => {
    try {
      let headers = new HttpHeaders({
        'Accept': 'application/json',
        'Content-Type': 'application/json',
        'Authorization': 'Bearer ' + this.APIAuthToken
      })

      let response = await this.httpClient.get(`http://${this.APIEndpoint}/devices`, {headers: headers}).toPromise();

      console.log("UpdateEchoDevices Response", response);

      if(response['status'] == "success") {
        let newData = {};

        for (let key in response['data']) {
          let device = response['data'][key];
          newData[device['uuid']] = device;
        }

        this.echoDevices.next(newData);

        return true;
      } else {
        return false;
      }

    } catch (error) {
      this.echoConnectionError.next(true);
      console.error("UpdateEchoDevices Error Response", error);
      return false;
    }
  }

  updateEchoClimateLog = async () => {
    try {
      let headers = new HttpHeaders({
        'Accept': 'application/json',
        'Content-Type': 'application/json',
        'Authorization': 'Bearer ' + this.APIAuthToken
      })

      let body = {
        'uuid': this.echoDeviceUUIDS['Main Climate Sensor'],
        'action': 'get_climate_data'
      }

      let response = await this.httpClient.post(`http://${this.APIEndpoint}/device`, body, {headers: headers}).toPromise();

      console.log("GetClimateData Response", response);

      if(response['status'] == "success") { 
        let newData = response['data'][0];
        this.echoClimateLog.next(newData);
      } else {
        return false;
      }

      return true;
    } catch (error) {
      this.echoConnectionError.next(true);
      console.error("GetClimateData Error Response", error);
      return false;
    }
  }

  updateEchoLightLog = async () => {
    try {
      let headers = new HttpHeaders({
        'Accept': 'application/json',
        'Content-Type': 'application/json',
        'Authorization': 'Bearer ' + this.APIAuthToken
      })

      let body = {
        'uuid': this.echoDeviceUUIDS['Main Light Sensor'], // Main Light Sensor
        'action': 'get_light_data'
      }

      let response = await this.httpClient.post(`http://${this.APIEndpoint}/device`, body, {headers: headers}).toPromise();

      console.log("GetLightData Response", response);

      if(response['status'] == "success") { 
        let newData = response['data'][0];
        this.echoLightLog.next(newData);
      } else {
        return false;
      }

      return true;
    } catch (error) {
      this.echoConnectionError.next(true);
      console.error("GetLightData Error Response", error);
      return false;
    }
  }

  handleDeviceAction = async (uuid, action, data = {}) => {
    try {
      let headers = new HttpHeaders({
        'Accept': 'application/json',
        'Content-Type': 'application/json',
        'Authorization': 'Bearer ' + this.APIAuthToken
      })

      let body = {
        'uuid': uuid,
        'action': action,
        'data': data
      }

      console.log('HandleDeviceAction Request', body);

      let response = await this.httpClient.post(`http://${this.APIEndpoint}/device`, body, {headers: headers}).toPromise();

      console.log("HandleDeviceAction Response", response);

      return response;
    } catch (error) {

      this.echoConnectionError.next(true);
      console.error("HandleDeviceAction Error Response", error);
      return false;
      
    } finally {
      // Update Data
      await this.updateEchoDeviceData();
    }
  }

}
