import { BreakpointObserver } from '@angular/cdk/layout';
import { CommonModule } from '@angular/common';
import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { NavigationEnd, Router, RouterModule } from '@angular/router';
import { faUserGear } from '@fortawesome/free-solid-svg-icons';
import { Collapse, Dropdown, initFlowbite } from 'flowbite';
import { KeycloakService } from 'keycloak-angular';
import onChange from 'on-change';
import { filter, Observable, Subject, Subscription } from 'rxjs';
import { User } from '../../../../../bizmatch-server/src/models/db.model';
import { BusinessListingCriteria, CommercialPropertyListingCriteria, emailToDirName, KeycloakUser, UserListingCriteria } from '../../../../../bizmatch-server/src/models/main.model';
import { environment } from '../../../environments/environment';
import { CriteriaChangeService } from '../../services/criteria-change.service';
import { SearchService } from '../../services/search.service';
import { SharedService } from '../../services/shared.service';
import { UserService } from '../../services/user.service';
import { compareObjects, createEmptyBusinessListingCriteria, createEmptyCommercialPropertyListingCriteria, createEmptyUserListingCriteria, getCriteriaStateObject, map2User } from '../../utils/utils';
import { DropdownComponent } from '../dropdown/dropdown.component';
import { ModalService } from '../search-modal/modal.service';
@Component({
  selector: 'header',
  standalone: true,
  imports: [CommonModule, RouterModule, DropdownComponent, FormsModule],
  templateUrl: './header.component.html',
  styleUrl: './header.component.scss',
})
export class HeaderComponent {
  public buildVersion = environment.buildVersion;
  user$: Observable<KeycloakUser>;
  keycloakUser: KeycloakUser;
  user: User;
  activeItem;
  faUserGear = faUserGear;
  profileUrl: string;
  env = environment;
  private filterDropdown: Dropdown | null = null;
  isMobile: boolean = false;
  private destroy$ = new Subject<void>();
  prompt: string;
  private subscription: Subscription;
  criteria: BusinessListingCriteria | CommercialPropertyListingCriteria | UserListingCriteria;
  private routerSubscription: Subscription | undefined;
  baseRoute: string;
  constructor(
    public keycloakService: KeycloakService,
    private router: Router,
    private userService: UserService,
    private sharedService: SharedService,
    private breakpointObserver: BreakpointObserver,
    private modalService: ModalService,
    private searchService: SearchService,
    private criteriaChangeService: CriteriaChangeService,
  ) {}

  async ngOnInit() {
    const token = await this.keycloakService.getToken();
    this.keycloakUser = map2User(token);
    if (this.keycloakUser) {
      this.user = await this.userService.getByMail(this.keycloakUser?.email);
      this.profileUrl = this.user.hasProfile ? `${this.env.imageBaseUrl}/pictures/profile/${emailToDirName(this.user.email)}.avif?_ts=${new Date().getTime()}` : `/assets/images/placeholder.png`;
    }

    setTimeout(() => {
      initFlowbite();
    }, 10);

    this.sharedService.currentProfilePhoto.subscribe(photoUrl => {
      if (photoUrl) {
        this.profileUrl = photoUrl;
      }
    });

    this.checkCurrentRoute(this.router.url);

    this.routerSubscription = this.router.events.pipe(filter(event => event instanceof NavigationEnd)).subscribe((event: any) => {
      this.checkCurrentRoute(event.urlAfterRedirects);
    });
  }
  private checkCurrentRoute(url: string): void {
    this.baseRoute = url.split('/')[1]; // Nimmt den ersten Teil der Route nach dem ersten '/'
    const specialRoutes = [, '', ''];
    if ('businessListings' === this.baseRoute) {
      //this.criteria = onChange(getCriteriaStateObject('business'), getSessionStorageHandlerWrapper('business'));
      //this.criteria = onChange(getCriteriaStateObject('business'), this.getSessionStorageHandler);
      this.criteria = this.createEnhancedProxy(getCriteriaStateObject('business'));
    } else if ('commercialPropertyListings' === this.baseRoute) {
      // this.criteria = onChange(getCriteriaStateObject('commercialProperty'), getSessionStorageHandlerWrapper('commercialProperty'));
      this.criteria = this.createEnhancedProxy(getCriteriaStateObject('commercialProperty'));
    } else if ('brokerListings' === this.baseRoute) {
      // this.criteria = onChange(getCriteriaStateObject('broker'), getSessionStorageHandlerWrapper('broker'));
      this.criteria = this.createEnhancedProxy(getCriteriaStateObject('broker'));
    } else {
      this.criteria = undefined;
    }
  }
  private createEnhancedProxy(obj: any) {
    const component = this;

    const sessionStorageHandler = function (path, value, previous, applyData) {
      let criteriaType = '';
      if ('/businessListings' === window.location.pathname) {
        criteriaType = 'business';
      } else if ('/commercialPropertyListings' === window.location.pathname) {
        criteriaType = 'commercialProperty';
      } else if ('/brokerListings' === window.location.pathname) {
        criteriaType = 'broker';
      }
      sessionStorage.setItem(`${criteriaType}_criteria`, JSON.stringify(this));
    };

    return onChange(obj, function (path, value, previous, applyData) {
      // Call the original sessionStorageHandler
      sessionStorageHandler.call(this, path, value, previous, applyData);

      // Notify about the criteria change using the component's context
      component.criteriaChangeService.notifyCriteriaChange();
    });
  }

  ngAfterViewInit() {}

  async openModal() {
    const accepted = await this.modalService.showModal(this.criteria);
    if (accepted) {
      this.searchService.search(this.criteria);
    }
  }
  navigateWithState(dest: string, state: any) {
    this.router.navigate([dest], { state: state });
  }
  login() {
    this.keycloakService.login({
      redirectUri: window.location.href,
    });
  }
  register() {
    this.keycloakService.register({ redirectUri: `${window.location.origin}/account` });
  }
  isActive(route: string): boolean {
    return this.router.url === route;
  }
  isListingUrl(): boolean {
    return ['/businessListings', '/commercialPropertyListings', '/brokerListings'].includes(this.router.url);
  }
  closeDropdown() {
    const dropdownButton = document.getElementById('user-menu-button');
    const dropdownMenu = this.user ? document.getElementById('user-login') : document.getElementById('user-unknown');

    if (dropdownButton && dropdownMenu) {
      const dropdown = new Dropdown(dropdownMenu, dropdownButton);
      dropdown.hide();
    }
  }
  closeMobileMenu() {
    const targetElement = document.getElementById('navbar-user');
    const triggerElement = document.querySelector('[data-collapse-toggle="navbar-user"]');

    if (targetElement instanceof HTMLElement && triggerElement instanceof HTMLElement) {
      const collapse = new Collapse(targetElement, triggerElement);
      collapse.collapse();
    }
  }
  closeMenus() {
    this.closeDropdown();
    this.closeMobileMenu();
  }

  ngOnDestroy() {
    this.destroy$.next();
    this.destroy$.complete();
  }
  getNumberOfFiltersSet() {
    if (this.criteria?.criteriaType === 'broker') {
      return compareObjects(createEmptyUserListingCriteria(), this.criteria, ['start', 'length', 'page', 'searchType', 'radius']);
    } else if (this.criteria?.criteriaType === 'business') {
      return compareObjects(createEmptyBusinessListingCriteria(), this.criteria, ['start', 'length', 'page', 'searchType', 'radius']);
    } else if (this.criteria?.criteriaType === 'commercialProperty') {
      return compareObjects(createEmptyCommercialPropertyListingCriteria(), this.criteria, ['start', 'length', 'page', 'searchType', 'radius']);
    } else {
      return 0;
    }
  }
}
