import { Component, ElementRef, ViewChild, OnInit, OnDestroy, AfterViewInit } from '@angular/core';
import { FormGroup, FormsModule } from '@angular/forms';
import { MatTableModule, MatTableDataSource } from '@angular/material/table';
import { TableSearchComponent } from '../../score-table/table-search/table-search.component';
import { MatPaginator, MatPaginatorIntl, MatPaginatorModule } from '@angular/material/paginator';
import { Observable, Subscription } from 'rxjs';
import { RankedUser } from '../../auth/model/user.model'; 
import { ScoreTableService } from '../score-table.service';
import { Router, RouterModule } from '@angular/router';
import { MatCard } from '@angular/material/card';
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
import { CommonModule } from '@angular/common';
import { AuthService } from '../../auth/authService/auth.service';
import { MatIconModule, MatIcon } from '@angular/material/icon';
import { PendingActionsService } from '../../score/pending-actions.service';
import { HeaderComponent } from '../../shared/header/header.component';
import { CustomMatPaginatorIntl } from '../custom-mat-paginator-intl';
import { DocumentData } from '@angular/fire/firestore';
import { User as FirebaseUser } from 'firebase/auth';
import { CONSTANTS } from '../../shared/constants';

export interface Games {
  id: string;
  score: string;
  date: string;
}

@Component({
  selector: 'app-score-table',
  standalone: true,
  templateUrl: './score-table.component.html',
  styleUrls: ['./score-table.component.css'],
  imports: [
    MatTableModule,
    TableSearchComponent,
    MatPaginatorModule,
    MatCard,
    MatSlideToggleModule,
    FormsModule,
    CommonModule,
    MatIconModule,
    MatIcon,
    HeaderComponent,
    RouterModule,
  ],
  providers: [{ provide: MatPaginatorIntl, useClass: CustomMatPaginatorIntl }],
})

export class ScoreTableComponent implements OnInit, OnDestroy, AfterViewInit {
  @ViewChild(MatPaginator) paginator!: MatPaginator;
  @ViewChild('slideToggle', { read: ElementRef }) slideToggleElement: ElementRef | undefined;
  displayedColumns: string[] = ['position', 'name', 'wins'];
  displayedColumnsUserGames: string[] = ['date', 'score'];
  dataSource = new MatTableDataSource<RankedUser>([]);
  dataSourceUserGames = new MatTableDataSource<Games>([]);
  users$: Observable<RankedUser[]>;
  subscription = new Subscription();
  showUserGames = false;
  isSearchActive = false;
  userProfileForm!: FormGroup;

  constructor(
    private scoreTableService: ScoreTableService,
    private router: Router,
    private authService: AuthService,
    private pendingActionsService: PendingActionsService
  ) {
    
    // Subscribe to the observable that provides the top users
    this.users$ = scoreTableService.getTopUsers();
    // Subscribe to the observable that indicates whether to show user games
    this.subscription.add(
      this.scoreTableService.showUserGames$.subscribe((data) => {
        this.showUserGames = data;
      })
    );
  }

  /**
   * Lifecycle hook that is called after Angular has initialized all data-bound properties.
   * Here, we subscribe to the users$ observable to get the top users and set the data source.
   */
  ngOnInit() {
    this.subscription.add(
      this.users$.subscribe((users) => {
        this.setPageSize();
        this.dataSource.data = users;
      })
    );

    this.subscription.add(
      this.authService.currentUser$.subscribe((user) => {
        if (user) this.handleUser(user);
      })
    );
  }
  
  /**
   * Lifecycle hook that is called when the component is destroyed.
   * Here, we unsubscribe from all subscriptions to prevent memory leaks.
   */
  ngOnDestroy() {
    this.subscription.unsubscribe();
  }

  /**
   * Lifecycle hook that is called after Angular has fully initialized a component's view.
   * Here, we set the SVG paths for the slide toggle icons.
   */
  ngAfterViewInit() {
    if (this.slideToggleElement) {
      this.slideToggleElement.nativeElement
        .querySelector('.mdc-switch__icon--on')
        .firstChild.setAttribute('d', CONSTANTS.SCORE_BOARD.PERSON_SVG_PATH);
      this.slideToggleElement.nativeElement
        .querySelector('.mdc-switch__icon--off')
        .firstChild.setAttribute('d', CONSTANTS.SCORE_BOARD.GROUP_SVG_PATH);
    }
  }

  /**
   * Handles the user data when a user is logged in.
   * Loads the user's games and checks for any pending QR data.
   * 
   * @param user - The currently logged-in user.
   */
  async handleUser(user: FirebaseUser) {
    if (!user?.uid) return;

    this.dataSourceUserGames.data = await this.scoreTableService.loadUserGames(
      user.uid
    );

    const pendingData = await this.pendingActionsService.checkForPendingQRData(
      user.uid
    );

    if (!pendingData) return;

    if (this.isUserVerified()) {
      this.navigateToUserProfile(pendingData.data());
      this.pendingActionsService.deleteTempQRCodeData(
        pendingData.data()['uid']
      );
    } else {
      this.pendingActionsService.addUserRefToQRCodeData(
        user.uid,
        pendingData.data()['uid']
      );
    }
  }

  /**
   * Navigates to the user profile page with the given pending data.
   * 
   * @param pendingData - The data to pass to the user profile page after a QR code scan.
   */
  navigateToUserProfile(pendingData: DocumentData) {
    this.router.navigate(['/user-profile'], {
      queryParams: {
        score: pendingData['score'],
        uid: pendingData['uid'],
      },
    });
  }

  /**
   * Sets the page size for the paginator based on the screen width.
   * Adjusts the page size for different screen sizes.
   */
  setPageSize() {
    const width = window.screen.width;
    if (width < 768) {
      this.paginator.pageSize = 10;
    } else if (width >= 768 && width < 1024) {
      this.paginator.pageSize = 25;
    } else {
      this.paginator.pageSize = 50;
    }
    if (this.showUserGames) {
      this.dataSourceUserGames.paginator = this.paginator;
    } else {
      this.dataSource.paginator = this.paginator;
    }
  }

  /**
   * Toggles the search functionality on and off.
   */
  toggleSearch() {
    this.isSearchActive = !this.isSearchActive;
  }

  /**
   * Navigates to user profile pages for the given user ID.
   * 
   * @param uid - The user ID to navigate to.
   */
  goToUserPage(uid: string) {
    if (this.isUserVerified()) {
      this.router.navigate(['/user-profile', uid]);
      this.scoreTableService.setShowUserGames(false);
    }
  }

  /**
   * Checks if the current user's email belongs to the Atos company.
   * 
   * @returns True if the user's email includes 'atos.net', false otherwise.
   */
  isCompanyAtos() {
    const email = this.authService.getCurrentUser()?.email;
    return email && email.includes('atos.net');
  }

  /**
   * Checks if the current user's email is verified after registration.
   * 
   * @returns True if the user's email is verified, false otherwise.
   */
  isUserVerified() {
    return this.authService.getCurrentUser()?.emailVerified;
  }

  /**
   * Checks if a user is currently logged in.
   * 
   * @returns The current user if logged in, null otherwise.
   */
  isUserLoggedIn() {
    return this.authService.getCurrentUser();
  }
}