import { AfterViewChecked, AfterViewInit, ChangeDetectorRef, Component, ElementRef, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router'
import { GestureController, Gesture, ModalController, NavParams, PopoverController, IonSlides, Platform } from '@ionic/angular';
import { map } from 'rxjs/operators';
import { ViewDocumentPage } from 'src/app/modals/view-document/view-document.page';
import { EventPerson } from 'src/app/models/eventperson.model';
import { ExpedientTaskModalPageNavParamsTask } from 'src/app/models/ExpedientTaskModalPage';
import { SearchDocumentDetails, SearchFolderDetails } from 'src/app/models/search-document';
import { ContactsPage } from 'src/app/pages/chat/messages/contacts/contacts.page';
import { AlertService } from 'src/app/services/alert.service';
import { AuthService } from 'src/app/services/auth.service';
import { ChatService } from 'src/app/services/chat.service';
import { FileService } from 'src/app/services/functions/file.service';
import { ProcessesService } from 'src/app/services/processes.service';
import { ToastService } from 'src/app/services/toast.service';
import { NewEventPage } from 'src/app/shared/agenda/new-event/new-event.page';
import { ChatOptionsPopoverPage } from 'src/app/shared/popover/chat-options-popover/chat-options-popover.page';
import { MessagesOptionsPage } from 'src/app/shared/popover/messages-options/messages-options.page';
import { ChatMessageStore } from 'src/app/store/chat/chat-message.service';
import { ChatUserStorage } from 'src/app/store/chat/chat-user.service';
import { environment } from 'src/environments/environment';
import { ThemeService } from 'src/app/services/theme.service'
import { Filesystem, Directory, Encoding } from '@capacitor/filesystem';
import { VoiceRecorder, VoiceRecorderPlugin, RecordingData, GenericResponse, CurrentRecordingStatus } from 'capacitor-voice-recorder';
import { Haptics, ImpactStyle } from '@capacitor/haptics';
import { PreviewCameraPage } from 'src/app/modals/preview-camera/preview-camera.page';
import { SqliteService } from 'src/app/services/sqlite.service';
import { elementAt } from 'rxjs-compat/operator/elementAt';
import { ViewMediaPage } from 'src/app/modals/view-media/view-media.page';
import { ViewEventPage } from 'src/app/modals/view-event/view-event.page';

const IMAGE_DIR = 'stored-images';

@Component({
  selector: 'app-messages',
  templateUrl: './messages.page.html',
  styleUrls: ['./messages.page.scss'],
})
export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
  showLoader: boolean;

  @ViewChild('scrollMe') private myScrollContainer: ElementRef;
  /*   @ViewChild('messageContainer') messageContainer: ElementRef; */
  @ViewChild('rectangle') private rectangle: ElementRef;

  canvas: any
  ctx: any
  loggedUser: any;
  message = '';
  messages: any;
  userPresence = '';
  dmUsers: any;
  roomId: string;
  el: any;
  members: any;
  scrollingOnce: boolean = true;

  chatMessageStore = ChatMessageStore;
  chatUserStorage = ChatUserStorage;

  private scrollChangeCallback: () => void;
  currentPosition: any;
  startPosition: number;
  scrollToBottomBtn = false;
  attendees: EventPerson[] = [];
  longPressActive = false;
  showMessageOptions = false;
  selectedMsgId: string;

  dicIndex = 0;
  task: ExpedientTaskModalPageNavParamsTask;
  LoadedDocument: any = null;

  recording = false;
  storedFileNames = [];
  durationDisplay = '';
  duration = 0;
  @ViewChild('recordbtn', { read: ElementRef }) recordBtn: ElementRef;
  myAudio: any;

  constructor(
    public popoverController: PopoverController,
    private modalController: ModalController,
    private navParams: NavParams,
    private chatService: ChatService,
    private authService: AuthService,
    private alertService: AlertService,
    private toastService: ToastService,
    private route: Router,
    private activatedRoute: ActivatedRoute,
    private fileService: FileService,
    private gestureController: GestureController,
    private processes: ProcessesService,
    public ThemeService: ThemeService,
    private changeDetectorRef: ChangeDetectorRef,
    private platform: Platform,
    private sqlservice: SqliteService
  ) {
    this.loggedUser = authService.ValidatedUserChat['data'];
    this.roomId = this.navParams.get('roomId');
    console.log('ROOM ID', this.roomId)

    window.onresize = (event) => {
      if (window.innerWidth > 701) {
        this.modalController.dismiss();
      }
    };
  }

  ngOnInit() {
    this.load();
    this.setStatus('online');

    //this.loadFiles();
    VoiceRecorder.requestAudioRecordingPermission();
    Filesystem.mkdir({
      path: IMAGE_DIR,
      directory: Directory.Data,
      recursive: true
    });
    this.getRoomMessageDB(this.roomId);
  }

  ngAfterViewInit() {
    this.scrollChangeCallback = () => this.onContentScrolled(event);
    window.addEventListener('scroll', this.scrollChangeCallback, true);

    const longpress = this.gestureController.create({
      el: this.recordBtn.nativeElement,
      threshold: 0,
      gestureName: 'long-press',
      onStart: ev => {
        Haptics.impact({ style: ImpactStyle.Light })
        this.startRecording();
        this.calculateDuration();
      },
      onEnd: ev => {
        Haptics.impact({ style: ImpactStyle.Light })
        this.stopRecording();
      }
    }, true);
    longpress.enable();
  }

  calculateDuration() {
    if (!this.recording) {
      this.duration = 0;
      this.durationDisplay = '';
      return;
    }
    this.duration += 1;
    const minutes = Math.floor(this.duration / 60);
    const seconds = (this.duration % 60).toString().padStart(2, '0');
    this.durationDisplay = `${minutes}:${seconds}`;

    setTimeout(() => {
      this.calculateDuration();
    }, 1000)
  }

  async loadFiles() {
    Filesystem.readdir({
      path: '',
      directory: Directory.Data
    }).then(result => {
      console.log(result);
      const temp: any[] = result.files.reverse();
      this.storedFileNames = temp[0];
      console.log(this.storedFileNames);

    })
  }

  startRecording() {
    if (this.recording) {
      return;
    }
    this.recording = true;
    VoiceRecorder.startRecording();
  }

  stopRecording() {
    if (!this.recording) {
      return;
    }
    this.recording = false;
    VoiceRecorder.stopRecording().then(async (result: RecordingData) => {
      this.recording = false;
      if (result.value && result.value.recordDataBase64) {
        const recordData = result.value.recordDataBase64;
        console.log(recordData);
        this.myAudio = recordData;
        const fileName = new Date().getTime() + ".wav";
        await Filesystem.writeFile({
          path: fileName,
          directory: Directory.Data,
          data: recordData,
        })
      }
    })

  }

  async playFile(fileName?: any) {
    const audioFile = await Filesystem.readFile({
      path: fileName,
      directory: Directory.Data
    })
    console.log(audioFile);
    const base64sound = audioFile.data;

    const audioRef = new Audio(`data:audio/aac;base64,${base64sound}`)
    audioRef.oncanplaythrough = () => audioRef.play();
    audioRef.load();

  }

  handlePress(id?: string) {
    this.selectedMsgId = id;
    this.showMessageOptions = true;
  }

  handleClick() {
    this.showMessageOptions = false;
    this.selectedMsgId = "";
  }

  deleteMessage(msgId: string) {
    let body = {
      "roomId": this.roomId,
      "msgId": msgId,
      "asUser": false,
    }
    if (msgId) {
      this.alertService.confirmDeleteMessage(body);
    }
    else {
      this.toastService.badRequest('Não foi possível apagar');
    }
    this.showMessageOptions = false;
    this.selectedMsgId = "";
  }

  setStatus(status: string) {
    let body = {
      message: '',
      status: status,
    }
    this.chatService.setUserStatus(body).subscribe(res => {
      console.log(res);
    })
  }

  notImplemented() {
    this.alertService.presentAlert('Funcionalidade em desenvolvimento');
  }

  close() {
    this.modalController.dismiss();
  }

  load() {
    this.serverLongPull();
    this.getChatMembers();
  }

  doRefresh(ev: any) {
    this.load();
    ev.target.complete();
  }

  scrollToBottom(): void {
    try {
      if (this.scrollingOnce) {
        this.myScrollContainer.nativeElement.scrollTop = this.myScrollContainer.nativeElement.scrollHeight;
        //this.scrollingOnce = false;
      }
    } catch (err) { }
  }

  scrollToBottomClicked(): void {
    try {
      this.myScrollContainer.nativeElement.scrollTop = this.myScrollContainer.nativeElement.scrollHeight;
    } catch (err) { }
  }

  async goToEvent(eventId: any) {
    let classs;
    if (window.innerWidth < 701) {
      classs = 'modal modal-desktop'
    } else {
      classs = 'modal modal-desktop showAsideOptions'
    }
    const modal = await this.modalController.create({
      component: ViewEventPage,
      componentProps: {
        eventId: eventId,
      },
      cssClass: classs,
    });
    await modal.present();
    modal.onDidDismiss().then((res) => {
      console.log(res);
    });
  }

  onContentScrolled(e) {
    this.startPosition = e.srcElement.scrollTop;
    let scroll = e.srcElement.scrollTop;
    let windowHeight = e.srcElement.scrollHeight;
    let containerHeight = windowHeight - e.srcElement.clientHeight;

    if (scroll > this.currentPosition) {
      //alert('BOTTOM');
    } else {
      //alert('UP');
      this.scrollingOnce = false;
    }
    if ((containerHeight - 100) > scroll) {
      this.scrollToBottomBtn = true;
    }
    else {
      this.scrollToBottomBtn = false;
    }
    this.currentPosition = scroll;

  }

  ngOnDestroy() {
    window.removeEventListener('scroll', this.scrollChangeCallback, true);
  }



  sendMessage() {
    let body = {
      "message":
      {
        "rid": this.roomId, "msg": this.message
      }
    }
    this.chatService.sendMessage(body).subscribe(res => {
      //this.loadMessages();
      this.scrollingOnce = true;
    });
    this.message = "";
  }

  loadMessages() {
    this.showLoader = true;
    const roomId = this.roomId;

    this.chatService.getRoomMessages(this.roomId).subscribe(res => {
      console.log(res);
      this.messages = res['messages'].reverse();
      this.chatMessageStore.add(roomId, this.messages)
      console.log(this.messages);
      this.showLoader = false;
    })
  }

  viewDocument(file: any, url?: string) {
    console.log(file);

    if (file.type == "application/webtrix") {
      this.openViewDocumentModal(file);
    }
    else {
      let fullUrl = "https://www.tabularium.pt" + url;
      this.fileService.viewDocumentByUrl(fullUrl);
    }
  }

  docIndex(index: number) {
    this.dicIndex = index
  }

  async openViewDocumentModal(file: any) {

    let task = {
      serialNumber: '',
      taskStartDate: '',
      isEvent: true,
      workflowInstanceDataFields: {
        FolderID: '',
        Subject: file.Assunto,
        SourceSecFsID: file.ApplicationId,
        SourceType: 'DOC',
        SourceID: file.DocId,
        DispatchNumber: ''
      }
    }

    let doc = {
      "Id": "",
      "ParentId": "",
      "Source": 1,
      "ApplicationId": file.ApplicationId,
      "CreateDate": "",
      "Data": null,
      "Description": "",
      "Link": null,
      "SourceId": file.DocId,
      "SourceName": file.Assunto,
      "Stakeholders": "",
    }

    const modal = await this.modalController.create({
      component: ViewDocumentPage,
      componentProps: {
        trustedUrl: '',
        file: {
          title: file.Assunto,
          url: '',
          title_link: '',
        },
        Document: doc,
        applicationId: file.ApplicationId,
        docId: file.DocId,
        folderId: '',
        task: task
      },
      cssClass: 'modal modal-desktop'
    });
    await modal.present();
  }

  getChatMembers() {
    this.showLoader = true;
    this.chatService.getMembers(this.roomId).subscribe(res => {
      this.members = res['members'];
      this.dmUsers = res['members'].filter(data => data.username != this.loggedUser.me.username)
      console.log(res);
      console.log(this.dmUsers);
      this.showLoader = false;
    });
  }

  showDateDuration(start: any) {
    let end;
    end = new Date();
    start = new Date(start);
    let customizedDate;

    const totalSeconds = Math.floor((end - (start)) / 1000);;
    const totalMinutes = Math.floor(totalSeconds / 60);
    const totalHours = Math.floor(totalMinutes / 60);
    const totalDays = Math.floor(totalHours / 24);

    const hours = totalHours - (totalDays * 24);
    const minutes = totalMinutes - (totalDays * 24 * 60) - (hours * 60);
    const seconds = totalSeconds - (totalDays * 24 * 60 * 60) - (hours * 60 * 60) - (minutes * 60);

    if (totalDays == 0) {
      if (start.getDate() == new Date().getDate()) {
        let time = start.getHours() + ":" + this.addZero(start.getUTCMinutes());
        return time;
      }
      else {
        return 'Ontem';
      }
    }
    else {
      let date = start.getDate() + "/" + (start.getMonth() + 1) + "/" + start.getFullYear();
      return date;
    }
  }

  addZero(i) {
    if (i < 10) {
      i = "0" + i;
    }
    return i;
  }

  async openMessagesOptions(ev?: any) {
    const popover = await this.popoverController.create({
      component: MessagesOptionsPage,
      componentProps: {
        roomId: this.roomId,
      },
      cssClass: 'messages-options',
      event: ev,
      translucent: true,
    });
    return await popover.present();
  }

  async addContacts() {
    const modal = await this.modalController.create({
      component: ContactsPage,
      componentProps: {},
      cssClass: 'contacts',
      backdropDismiss: false
    });

    await modal.present();

    modal.onDidDismiss();
  }

  async bookMeeting() {
    this.attendees = this.members.map((val) => {
      return {
        Name: val.name,
        EmailAddress: val.username + "@" + environment.domain,
        IsRequired: "true",
      }
    });
    console.log(this.attendees);
    this.popoverController.dismiss();
    if (window.innerWidth <= 1024) {
      const modal = await this.modalController.create({
        component: NewEventPage,
        componentProps: {
          attendees: this.attendees,
        },
        cssClass: 'modal  modal-desktop',
        backdropDismiss: false
      });
      await modal.present();
      modal.onDidDismiss().then((data) => {
        if (data) {

        }
      });
    }
  }

  async openChatOptions(ev?: any) {
    const roomId = this.roomId
    console.log(this.members);

    const popover = await this.popoverController.create({
      component: ChatOptionsPopoverPage,
      cssClass: 'chat-options-popover',
      event: ev,
      componentProps: {
        room: this.roomId,
        members: this.members,
        eventSelectedDate: new Date(),
      },
      translucent: true
    });
    await popover.present();
    popover.onDidDismiss().then((res) => {
      console.log(res['data']);
      if (res['data'] == 'meeting') {
        this.bookMeeting();
      }
      else if (res['data'] == 'take-picture') {
        this.fileService.addCameraPictureToChat(roomId);
        //this.loadPicture();
      }
      else if (res['data'] == 'add-picture') {
        this.fileService.addPictureToChatMobile(roomId);
        //this.loadPicture();
      }
      else if (res['data'] == 'add-document') {
        this.fileService.addDocumentToChat(this.roomId);
        //this.loadDocument();
      }
      else if (res['data'] == 'documentoGestaoDocumental') {

        this.fileService.addDocGestaoDocumentalToChat(this.roomId);
        //this.addDocGestaoDocumental();
      }
      this.loadMessages();

    });
  }

  getRoomMessageDB(roomId) {
    if (this.platform.is('desktop') || this.platform.is('mobileweb')) {
    } else {
      this.sqlservice.getAllChatMSG(roomId).then((msg: any) => {
        let chatmsgArray = [];
        let array = []
        msg.forEach(element => {
          console.log('CHANNEL ELEMENT', element.channels)

          let msgChat = {
            _id: element.Id,
            attachments: this.isJson(element.Attachments),
            channels: this.isJson(element.Channels),
            file: this.isJson(element.File),
            mentions: this.isJson(element.Mentions),
            msg: element.Msg,
            rid: element.Rid,
            ts: element.Ts,
            u: this.isJson(element.U),
            _updatedAt: element.UpdatedAt
          }

          chatmsgArray.push(msgChat)
        });

        this.messages = chatmsgArray.reverse();
        console.log('CHAT MSG FROM DB', chatmsgArray)
      })
    }
  }

  isJson(str) {
    try {
      JSON.parse(str);
    } catch (e) {
      return "";
    }
    return JSON.parse(str);
  }



  transformDataMSG(res) {
    if (this.platform.is('desktop') || this.platform.is('mobileweb')) {
    } else {
      res.forEach(element => {
        let chatmsg = {
          _id: element._id,
          attachments: element.attachments,
          channels: element.channels,
          file: element.file,
          mentions: element.mentions,
          msg: element.msg,
          rid: element.rid,
          ts: element.ts,
          u: element.u,
          _updatedAt: element._updatedAt
        }

        this.sqlservice.addChatMSG(chatmsg)
      });
    }

  }

  async serverLongPull() {

    const roomId = this.roomId

    /* this.chatService.getRoomMessages(roomId).subscribe(res=>{
      console.log(res);

    }) */


    this.chatService.getRoomMessages(roomId).subscribe(async res => {
      console.log("Chat message", res)

      this.transformDataMSG(res['messages'])
      this.getRoomMessageDB(this.roomId);


      if (res == 502) {
        // Connection timeout
        // happens when the synchro was pending for too long
        // let's reconnect
        await this.serverLongPull();
      }
      else if (res != 200) {
        // Show Error
        //showMessage(response.statusText);
        //this.loadMessages()
        if (this.platform.is('desktop') || this.platform.is('mobileweb')) {
          this.messages = res['messages'].reverse();
          this.chatMessageStore.add(roomId, this.messages)
        }


        //console.log(this.messages);
        // Reconnect in one second
        if (this.route.url != "/home/chat") {
          console.log("Timer message stop")
        } else {
          //Check if modal is opened
          if (document.querySelector('.isMessagesChatOpened')) {
            await new Promise(resolve => setTimeout(resolve, 5000));
            await this.serverLongPull();
            //console.log('Timer message running')
          }
        }

      } else {
        // Got message
        //let message = await response.text();
        //this.loadMessages()
        await this.serverLongPull();
      }
    });
  }


  sliderOpts = {
    zoom: false,
    slidesPerView: 1.5,
    spaceBetween: 20,
    centeredSlides: true
  };
  zoomActive = false;
  zoomScale = 1;

  sliderZoomOpts = {
    allowSlidePrev: false,
    allowSlideNext: false,
    zoom: {
      maxRatio: 5
    },
    on: {
      zoomChange: (scale, imageEl, slideEl) => {
        this.zoomActive = true;
        this.zoomScale = scale / 5;
        this.changeDetectorRef.detectChanges();
      }
    }
  }

  async touchEnd(zoomslides: IonSlides, card) {
    // Zoom back to normal
    const slider = await zoomslides.getSwiper();
    const zoom = slider.zoom;
    zoom.out();

    // Card back to normal
    card.el.style['z-index'] = 9;

    this.zoomActive = false;
    this.changeDetectorRef.detectChanges();
  }

  touchStart(card) {
    // Make card appear above backdrop
    card.el.style['z-index'] = 11;
  }


  async openPreview(msg) {
    const modal = await this.modalController.create({
      component: ViewMediaPage,
      cssClass: 'modal modal-desktop',
      componentProps: {
        image: msg.attachments[0].image_url,
        username: msg.u.name,
        _updatedAt: msg._updatedAt,
      }
    });
    modal.present();
  }


  imageSize(img) {
    var canvas = document.createElement('canvas');
    var ctx = canvas.getContext('2d');
    canvas.width = 300
    canvas.height = 234
    ctx.drawImage(img.attachments[0].image_url, 0, 0, 300, 234);
    document.body.appendChild(canvas);
  }

  getPicture(img) {
    var canvas = document.createElement('canvas');
    var ctx = canvas.getContext('2d');
    canvas.width = 300
    canvas.height = 234
    ctx.drawImage(img.attachments[0].image_url, 0, 0, 300, 234);
    document.body.appendChild(canvas);

  }

  // async ShareEmail(msg){
  //   // Check if sharing via email is supported
  //   await Share.share({
  //     title:  msg.u.username,
  //     text:  msg._updatedAt,
  //     url: msg.attachments[0].image_url,
  //     dialogTitle: 'Share with buddies',
  //   });
  // }
}



