import { CommonModule, isPlatformBrowser } from '@angular/common';
import { Component, HostListener, OnDestroy, OnInit, AfterViewInit, PLATFORM_ID, inject } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { NavigationEnd, Router, RouterModule } from '@angular/router';
import { APP_ICONS } from '../../utils/fontawesome-icons';
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
import { Collapse, Dropdown, initFlowbite } from 'flowbite';
import { filter, Observable, Subject, takeUntil } from 'rxjs';

import { SortByOptions, User } from '../../../../../bizmatch-server/src/models/db.model';
import { emailToDirName, KeycloakUser, KeyValueAsSortBy, UserListingCriteria } from '../../../../../bizmatch-server/src/models/main.model';
import { environment } from '../../../environments/environment';
import { AuthService } from '../../services/auth.service';
import { FilterStateService } from '../../services/filter-state.service';
import { ListingsService } from '../../services/listings.service';
import { SearchService } from '../../services/search.service';
import { SelectOptionsService } from '../../services/select-options.service';
import { SharedService } from '../../services/shared.service';
import { UserService } from '../../services/user.service';
import { map2User } from '../../utils/utils';

import { ModalService } from '../search-modal/modal.service';

@UntilDestroy()
@Component({
  selector: 'header',
  standalone: true,
  imports: [CommonModule, RouterModule, FormsModule],
  templateUrl: './header.component.html',
  styleUrl: './header.component.scss',
})
export class HeaderComponent implements OnInit, OnDestroy, AfterViewInit {
  public buildVersion = environment.buildVersion;
  user$: Observable<KeycloakUser>;
  keycloakUser: KeycloakUser;
  user: User;
  activeItem;
  faUserGear = APP_ICONS.faUserGear;
  profileUrl: string;
  env = environment;
  private filterDropdown: Dropdown | null = null;
  isMobile: boolean = false;
  private destroy$ = new Subject<void>();
  prompt: string;
  private platformId = inject(PLATFORM_ID);
  private isBrowser = isPlatformBrowser(this.platformId);

  // Aktueller Listing-Typ basierend auf Route
  currentListingType: 'businessListings' | 'commercialPropertyListings' | 'brokerListings' | null = null;

  // Sortierung
  sortDropdownVisible: boolean = false;
  sortByOptions: KeyValueAsSortBy[] = [];
  sortBy: SortByOptions = null;

  // Observable für Anzahl der Listings
  numberOfBroker$: Observable<number>;
  numberOfCommercial$: Observable<number>;

  constructor(
    private router: Router,
    private userService: UserService,
    private sharedService: SharedService,
    private modalService: ModalService,
    private searchService: SearchService,
    private filterStateService: FilterStateService,
    public selectOptions: SelectOptionsService,
    public authService: AuthService,
    private listingService: ListingsService,
  ) { }

  @HostListener('document:click', ['$event'])
  handleGlobalClick(event: Event) {
    const target = event.target as HTMLElement;
    // Don't close sort dropdown when clicking on sort buttons or user menu button
    const excludedIds = ['sortDropdownButton', 'sortDropdownMobileButton', 'user-menu-button'];
    if (!excludedIds.includes(target.id) && !target.closest('#user-menu-button')) {
      this.sortDropdownVisible = false;

      // Close User Menu if clicked outside
      // We check if the click was inside the menu containers
      const userLogin = document.getElementById('user-login');
      const userUnknown = document.getElementById('user-unknown');
      const clickedInsideMenu = (userLogin && userLogin.contains(target)) || (userUnknown && userUnknown.contains(target));

      if (!clickedInsideMenu) {
        this.closeDropdown();
      }
    }
  }

  async ngOnInit() {
    // User Setup
    const token = await this.authService.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`;
    }

    // Lade Anzahl der Listings
    this.numberOfBroker$ = this.userService.getNumberOfBroker(this.createEmptyUserListingCriteria());
    this.numberOfCommercial$ = this.listingService.getNumberOfListings('commercialProperty');

    // Flowbite is now initialized once in AppComponent

    // Profile Photo Updates
    this.sharedService.currentProfilePhoto.pipe(untilDestroyed(this)).subscribe(photoUrl => {
      this.profileUrl = photoUrl;
    });

    // User Updates - re-initialize Flowbite when user state changes
    // This ensures the dropdown bindings are updated when the dropdown target changes
    this.userService.currentUser.pipe(untilDestroyed(this)).subscribe(u => {
      const previousUser = this.user;
      this.user = u;
      // Re-initialize Flowbite if user logged in/out state changed
      if ((previousUser === null) !== (u === null) && this.isBrowser) {
        setTimeout(() => initFlowbite(), 50);
      }
    });

    // Router Events
    this.router.events
      .pipe(
        filter(event => event instanceof NavigationEnd),
        untilDestroyed(this),
      )
      .subscribe((event: NavigationEnd) => {
        this.checkCurrentRoute(event.urlAfterRedirects);
      });

    // Initial Route Check
    this.checkCurrentRoute(this.router.url);
  }

  private checkCurrentRoute(url: string): void {
    const baseRoute = url.split('/')[1];

    // Bestimme den aktuellen Listing-Typ
    if (baseRoute === 'businessListings') {
      this.currentListingType = 'businessListings';
    } else if (baseRoute === 'commercialPropertyListings') {
      this.currentListingType = 'commercialPropertyListings';
    } else if (baseRoute === 'brokerListings') {
      this.currentListingType = 'brokerListings';
    } else {
      this.currentListingType = null;
      return; // Keine relevante Route für Filter/Sort
    }

    // Setup für diese Route
    this.setupSortByOptions();
    this.subscribeToStateChanges();
  }

  private subscribeToStateChanges(): void {
    if (!this.currentListingType) return;

    // Abonniere State-Änderungen für den aktuellen Listing-Typ
    this.filterStateService
      .getState$(this.currentListingType)
      .pipe(takeUntil(this.destroy$))
      .subscribe(state => {
        this.sortBy = state.sortBy;
      });
  }

  private setupSortByOptions(): void {
    this.sortByOptions = [];

    if (!this.currentListingType) return;

    switch (this.currentListingType) {
      case 'brokerListings':
        this.sortByOptions = [...this.selectOptions.sortByOptions.filter(s => s.type === 'professional')];
        break;
      case 'businessListings':
        this.sortByOptions = [...this.selectOptions.sortByOptions.filter(s => s.type === 'business' || s.type === 'listing')];
        break;
      case 'commercialPropertyListings':
        this.sortByOptions = [...this.selectOptions.sortByOptions.filter(s => s.type === 'commercial' || s.type === 'listing')];
        break;
    }

    // Füge generische Optionen hinzu (ohne type)
    this.sortByOptions = [...this.sortByOptions, ...this.selectOptions.sortByOptions.filter(s => !s.type)];
  }

  sortByFct(selectedSortBy: SortByOptions): void {
    if (!this.currentListingType) return;

    this.sortDropdownVisible = false;

    // Update sortBy im State
    this.filterStateService.updateSortBy(this.currentListingType, selectedSortBy);

    // Trigger search
    this.searchService.search(this.currentListingType);
  }

  async openModal() {
    if (!this.currentListingType) return;

    const criteria = this.filterStateService.getCriteria(this.currentListingType);
    const modalResult = await this.modalService.showModal(criteria);

    if (modalResult.accepted) {
      this.searchService.search(this.currentListingType);
    }
  }

  navigateWithState(dest: string, state: any) {
    this.router.navigate([dest], { state: state });
  }

  isActive(route: string): boolean {
    return this.router.url === route;
  }

  isFilterUrl(): boolean {
    return ['/businessListings', '/commercialPropertyListings', '/brokerListings'].includes(this.router.url);
  }

  isBusinessListing(): boolean {
    return this.router.url === '/businessListings';
  }

  isCommercialPropertyListing(): boolean {
    return this.router.url === '/commercialPropertyListings';
  }

  isProfessionalListing(): boolean {
    return this.router.url === '/brokerListings';
  }

  closeDropdown() {
    if (!this.isBrowser) return;

    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() {
    if (!this.isBrowser) return;

    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();
    }
  }

  closeMenusAndSetCriteria(path: string) {
    this.closeDropdown();
    this.closeMobileMenu();

    // Bestimme Listing-Typ aus dem Pfad
    let listingType: 'businessListings' | 'commercialPropertyListings' | 'brokerListings' | null = null;

    if (path === 'businessListings') {
      listingType = 'businessListings';
    } else if (path === 'commercialPropertyListings') {
      listingType = 'commercialPropertyListings';
    } else if (path === 'brokerListings') {
      listingType = 'brokerListings';
    }

    if (listingType) {
      // Reset Pagination beim Wechsel zwischen Views
      this.filterStateService.updateCriteria(listingType, {
        page: 1,
        start: 0,
      });
    }
  }

  toggleSortDropdown() {
    this.sortDropdownVisible = !this.sortDropdownVisible;
  }

  get isProfessional() {
    return this.user?.customerType === 'professional';
  }

  // Helper method für leere UserListingCriteria
  private createEmptyUserListingCriteria(): UserListingCriteria {
    return {
      criteriaType: 'brokerListings',
      types: [],
      state: null,
      city: null,
      radius: null,
      searchType: 'exact' as const,
      brokerName: null,
      companyName: null,
      counties: [],
      prompt: null,
      page: 1,
      start: 0,
      length: 12,
    };
  }



  ngAfterViewInit(): void {
    // Flowbite initialization is now handled manually or via AppComponent
  }

  ngOnDestroy() {
    this.destroy$.next();
    this.destroy$.complete();
  }
}
