import {Component, inject, OnInit, ViewChild} from '@angular/core'
import {IonContent} from '@ionic/angular'
import {Observable, of} from 'rxjs'
import {IMessage} from '../../models/IMessage'
import {DatabaseService} from '../services/database.service'
import {ActivatedRoute} from '@angular/router'

@Component({
  selector: 'app-channel',
  templateUrl: './channel.page.html',
  styleUrls: ['./channel.page.scss'],
})
export class ChannelPage implements OnInit {
  @ViewChild(IonContent) content?: IonContent
  #scrollElement?: HTMLElement
  #scrollTop?: number

  channelName = 'General'
  newMessage?: string
  #floatLeft = true
  #prevUser: string = ''
  #dbService = inject(DatabaseService)
  #activatedRoute = inject(ActivatedRoute)
  messagesObservable: Observable<IMessage[]> = of([])

  constructor() {
  }

  /**
   * Send a new message to the database
   */
  sendMessage(): void {
    this.#scrollTop = this.#scrollElement?.scrollTop
    if (this.newMessage) {
      this.#dbService.sendMessage(this.channelName, this.newMessage).then()
      this.newMessage = undefined
    }
  }

  /**
   * Determine if a message should be displayed on the left or the right.
   *
   * @param i     The index of the number in the array of messages.
   * @param user  The id of the user who wrote the message.
   */
  determineFloatLeft(i: number, user: string): boolean {
    // The first message is always displayed on the left.
    if (i === 0) {
      this.#prevUser = user
      this.#floatLeft = true
    }

    // As long as the user who wrote the message doesn't change,
    // the position doesn't change either.
    if (this.#prevUser !== user) {
      this.#prevUser = user
      this.#floatLeft = !this.#floatLeft
    }
    return this.#floatLeft
  }
  ngOnInit() {
    console.log(`${this.channelName} page initialized`)
    this.channelName = this.#activatedRoute.snapshot.paramMap.get('channelName') ?? 'General'
    this.messagesObservable = this.#dbService.retrieveMessages(this.channelName)
  }

  ionViewDidEnter(): void {
    this.content?.getScrollElement().then(x => this.#scrollElement = x)
  }

  ngAfterViewChecked(): void {
    if (this.content && this.#scrollElement && this.#scrollTop) {
      this.content
          .scrollToPoint(0, this.#scrollTop)
          .then(_ => {
            this.#scrollTop = undefined
            setTimeout(() => this.content?.scrollToBottom(500), 500)
          })
    }
  }

  ngOnDestroy(): void {
    console.log(`${this.channelName} page destroyed`)
  }
}
