<template>
  <div class="apselui chat--frame">
    <MessagesPane
      :chatEngine=chatEngine
      :messages=messages
      :userId=userId
      :bus=this
      :loading=loading
    />
    <Input 
      v-on:new_message=sendMessage
    />
  </div>
</template>

<script lang="ts">
import { Component, Prop, Vue, Watch } from 'vue-property-decorator';
import Input from './Input.vue';
import MessagesPane from './MessagesPane.vue';
import ImageViewer from './ImageViewer.vue';
import { MessageList, InputMessage, Message, Person, Attachment } from './type';
import ChatEngine from './ChatEngine';
import { ChatInfo, ChatNewMessage } from '@apsel/apsel-api-ts-axios';

@Component({
  components: {
    Input,
    MessagesPane,
    ImageViewer,
  },
})
export default class Chat extends Vue {
  @Prop() private chatEngine!: ChatEngine;

  private chatId: string = '';
  private chat!: ChatInfo;
  private userId!: string;
  private loading: Boolean = false;

  private recipientId!: string;
  // private messages: MessageList = new MessageList([]);
  private messages: any = [];

  private currentPreview: Message | null = null;

  /**
   * Send a message
   */
  public async sendMessage(input: InputMessage) {

    console.info('[Chat] Send a chat message');

    // Generate a temporary message to put in the list
    const message = Message.fromInputMessage(input,
                                             this.userId,
                                             this.recipientId);
    // Add the message to the message list for immediate feedback
    this.messages.addMessage(message);


    // Create the send message for the API
    const chatNewMessage = {
      type: message.type,
      content: message.content,
      attachment: message.attachment,
      replyTo: undefined,  // FIXME
      actions: undefined,  // FIXME
    } as ChatNewMessage;

    console.info('[Chat] Sending messsage', JSON.stringify( chatNewMessage) );
    // Send the message
    const returnedMessage = await this.chatEngine.sendMessage(this.chatId, chatNewMessage);

    if (returnedMessage == null) {
      // TODO: handled failed message with a retry
      console.error('[Chat] failed to send message');
    }
    console.info('[Chat] Message sent');
  }

  /**
   * Load the chat and the messages
   */
  public async load() {
    this.$emit('loading', { state: true });
    this.loading = true;
    // Loading chat
    const chat = await this.chatEngine.getChat(this.chatId);
    if (!chat) {
      // Loading failed.
      this.$root.$router.push({ path: '/chat', replace: false });
      return;
    }

    this.chat = chat as ChatInfo;
    console.info('[Chat] Chat loaded ', this.chat);

    // get the messages
    const messageList = await this.chatEngine.getMessageList(chat.id);

    if (messageList == null) {
      console.info('[Chat] failed to load message list for ' + chat.id);
      return;
    }
    // await setTimeout(()=>{}, 2000);
    // this.messages.length = 0;
    this.messages = messageList;
    this.loading = false;
    console.info('[Chat] Message list loaded', messageList);

    this.$emit('loading', { state: false });
  }

  public created() {
    // Get the userId from the chatEngine (for reactivity purpose)
    console.log(this.chatEngine);
    this.userId = this.chatEngine.userId;
    this.chatId = this.$root.$route.params.id;
  }

  public mounted() {

    // Tell Vue to load the list of messages later
    this.$nextTick(() => {
      this.load();
    });

    /** Register document viewer */
    this.$on('preview-document', (message: Message) => {
        console.log('[Chat] Preview document', message);
        if (message.attachment && message.attachment.length > 0) {
          const url = this.chatEngine.urlForAttachment(message.attachment[0]);
          window.open(url, 'blank');
        }
    });

    /** Register image viewer */
    this.$on('preview-image', (message: Message) => {
      console.log('[Chat] Preview image', message);

      if (message.attachment && message.attachment.length > 0) {
        const url = this.chatEngine.urlForAttachment(message.attachment[0]);

        // @ts-ignore
        this.$zoom(url, {
          allowZoom:          true,
          autoScale:          true,
          closeOnClickModal:  true,
        });
      }

    });
  }

  private updated() {
    // this.load();
  }

  // @Watch('$route') route_changed(x: any, y: any) {
  //   this.$nextTick(() => {
  //     this.load();
  //   });
  // }
  // @Watch('loading') loading_changed(x: any, y: any) {
  //   console.warn('loading', this.loading);
  // }

}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="scss">
@import './chat.scss'

</style>
