import {ChangeDetectionStrategy, ChangeDetectorRef, Component, inject, OnInit} from '@angular/core';
import {NgbModal, NgbTooltip} from '@ng-bootstrap/ng-bootstrap';
import {take} from 'rxjs/operators';
import {MemberService} from 'src/app/_services/member.service';
import {Member} from 'src/app/_models/auth/member';
import {AccountService} from 'src/app/_services/account.service';
import {ToastrService} from 'ngx-toastr';
import {ResetPasswordModalComponent} from '../_modals/reset-password-modal/reset-password-modal.component';
import {ConfirmService} from 'src/app/shared/confirm.service';
import {MessageHubService} from 'src/app/_services/message-hub.service';
import {InviteUserComponent} from '../invite-user/invite-user.component';
import {EditUserComponent} from '../edit-user/edit-user.component';
import {ServerService} from 'src/app/_services/server.service';
import {Router} from '@angular/router';
import {TagBadgeComponent} from '../../shared/tag-badge/tag-badge.component';
import {AsyncPipe, DatePipe, NgFor, NgIf, TitleCasePipe} from '@angular/common';
import {TranslocoModule, TranslocoService} from "@ngneat/transloco";
import {DefaultDatePipe} from "../../pipe/default-date.pipe";

@Component({
    selector: 'app-manage-users',
    templateUrl: './manage-users.component.html',
    styleUrls: ['./manage-users.component.scss'],
    standalone: true,
    changeDetection: ChangeDetectionStrategy.OnPush,
    imports: [NgFor, NgIf, NgbTooltip, TagBadgeComponent, AsyncPipe, TitleCasePipe, DatePipe, TranslocoModule, DefaultDatePipe]
})
export class ManageUsersComponent implements OnInit {

  members: Member[] = [];
  loggedInUsername = '';
  loadingMembers = false;

  translocoService = inject(TranslocoService);
  cdRef = inject(ChangeDetectorRef);

  constructor(private memberService: MemberService,
              private accountService: AccountService,
              private modalService: NgbModal,
              private toastr: ToastrService,
              private confirmService: ConfirmService,
              public messageHub: MessageHubService,
              private serverService: ServerService,
              private router: Router) {
    this.accountService.currentUser$.pipe(take(1)).subscribe((user) => {
      if (user) {
        this.loggedInUsername = user.username;
        this.cdRef.markForCheck();
      }
    });

  }

  ngOnInit(): void {
    this.loadMembers();
  }


  loadMembers() {
    this.loadingMembers = true;
    this.cdRef.markForCheck();
    this.memberService.getMembers(true).subscribe(members => {
      this.members = members;
      // Show logged-in user at the top of the list
      this.members.sort((a: Member, b: Member) => {
        if (a.username === this.loggedInUsername) return 1;
        if (b.username === this.loggedInUsername) return 1;

        const nameA = a.username.toUpperCase();
        const nameB = b.username.toUpperCase();
        if (nameA < nameB) return -1;
        if (nameA > nameB) return 1;
        return 0;
      })
      this.loadingMembers = false;
      this.cdRef.markForCheck();
    });
  }

  canEditMember(member: Member): boolean {
    return this.loggedInUsername !== member.username;
  }

  openEditUser(member: Member) {
    const modalRef = this.modalService.open(EditUserComponent, {size: 'lg'});
    modalRef.componentInstance.member = member;
    modalRef.closed.subscribe(() => {
      this.loadMembers();
    });
  }


  async deleteUser(member: Member) {
    if (await this.confirmService.confirm(this.translocoService.translate('toasts.confirm-delete-user'))) {
      this.memberService.deleteMember(member.username).subscribe(() => {
        setTimeout(() => {
          this.loadMembers();
          this.toastr.success(this.translocoService.translate('toasts.user-deleted', {user: member.username}));
        }, 30); // SetTimeout because I've noticed this can run superfast and not give enough time for data to flush
      });
    }
  }

  inviteUser() {
    const modalRef = this.modalService.open(InviteUserComponent, {size: 'lg'});
    modalRef.closed.subscribe((successful: boolean) => {
      this.loadMembers();
    });
  }

  resendEmail(member: Member) {
    this.serverService.isServerAccessible().subscribe(canAccess => {
      this.accountService.resendConfirmationEmail(member.id).subscribe(async (email) => {
        if (canAccess) {
          this.toastr.info(this.translocoService.translate('toasts.email-sent-to-user', {user: member.username}));
          return;
        }
        await this.confirmService.alert(
          this.translocoService.translate('toasts.click-email-link') + '<br/> <a href="' + email + '" target="_blank" rel="noopener noreferrer">' + email + '</a>');
      });
    });
  }

  setup(member: Member) {
    this.accountService.getInviteUrl(member.id, false).subscribe(url => {
      if (url) {
        this.router.navigateByUrl(url);
      }
    });
  }

  updatePassword(member: Member) {
    const modalRef = this.modalService.open(ResetPasswordModalComponent);
    modalRef.componentInstance.member = member;
  }

  formatLibraries(member: Member) {
    if (member.libraries.length === 0) {
      return this.translocoService.translate('manage-users.none');
    }

    return member.libraries.map(item => item.name).join(', ');
  }

  hasAdminRole(member: Member) {
    return member.roles.indexOf('Admin') >= 0;
  }

  getRoles(member: Member) {
    return member.roles.filter(item => item != 'Pleb');
  }

}
