import { HttpHeaders, HttpParams } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { AuthService } from './auth.service';
import { HttpService } from './http.service';
import { StorageService } from './storage.service';
import { HttpClient, HttpHeaderResponse } from '@angular/common/http';
import { environment } from 'src/environments/environment';
import { Storage } from '@ionic/storage';
import { Message } from 'src/app/models/message.model';
import { Observable, Subject } from "rxjs/Rx";
import { WebsocketService } from './websocket.service';

@Injectable({
  providedIn: 'root'
})
export class ChatService {
  headers: HttpHeaders;
  options:any;
  options1:any;
  X_User_Id:any;
  X_Auth_Token:any;

  //SERVER_URL = 'wss://www.tabularium.pt/websocket';
  //public messages: Subject<any>;
  loggedUserChat:any;
  bindOnMessage: any;

  constructor(
    private http:HttpClient,
    private httpService: HttpService,
    private authService: AuthService,
    private storage: Storage,
    private storageService:StorageService,
    //private wsService: WebsocketService,
    )
    {
      this.loggedUserChat = authService.ValidatedUserChat;
      this.headers = new HttpHeaders();
      this.headers = this.headers.set('X-User-Id', this.loggedUserChat['data'].userId);
      this.headers = this.headers.set('X-Auth-Token', this.loggedUserChat['data'].authToken);
      this.options = {
        headers: this.headers,
      };

      /* this.messages = <Subject<any>>this.wsService.connect(this.SERVER_URL).map((response: MessageEvent): any => {
          let data = JSON.parse(response.data);
          console.log(data);
          return (JSON.stringify(data));
        }); */
    }

    getDocumentDetails(url:string){
      let headersc = new HttpHeaders();
      headersc = headersc.set('X-User-Id', this.loggedUserChat['data'].userId);
      headersc = headersc.set('X-Auth-Token', this.loggedUserChat['data'].authToken);
      headersc = headersc.set('Sec-Fetch-Dest', 'attachment');
      headersc = headersc.set('Sec-Fetch-Mode', 'navigate');
      headersc = headersc.set('Cookie', 'rc_uid=fsMwcNdufWvdnChj7');
      headersc = headersc.set('Cookie', 'rc_token=MLbhikLQI4xo9_vL43HqheKPPbxjag7hKfwxe9AjcvY');
      // headersc = headersc.set("Host", "www.tabularium.pt");
      // headersc = headersc.set("Origin", "http://localhost:8100");
      headersc = headersc.set('Referer', 'http://localhost:8100/');
      let optionsc = {
        headers: headersc,
        withCredentials: true
      };
      //let fullUrl = "https://www.tabularium.pt/" + url;
      return this.http.get(url, optionsc).subscribe(()=>{
        //this.fileService.viewDocumentByUrl(url)
      });
    }

    getAllChannels(){
      return this.http.get(environment.apiChatUrl+'channels.list', this.options);
    }

    getAllUserChannels(){
      return this.http.get(environment.apiChatUrl+'channels.list.joined', this.options);
    }

    getAllRooms(){
      return this.http.get(environment.apiChatUrl+'rooms.get', this.options);
    }

    getRoomInfo(roomId:any){
      let params = new HttpParams();
      params = params.set("roomId", roomId);
      let opts = {
        headers: this.headers,
        params: params
      }
      return this.http.get(environment.apiChatUrl+'rooms.info', opts);

    }
    customsRooms(params:any){
      let opts = {
        headers: this.headers,
        params: params
      }
      return this.http.get(environment.apiChatUrl+'rooms.get', opts);
    }
    getAllPrivateGroups(){
      return this.http.get(environment.apiChatUrl+'groups.list', this.options);
    }

    getAllUsers(){
      return this.http.get(environment.apiChatUrl+'users.list', this.options);
    }
    getAllConnectedUsers(){
      return this.http.get(environment.apiChatUrl+'users.presence', this.options);
    }

    //Load messages from roomId
    getAllDirectMessages(){
      return this.http.get(environment.apiChatUrl+'im.list', this.options);
    }
    //Load messages from roomId
    getRoomMessages(roomId:any){

      let params = new HttpParams();
      params = params.set("roomId", roomId);

      let opts = {
        headers: this.headers,
        params: params,
      }
      return this.http.get(environment.apiChatUrl+'im.history', opts);
    }

    sendMessage(body:any){
      let opts = {
        headers: this.headers,
      }
      return this.http.post(environment.apiChatUrl+'chat.sendMessage', body, opts);
    }

    uploadFile(formData:any, rid:string){
      let url = environment.apiChatUrl+'rooms.upload/'+rid;
      let opts = {
        headers: this.headers,
      }
      return this.http.post(url, formData, opts);
    }

    deleteMessage(body:any){
      let opts = {
        headers: this.headers,
      }
      return this.http.post(environment.apiChatUrl+'chat.delete', body, opts);
    }

    leaveRoom(body:any){
      let opts = {
        headers: this.headers,
      }
      return this.http.post(environment.apiChatUrl+'rooms.leave', body, opts);
    }
    //Load members from a chat
    getMembers(roomId:any){

      let params = new HttpParams();
      params = params.set("roomId", roomId);

      let opts = {
        headers: this.headers,
        params: params
      }
      return this.http.get(environment.apiChatUrl+'im.members', opts);
    }

    getMemberInfo(userId:string){
      let params = new HttpParams();
      params = params.set("userId", userId);

      let opts = {
        headers: this.headers,
        params: params
      }
      return this.http.get(environment.apiChatUrl+'users.info', opts);
    }

    setUserStatus(body:any){
      let opts = {
        headers: this.headers,
      }
      return this.http.post(environment.apiChatUrl+'users.setStatus', body, this.options);
    }

    removeChatRoom(body:any){
      let opts = {
        headers: this.headers,
      }
      return this.http.post(environment.apiChatUrl+'im.close', body, this.options);
    }

    createRoom(body:any){
      return this.http.post(environment.apiChatUrl+'im.create', body, this.options);
    }
    getDirectMessage(roomId:string){
      let params = new HttpParams();
      params = params.set("roomId", roomId);

      let opts = {
        headers: this.headers,
        params: params
      }
      return this.http.get(environment.apiChatUrl+'im.messages', opts);
    }

    /* GROUPS */
    addGroup(body:any){
      console.log(body);
      return this.http.post(environment.apiChatUrl+'groups.create', body, this.options);
    }
    setGroupCustomFields(body:any){
      return this.http.post(environment.apiChatUrl+'groups.setCustomFields', body, this.options);
    }

    getGroupMembers(roomId:string){
      let params = new HttpParams();
      let url=environment.apiChatUrl+'groups.members';
      params = params.set("roomId", roomId);

      let opts = {
        headers: this.headers,
        params: params
      }
      return this.http.get(url, opts);
    }

    getChannelMembers(roomId:string){
      let params = new HttpParams();
      let url=environment.apiChatUrl+'channels.members';
      params = params.set("roomId", roomId);

      let opts = {
        headers: this.headers,
        params: params
      }
      return this.http.get(url, opts);
    }
    /* GROUP MESSAGES */
    getPrivateGroupMessages(roomId:any){

      let params = new HttpParams();
      params = params.set("roomId", roomId);

      let opts = {
        headers: this.headers,
        params: params
      }
      return this.http.get(environment.apiChatUrl+'groups.history', opts);
    }
    getPublicGroupMessages(roomId:any){
      let params = new HttpParams();
      params = params.set("roomId", roomId);

      let opts = {
        headers: this.headers,
        params: params
      }
      return this.http.get(environment.apiChatUrl+'channels.history', opts);
    }
    closeGroup(body:any){
      return this.http.post(environment.apiChatUrl+'groups.close', body, this.options);
    }
    closeChannel(body:any){
      return this.http.post(environment.apiChatUrl+'channels.close', body, this.options);
    }
    leaveGroup(body:any){
      return this.http.post(environment.apiChatUrl+'groups.leave', body, this.options);
    }
    leaveChannel(body:any){
      return this.http.post(environment.apiChatUrl+'channels.leave', body, this.options);
    }
    removeChannelMember(body:any){
      let opts = {
        headers: this.headers,
      }
      return this.http.post(environment.apiChatUrl+'channels.kick', body, opts);
    }

    deleteGroup(body:any){
      return this.http.post(environment.apiChatUrl+'groups.delete', body, this.options);
    }

    deleteChannel(body:any){
      return this.http.post(environment.apiChatUrl+'channels.delete', body, this.options);
    }
    addUserToGroup(body:any){
      return this.http.post(environment.apiChatUrl+'groups.invite', body, this.options);
    }
    getGroupInfo(roomId:any){
      let params = new HttpParams();
      params = params.set("roomId", roomId);

      let opts = {
        headers: this.headers,
        params: params
      }
      return this.http.get(environment.apiChatUrl+'groups.info', opts);
    }
    renameGroup(body:any){
      return this.http.post(environment.apiChatUrl+'groups.rename', body, this.options);
    }
    removeGroupMember(body:any){
      let opts = {
        headers: this.headers,
      }
      return this.http.post(environment.apiChatUrl+'groups.kick', body, opts);
    }

    async subscribe(roomId:any) {
      console.log('Subcrive')
      let params = new HttpParams();
      params = params.set("roomId", roomId);
      let opts = {
        headers: this.headers,
        params: params
      }

      this.http.get(environment.apiChatUrl+'im.messages', opts).subscribe(async res => {
        console.log("Subcrive", res)

        if (res == 502) {
          // Connection timeout
          // happens when the connection was pending for too long
          // let's reconnect
          await this.subscribe(roomId);
        } else if (res != 200) {
          // Show Error
          //showMessage(response.statusText);
          this.getRoomMessages(roomId)
          // Reconnect in one second
          await new Promise(resolve => setTimeout(resolve, 1000));
          await this.subscribe(roomId);
        } else {
          // Got message
          //let message = await response.text();
          this.getRoomMessages(roomId)
          await this.subscribe(roomId);
        }

      })


    }

}
