import { NgClass } from '@angular/common';
import { Title, Meta } from '@angular/platform-browser';
import { Observable, Subscription, filter, fromEvent } from 'rxjs';
import { NavigationEnd, Router, RouterModule } from '@angular/router';
import { Component, AfterViewInit, Renderer2, ViewChild, OnInit, OnDestroy, inject } from '@angular/core';

import { Api } from '../providers/api/api';
import packageJson from '../../package.json';
import { UpdateService } from './update.service';
import { SignalRService } from './signalR.service';
import { AppMenuComponent } from './app.menu.component';
import { AppTopBarComponent } from './app.topbar.component';
import { AppFooterComponent } from './app.footer.component';
import { AlertComponent } from './components/alert/alert.component';
import { AppBreadcrumbComponent } from './app.breadcrumb.component';
import { ScrollPanelComponent } from './components/scrollpanel/scrollpanel.component';
import { InternetStatusComponent } from './components/internetstatus/internetstatus.component';
import { AuthenticationService } from '../providers/user/authentication.service';

@Component({
  standalone: true,
  selector: 'app-root',
  templateUrl: './app.component.html',
  imports: [NgClass, RouterModule, AlertComponent, ScrollPanelComponent, AppBreadcrumbComponent, AppMenuComponent, AppTopBarComponent, AppFooterComponent, InternetStatusComponent]
})
export class AppComponent implements OnInit, AfterViewInit, OnDestroy
{
  public renderer = inject(Renderer2);
  private readonly router = inject(Router);
  private readonly metaService = inject(Meta);
  private readonly titleService = inject(Title);
  private readonly updateSvc = inject(UpdateService);
  private readonly signalRSvc = inject(SignalRService);
  private readonly service = inject(AuthenticationService);

  public grouped: boolean = true;
  public darkMenu: boolean = true;
  public resetMenu: boolean = false;
  public userId: number = 0;
  public loginId: string = '';
  public profileMode = 'popup';
  public activeTopbarItem: any;
  public layoutMode = 'overlay';
  public swVersion: string = '';
  public detailInfo: string = '';
  public autoScrollMenu: string = '';
  public connectionStatus: string = '';
  public notificationCount: number = 0;
  public onlineEvent: Observable<Event>;
  public offlineEvent: Observable<Event>;
  public menuHoverActive: boolean = false;
  public rotateMenuButton: boolean = false;
  public topbarMenuActive: boolean = false;
  public overlayMenuActive: boolean = false;
  public staticMenuMobileActive: boolean = false;
  public connectionStatusMessage: string = '';
  public staticMenuDesktopInactive: boolean = false;
  public subscriptions: Subscription[] = [];

  private menuClick: boolean = false;
  private topbarItemClick: boolean = false;

  @ViewChild('layoutMenuScroller', { static: true }) layoutMenuScrollerViewChild: ScrollPanelComponent;

  constructor()
  {
    this.updateSvc.checkForUpdates();
    if (Api.microServiceEnabled)
    {
      this.signalRSvc.monitorAuthenticationHub();
    }
    this.signalRSvc.monitorNotificationHub();
    this.service.notificationEvent.subscribe((raised: boolean) => this.raiseEventNotifCoun(raised));

    this.router.events
      .pipe(filter(event => event instanceof NavigationEnd))
      .subscribe((event: any) =>
      {
        Api.previousUrl = Api.currentUrl;
        Api.currentUrl = event.url;
      });
  }

  ngOnInit(): void
  {
    this.onlineEvent = fromEvent(window, 'online');
    this.offlineEvent = fromEvent(window, 'offline');

    this.subscriptions.push(this.onlineEvent.subscribe(() =>
    {
      this.connectionStatusMessage = 'Back to online';
      this.connectionStatus = 'online';
    }));

    this.subscriptions.push(this.offlineEvent.subscribe(() =>
    {
      this.connectionStatusMessage = 'Connection lost! You are not connected to internet';
      this.connectionStatus = 'offline';
    }));

    this.swVersion = packageJson.version;
    this.titleService.setTitle('Ease Taskforce');
    this.detailInfo = `Version: ${this.swVersion}`;
    this.metaService.addTags([
      { name: 'robots', content: 'index, follow' },
      { name: 'keywords', content: 'CEL, Computer Ease Limited' },
      { name: 'description', content: 'Author: CEL, Company: Computer Ease Limited, Address: 122 West Dhanmondi, Dhaka-1209, Bangladesh' }
    ]);
  }

  ngAfterViewInit(): void
  {
    setTimeout(() => { this.layoutMenuScrollerViewChild.moveBar(); }, 100);
  }

  private raiseEventNotifCoun(raised: boolean): void
  {
    if (raised === false || !this.service.currentUserValue?.id)
    {
      this.notificationCount = 0;
      return;
    }

    this.service.loadNotificationCount(this.service.currentUserValue?.id).subscribe(
      {
        next: (resp: number) =>
        {
          this.notificationCount = resp;
        },
        error: () =>
        {
          this.notificationCount = 0;
        }
      });
  }

  public onLayoutClick()
  {
    if (!this.topbarItemClick)
    {
      this.activeTopbarItem = null;
      this.topbarMenuActive = false;
    }

    if (!this.menuClick)
    {
      if (this.isHorizontal() || this.isSlim())
      {
        this.resetMenu = true;
      }

      if (this.overlayMenuActive || this.staticMenuMobileActive)
      {
        this.hideOverlayMenu();
      }

      this.menuHoverActive = false;
    }

    this.topbarItemClick = false;
    this.menuClick = false;
  }

  public onMenuButtonClick(event: any)
  {
    this.menuClick = true;
    this.rotateMenuButton = !this.rotateMenuButton;
    this.topbarMenuActive = false;

    if (this.layoutMode === 'overlay' && !this.isMobile())
    {
      this.overlayMenuActive = !this.overlayMenuActive;
    }
    else if (this.isDesktop())
    {
      this.staticMenuDesktopInactive = !this.staticMenuDesktopInactive;
    }
    else
    {
      this.staticMenuMobileActive = !this.staticMenuMobileActive;
    }

    event.preventDefault();
  }

  public onMenuClick()
  {
    this.menuClick = true;
    this.resetMenu = false;
    if (!this.isHorizontal())
    {
      setTimeout(() => { this.layoutMenuScrollerViewChild.moveBar(); }, 450);
    }
  }

  public onTopbarMenuButtonClick(event: any)
  {
    this.topbarItemClick = true;
    this.topbarMenuActive = !this.topbarMenuActive;

    this.hideOverlayMenu();

    event.preventDefault();
  }

  public onTopbarItemClick(event: any, item: any)
  {
    this.topbarItemClick = true;

    if (this.activeTopbarItem === item)
    {
      this.activeTopbarItem = null;
    }
    else
    {
      this.activeTopbarItem = item;
    }

    event.preventDefault();
  }

  public onTopbarSubItemClick(event: any, router: any)
  {
    this.router.navigate(['/' + router]);
    event.preventDefault();
  }

  public onPendingNotifClick()
  {
    this.router.navigateByUrl('/pendingauth');
  }

  public hideOverlayMenu(): void
  {
    this.rotateMenuButton = false;
    this.overlayMenuActive = false;
    this.staticMenuMobileActive = false;
  }

  public isTablet()
  {
    const width = window.innerWidth;
    return width <= 1024 && width > 640;
  }

  public isDesktop()
  {
    return window.innerWidth > 1024;
  }

  public isMobile()
  {
    return window.innerWidth <= 640;
  }

  public isOverlay()
  {
    return this.layoutMode === 'overlay';
  }

  public isHorizontal()
  {
    return this.layoutMode === 'horizontal';
  }

  public isSlim()
  {
    return this.layoutMode === 'slim';
  }

  public isStatic()
  {
    return this.layoutMode === 'static';
  }

  ngOnDestroy(): void
  {
    this.signalRSvc?.stopNotificationHub();
    if (Api.microServiceEnabled)
    {
      this.signalRSvc.stopAuthenticationHub();
    }

    for (const subscription of this.subscriptions)
    {
      subscription.unsubscribe();
    }
  }
}
