import { Component, inject, signal, OnInit, OnDestroy, Renderer2 } from '@angular/core';
import { Router, RouterModule } from '@angular/router';
import { TranslateService } from '@ngx-translate/core';
import { Subscription, map } from 'rxjs';

import { StateStorageService } from 'app/core/auth/state-storage.service';
import SharedModule from 'app/shared/shared.module';
import HasAnyAuthorityDirective from 'app/shared/auth/has-any-authority.directive';
import { VERSION } from 'app/app.constants';
import { LANGUAGES } from 'app/config/language.constants';
import { AccountService } from 'app/core/auth/account.service';
import { LoginService } from 'app/login/login.service';
import { ProfileService } from 'app/layouts/profiles/profile.service';
import { EntityNavbarItems } from 'app/entities/entity-navbar-items';
import ActiveMenuDirective from './active-menu.directive';
import NavbarItem from './navbar-item.model';

import {ResilientOrganizationsComponent} from 'app/resilient/resilient-environment/organizations/resilient-organizations.component'
import { DocumentService } from 'app/entities/document/service/document.service';
import { IDocument } from 'app/entities/document/document.model';
import { HttpResponse } from '@angular/common/http';
import { DataUtils } from 'app/core/util/data-util.service';
import { Resources } from 'app/security/resources.model';
import { SecurityPermission } from 'app/security/security-permission.model';
import { SecurityAction } from 'app/security/security-action.model';

@Component({
  standalone: true,
  selector: 'jhi-navbar',
  templateUrl: './navbar.component.html',
  styleUrl: './navbar.component.scss',
  imports: [RouterModule, SharedModule, HasAnyAuthorityDirective, ActiveMenuDirective, ResilientOrganizationsComponent],
})
export default class NavbarComponent implements OnInit, OnDestroy {
  private authSubscription?: Subscription;
   
  inProduction?: boolean;
  isNavbarCollapsed = signal(true);
  languages = LANGUAGES;
  openAPIEnabled?: boolean;
  version = '';
  entitiesNavbarItems: NavbarItem[] = [];
  documents?: IDocument[];

  private loginService = inject(LoginService);
  private translateService = inject(TranslateService);
  private stateStorageService = inject(StateStorageService);
  private profileService = inject(ProfileService);
  private router = inject(Router);
  private accountService = inject(AccountService);
  private documentService = inject(DocumentService);
  protected dataUtils = inject(DataUtils);

  account = this.accountService.trackCurrentAccount();
  
  /**
   * This makes the enum accessible in the template
   * Use it, mainly, in html templates for security.
   * Example:
   *    <button *ngIf="hasCreatePermission(Resources.UNIT_TYPE)"></button>
   */
  Resources = Resources; 

  constructor(private renderer: Renderer2) {
    if (VERSION) {
      this.version = VERSION.toLowerCase().startsWith('v') ? VERSION : `v${VERSION}`;
    }
  }

  ngOnInit(): void {
    this.entitiesNavbarItems = EntityNavbarItems;
    this.profileService.getProfileInfo().subscribe(profileInfo => {
      this.inProduction = profileInfo.inProduction;
      this.openAPIEnabled = profileInfo.openAPIEnabled;
    });
    
    this.authSubscription = this.accountService.getAuthenticationState().subscribe(account => {
      if (account) {
        this.renderer.addClass(document.body, 'authenticated');
        if (!this.documents || this.documents.length==0) { 
          // Only when user is authenticated. And if documents[] NOT already loaded. 
          // NOTE: Before, I was doing it always, for unauthenticated users it failed (security) and redirected him to login page. THIS is not intended,
          //       the user must be hable to access public anonymous HOME page.
          this.loadDocuments(); 
        }
      } else {
        this.renderer.removeClass(document.body, 'authenticated');
      }
    });
    
    // add 'navbar-present' class
    this.renderer.addClass(document.body, 'navbar-present');
  }

  ngOnDestroy(): void {
    this.authSubscription?.unsubscribe();
    
    // Remove class
    this.renderer.removeClass(document.body, 'navbar-present');
  }
  
  changeLanguage(languageKey: string): void {
    this.stateStorageService.storeLocale(languageKey);
    this.translateService.use(languageKey);
  }

  collapseNavbar(): void {
    this.isNavbarCollapsed.set(true);
  }

  login(): void {
    this.router.navigate(['/login']);
  }

  logout(): void {
    this.collapseNavbar();
    this.loginService.logout();
    this.router.navigate(['']);
  }

  toggleNavbar(): void {
    this.isNavbarCollapsed.update(isNavbarCollapsed => !isNavbarCollapsed);
  }
  
  hasRole(role: string): boolean {
    return this.accountService.hasAnyAuthority([role]);
  }

  hasReadPermission(evalResource: Resources): boolean {
    const allowPermissions = [SecurityPermission.ALL, SecurityPermission.HIERARCHY]; 
    return allowPermissions.includes(this.accountService.getPermission(evalResource, SecurityAction.READ));
  }

  openFile(base64String: string, contentType: string | null | undefined): void {
    this.dataUtils.openFile(base64String, contentType);
  }

  protected loadDocuments(): void {
    const queryObject: any = {
      eagerload: true,
    };

    // Load documents
    this.documentService
      .query(queryObject)
      .pipe(
        map((res: HttpResponse<IDocument[]>) => res.body ?? [])
      ).subscribe({
        next: (docs: IDocument[]) => {
          this.documents = docs;
        },
      });;
  }
}
