import { Component, OnChanges, OnDestroy, OnInit } from "@angular/core";
import { ActivatedRoute, Router, NavigationEnd } from "@angular/router";
import { marker } from "@biesbjerg/ngx-translate-extract-marker";
import { base64 } from "rfc4648";
import { AccountService } from "src/app/shared/server-services/account.service";
import { AuthService } from "src/app/shared/server-services/auth.service";
import { DialogueService } from "src/app/shared/server-services/dialogue.service";
import { AccountAvatarRecord } from "src/app/shared/server-services/query-records/account-records";
import { DialogueDataRecord } from "src/app/shared/server-services/query-records/room-records";
import { WorkspaceSubscriptionRoomAccountPermissionEventRecord, WorkspaceSubscriptionRoomEventRecord, WorkspaceSubscriptionRoomPermissionEventRecord } from "src/app/shared/server-services/query-records/workspace-records";
import {
  RoomData,
  RoomService,
} from "src/app/shared/server-services/room.service";
import {
  SubscriptionServiceEvent,
  SubscriptionServiceEventType,
} from "src/app/shared/server-services/subscription-event";
import { SubscriptionService } from "src/app/shared/server-services/subscription.service";
import { DialogService } from "src/app/shared/services/dialog.service";
import { RouterHandler } from "src/app/shared/services/router-handler.service";
import { TitleService } from "src/app/shared/services/title.service";

@Component({
  selector: "app-resource-page",
  templateUrl: "./resource-page.component.html",
  styleUrls: ["./resource-page.component.scss"],
})
export class ResourcePageComponent implements OnInit, OnDestroy {
  public activeMenu = "chat";
  public resourceId;
  public resourceName = "";
  public roomImage: ArrayBuffer;
  public avatar: AccountAvatarRecord;
  public routeSubscription;
  public dataLoaded = false;
  public loadError = true;
  public pinnedKey = "";
  public isReadOnly: boolean = false;
  public isMessageboard: boolean = false;
  public showNewMessageCircle: boolean = false;

  public onRouterChangeChat = (res) => {
    this.onChangeRoute(
      res,
      res.params.type !== "room" ? "private" : "chat",
      res.params.type !== "private"
    );
  };

  public onRouterChangeDrive = (res) => {
    this.onChangeRoute(res, "drive", res.params.type !== "chat");
  };

  public onRouterChangeDetails = (res) => {
    this.onChangeRoute(res, "details", res.params.type !== "chat");
  };

  private checkReadOnly(){
    if (this.authService.isAnonym()){
      this.isReadOnly = true;
    }
    else{
      this.roomService.getMyRoomPermissions(this.resourceId).then((res)=>{
        this.isReadOnly = false;

      }).catch(()=>{
        this.isReadOnly = true;
      })
    }
  }

  private onChangeRoute(res, activeMenu, isRoom = true) {
    this.activeMenu = activeMenu;

    let outerPinnedKey;

    if (res.fragment?.roomkey) {
      // TODO paralell fragmentation
      outerPinnedKey = res.fragment.roomkey;
      console.log('pinnedKey', outerPinnedKey)
    }

    if (
      !this.resourceId ||
      this.resourceId != res.params.id ||
      (isRoom && this.pinnedKey != outerPinnedKey)
    ) {
      console.log("room changed");
      this.resourceId = res.params.id;
      this.roomImage = null;
      this.dataLoaded = false;
      this.loadError = false;

      if (isRoom) {
        this.checkReadOnly();
        this.pinnedKey = outerPinnedKey;
        let parsedPinnedKey: Uint8Array;

        if (this.pinnedKey) {
          try {
            parsedPinnedKey = base64.parse(this.pinnedKey);
          } catch (e) {
            console.error("can not parse pinned key");
            // just try to load the room without pinned key
            // if it fails, we response with error message
            // there is a chance, we do not need the pinned key
            // when we are logged in and we are member of the room
          }
        }
        this.roomService
          .getData(this.resourceId, parsedPinnedKey)
          .then((res) => {
            if (res) {
              this.resourceName = (<RoomData>res.data)?.name;
              this.roomImage = (<RoomData>res.data)?.avatar;
              this.avatar = null;
              this.dataLoaded = true;
              this.titleService.setTabTitle(this.resourceName);
            } else {
              console.error("there is no response from get data");
              this.loadError = false;
            }
          })
          .catch((err) => {
            console.error("could not load room data", err);
            this.loadError = true;
          });
      } else {
        this.dialgueService
          .getData(this.resourceId)
          .then((dialogueRecord: DialogueDataRecord) => {
            this.resourceName = dialogueRecord.account
              ? dialogueRecord.account.avatarName
              : dialogueRecord.errorMessage;
            this.dataLoaded = true;
            this.avatar = dialogueRecord.account;
            this.roomImage = null;
            this.titleService.setTabTitle(this.resourceName);
          }).catch((err) => {
            console.error("could not load room data", err);
            this.loadError = true;
          });
      }
    }

    this.resourceId = res.params.id;
  }

  public onRoomDataChanged = (res: WorkspaceSubscriptionRoomEventRecord) => {
    if (res.id == this.resourceId) {
      if ("data" in res && "name" in res.data) {
        this.resourceName = res.data.name;
      }

      if ("data" in res && "avatar" in res.data) {
        this.roomImage = res.data.avatar;
      }
    }
  };

  constructor(
    private routerHandler: RouterHandler,
    private roomService: RoomService,
    private accountService: AccountService,
    private titleService: TitleService,
    private subscriptionService: SubscriptionService,
    private dialgueService: DialogueService,
    private authService: AuthService,
    private dialogService: DialogService
  ) {
    if (this.routerHandler.isOnPage("room/?/chat/?")) {
      this.onRouterChangeChat(this.routerHandler.getRoute());
    }
    this.routerHandler.subscribe("room/?/chat/?", this.onRouterChangeChat);

    if (this.routerHandler.isOnPage("room/?/drive")) {
      this.onRouterChangeDrive(this.routerHandler.getRoute());
    }
    this.routerHandler.subscribe("room/?/drive", this.onRouterChangeDrive);

    if (this.routerHandler.isOnPage("room/?/details")) {
      this.onRouterChangeDetails(this.routerHandler.getRoute());
    }
    this.routerHandler.subscribe("room/?/details", this.onRouterChangeDetails);

    this.roomService.getRoomPermissions(this.resourceId).then((perm)=>{
      this.isMessageboard = perm.msgBrdReadOnly;
    })

    this.subscriptionService.subscribe(
      SubscriptionServiceEvent.ROOM_EVENT,
      SubscriptionServiceEventType.MODIFY,
      this.onRoomDataChanged.bind(this)
    );

    this.subscriptionService.subscribe(
      SubscriptionServiceEvent.ROOM_ACCOUNT_PERMISSION_EVENT,
      SubscriptionServiceEventType.ALL,
      this.onRoomAccountPermissionChange.bind(this)
    );

    this.subscriptionService.subscribe(
      SubscriptionServiceEvent.ROOM_PERMISSION_EVENT,
      SubscriptionServiceEventType.ALL,
      this.onRoomPermissionChange.bind(this)
    );

    this.subscriptionService.subscribe(
      SubscriptionServiceEvent.ROOM_MESSAGE_EVENT,
      SubscriptionServiceEventType.CREATE,
      this.onMessageEvent.bind(this)
    );
  }

  private onRoomAccountPermissionChange(event: WorkspaceSubscriptionRoomAccountPermissionEventRecord){
    if (event.id == this.resourceId){
      this.checkReadOnly();
      this.dialogService.showSnackbar(marker("Your permission has changed for this room."))
    }
  }

  private onRoomPermissionChange(event: WorkspaceSubscriptionRoomPermissionEventRecord){
    if (event.id == this.resourceId){
      this.isMessageboard = event.msgBrdReadOnly;
    }
  }

  private onMessageEvent(event){
    if(this.activeMenu != 'chat')
      this.showNewMessageCircle = true;
  }

  public changeMenu(menu) {
    this.activeMenu = menu;
    if(this.activeMenu == 'chat')
      this.showNewMessageCircle = false;
  }

  ngOnInit(): void {
    if (this.routerHandler.isOnPage("room/?")) {
      this.resourceId = this.routerHandler.getRoute().params.id;
    }
  }

  ngOnDestroy() {
    this.routerHandler.unsubscribe("room/?/chat/?", this.onRouterChangeChat);
    this.routerHandler.unsubscribe("room/?/drive", this.onRouterChangeDrive);
    this.routerHandler.unsubscribe(
      "room/?/details",
      this.onRouterChangeDetails
    );

    this.subscriptionService.unsubscribe(
      SubscriptionServiceEvent.ROOM_EVENT,
      SubscriptionServiceEventType.MODIFY,
      this.onRoomDataChanged.bind(this)
    );

    this.subscriptionService.unsubscribe(
      SubscriptionServiceEvent.ROOM_ACCOUNT_PERMISSION_EVENT,
      SubscriptionServiceEventType.ALL,
      this.onRoomAccountPermissionChange.bind(this)
    );

    this.subscriptionService.unsubscribe(
      SubscriptionServiceEvent.ROOM_MESSAGE_EVENT,
      SubscriptionServiceEventType.CREATE,
      this.onMessageEvent.bind(this)
    );
  }

  openChat() {
    this.routerHandler
      .navigate(["/room/" + this.resourceId + "/chat/room"], {
        fragment: this.routerHandler.getRoute().rawFragment,
      })
      .then((navigated: boolean) => {
        if (navigated) this.changeMenu("chat");
      });
  }

  openDrive() {
    this.routerHandler
      .navigate(["/room/" + this.resourceId + "/drive"], {
        fragment: this.routerHandler.getRoute().rawFragment,
      })
      .then((navigated: boolean) => {
        if (navigated) this.changeMenu("drive");
      });
  }

  openDetails() {
    this.routerHandler
      .navigate(["/room/" + this.resourceId + "/details"], {
        fragment: this.routerHandler.getRoute().rawFragment,
      })
      .then((navigated: boolean) => {
        if (navigated) this.changeMenu("details");
      });
  }

  get isAnon(): boolean{
    return this.authService.isAnonym();
  }
}
