import { Component, OnDestroy, OnInit } from "@angular/core";
import { FormControl } from "@angular/forms";
import { marker } from "@biesbjerg/ngx-translate-extract-marker";
import { SafeRadix32 } from "src/app/shared/safe-radix32";
import { AccountService } from "src/app/shared/server-services/account.service";
import { DialogueService } from "src/app/shared/server-services/dialogue.service";
import { AccountAvatarRecord } from "src/app/shared/server-services/query-records/account-records";
import { ID } from "src/app/shared/server-services/query-records/common-records";
import {
  createContactQuery,
  deleteContactQuery,
  getAccountQuery,
  getContactListQuery,
} from "src/app/shared/server-services/querys";
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 { ServerRestApiService } from "src/app/shared/services/server-rest-api.service";
import { sideMenuActiveObserver } from "../header/header.component";
import { WeightedSearch } from "src/app/shared/weighted-search";
@Component({
  selector: "app-contact-list",
  templateUrl: "./contact-list.component.html",
  styleUrls: ["./contact-list.component.scss"],
})
export class ContactListComponent implements OnInit, OnDestroy {
  public contactList: AccountAvatarRecord[];
  public filteredContactList: AccountAvatarRecord[];
  public foundError: boolean = false;
  public foundAccount: AccountAvatarRecord = null;
  public isLoading: boolean = false;
  public me: AccountAvatarRecord;

  public searchTermControl = new FormControl('');

  constructor(
    private serverRestApiService: ServerRestApiService,
    private accountService: AccountService,
    private subscriptionService: SubscriptionService,
    private dialogService: DialogService,
    private dialogueService: DialogueService,
    private routerHandler: RouterHandler
  ) {
    this.accountService
      .getMe()
      .then((me) => {
        this.me = me;
      })
      .then(() => {
        this.reloadAndsortContactList();
      });

    this.subscriptionService.subscribe(
      SubscriptionServiceEvent.ACCOUNT_CONTACT_EVENT,
      SubscriptionServiceEventType.ALL,
      this.reloadAndsortContactList.bind(this)
    );
  }

  ngOnDestroy() {
    this.subscriptionService.unsubscribe(
      SubscriptionServiceEvent.ACCOUNT_CONTACT_EVENT,
      SubscriptionServiceEventType.ALL,
      this.reloadAndsortContactList.bind(this)
    );
  }

  private reloadAndsortContactList() {
    return this.serverRestApiService
      .query({
        query: getContactListQuery,
      })
      .then((contactList: AccountAvatarRecord[]) => {
        this.contactList = contactList;
        this.sort();
        this.filter();
      });
  }

  ngOnInit(): void {
    sideMenuActiveObserver.next(false);
  }

  public searchUser() {
    this.foundError = false;
    this.isLoading = true;
    this.foundAccount = null;

    this.searchTermControl.setErrors(null);

    if(!SafeRadix32.isSafeRadix(this.searchTermControl.value)){
      this.filter();
      return;
    }

    var userId = this.searchTermControl.value;

    this.serverRestApiService
      .query({
        query: getAccountQuery,
        variables: {
          id: userId,
        },
      })
      .then((acc) => {
        if (acc) {
          this.foundAccount = acc;
        } else {
          this.foundError = true;
        }
      })
      .catch((err) => {
        this.foundError = true;
      })
      .finally(() => {
        this.isLoading = false;

        if(this.foundError)
          this.searchTermControl.setErrors({foundError: true});
        if(this.foundAccount){
          if(this.foundAccount == this.me)
            this.searchTermControl.setErrors({meError: true});
          else if(this.contactList?.includes(this.foundAccount))
            this.searchTermControl.setErrors({existsError: true});
        }        
      });
  }

  public deleteContact(acc: AccountAvatarRecord) {
    this.dialogService
      .openConfirmDialog(
        marker("Remove User"),
        marker(
          "Are you sure you want to remove this user from your contact list?"
        )
      )
      .subscribe((confirm) => {
        if (confirm) {
          this.serverRestApiService
            .mutate({
              query: deleteContactQuery,
              variables: {
                peerId: acc.id,
              },
            })
            .then((res) => {
              this.dialogService.showSnackbar(
                marker("User removed from your contact list.")
              );
            })
            .catch(() => {
              this.dialogService.openAlertDialog(
                marker("Error"),
                marker("Error happened during the operation.")
              );
            });
        }
      });
  }

  public createContact(acc: AccountAvatarRecord) {
    if (acc) {
      this.serverRestApiService
        .mutate({
          query: createContactQuery,
          variables: {
            peerId: acc.id,
          },
        })
        .then((res) => {
          this.foundAccount = null;
          this.dialogService.showSnackbar(
            marker("User added to your contact list.")
          );
        })
        .catch((err) => {
          if(err.message === "Contacts limit is reached (10000)"){
            this.dialogService.openAlertDialog(
              marker("Contact limit"),
              marker("Contacts limit is reached.")
            );
          }
          else{
            this.dialogService.openAlertDialog(
              marker("Error"),
              marker("Error happened during the operation.")
            );
          }
        });
    }
  }

  public get canAdd(): boolean {
    return !(this.isLoading ||
    this.foundError ||
    !this.foundAccount ||
    this.me === this.foundAccount ||
    this.contactList.includes(this.foundAccount));
  }

  private sort() {
    this.contactList = this.contactList.sort((a, b) => { return a.avatarName > b.avatarName ? -1 : 1 });
  }

  private filter(){  
    this.filteredContactList = WeightedSearch.search<AccountAvatarRecord>(this.searchTermControl.value, ["avatarName", "id"], this.contactList);
    this.filteredContactList.sort((a, b) => (a.avatarName > b.avatarName) ? 1 : (a.avatarName < b.avatarName) ? -1 : 0);
  }

  public startDialogue(account: AccountAvatarRecord) {
    this.dialogueService
      .getData(account.id)
      .then((dialogueData) => {
        // there is already a dialogue for this user
        this.routerHandler.navigate(["room", account.id, "chat", "private"]);
      })
      .catch((err) => {
        // we need to create a new dialogue
        this.dialogueService
          .createDialogue(account.id)
          .then((ok) => {
            this.routerHandler.navigate([
              "room",
              account.id,
              "chat",
              "private",
            ]);
          })
          .catch((err) => {
            this.dialogService.openAlertDialog(
              marker("Error"),
              marker("Error happened during the operation")
            );
          });
      });
  }
}
