import { Component, createNgModuleRef, Injector, OnInit, ViewChild } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { MatSnackBar } from '@angular/material/snack-bar';
import { ActivatedRoute, Router } from '@angular/router';
import { Player } from 'src/app/model';
import { AuthService } from 'src/app/modules/auth.service';
import { Team } from 'src/app/modules/teams/model/team';
import { TeamInvite } from 'src/app/modules/teams/model/team-invite';
import { TeamsService } from 'src/app/modules/teams/teams.service';
import { NewTransactionDialogComponent, TeamTransactionDialogComponent } from 'src/app/shared';
import { CreatePlayerDialogComponent } from 'src/app/shared/dialog/create-player-dialog/create-player.dialog.component';
import { PrivilegesInfoDialogComponent } from 'src/app/shared/dialog/privileges-info-dialog/privileges-info-dialog.component';
import { PlayerDetailsComponent } from './player-card/player-details/player-details.component';
import { CommonModule } from '@angular/common';
import { MatDividerModule } from '@angular/material/divider';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
import { MatMenuModule } from '@angular/material/menu';
import { MatTabsModule } from '@angular/material/tabs';
import { PlayerCardComponent } from './player-card/player-card.component';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatListModule } from '@angular/material/list';
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
import { MatInputModule } from '@angular/material/input';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';

@Component({
  selector: 'app-team-details',
  templateUrl: './team-details.component.html',
  styleUrls: ['./team-details.component.scss'],
  standalone: true,
  imports: [
    CommonModule
    , ReactiveFormsModule
    , FormsModule
    , MatProgressSpinnerModule
    , MatDividerModule
    , MatButtonModule
    , MatIconModule
    , MatMenuModule
    , MatTabsModule
    , MatFormFieldModule
    , MatListModule
    , MatSlideToggleModule
    , MatInputModule
    , PlayerCardComponent
  ]
})
export class TeamDetailsComponent implements OnInit {
  id: string | null = null;

  team: Team | undefined;

  correspondingPlayer: Player | undefined;

  canDoTransactions: boolean = false;
  canInvite: boolean = false;
  roleName: string = '';

  isLoading: boolean = true;

  selectedPlayers: Player[] = [];

  usersPlayers: Player[] = [];

  @ViewChild('players') players: any; 

  constructor(private route: ActivatedRoute, private teamsService: TeamsService, private authService: AuthService,
    private router: Router, public dialog: MatDialog, private injector: Injector, private _snackBar: MatSnackBar) {}

  ngOnInit(): void {
    this.id = this.route.snapshot.paramMap.get('id');

    if (this.id) {
      this.loadTeamDetails();
    }
  }

  protected loadTeamDetails() {
    if (!this.id) { return; }
    this.teamsService.loadTeamDetails(this.id).subscribe(result => {
      this.team = result;
      this.findCorrespondingPlayer();
      this.isLoading = false;
    })
  }

  back() {
    this.router.navigate(['../dashboard'])
  }

  openDialog(): void {
    
    const dialogRef = this.dialog.open(NewTransactionDialogComponent, {
      data: {
        team: this.team,
        players: this.selectedPlayers
      }
    });

    dialogRef.afterClosed().subscribe(async result => {
      if (result && result.length > 0) {
        this.isLoading = true;
        this.teamsService.createTransactions(result).subscribe(res => {
          if (res && res.length > 0) {
            this.loadTeamDetails();
          }
        })
        
      }
    });
  }


  openTeamTransactionDialog() {
    if (!this.team) { return; }
    const dialogRef = this.dialog.open(TeamTransactionDialogComponent, {
      data: {
        teamId: this.team.id
      }
    });

    dialogRef.afterClosed().subscribe(async result => {

      if (result) { this.saveTeamTransaction(result); }
    });
  }

  saveTeamTransaction(transaction: any) {
    this.isLoading = true;
    this.teamsService.createTeamTransaction(transaction).subscribe(res => {
      if (res && res['id']) {
        this.loadTeamDetails();
      }
    })
  }

  selectAll() {
    if (this.team == null || this.team.players == null) { return; }
    if (this.selectedPlayers.length < this.team.players.length) {
      this.selectedPlayers = [];
      for (let p of this.team.players) {
        this.selectedPlayers.push(p);
      }
    } else {
      this.selectedPlayers = [];
    }
    
  }

  onAllClick() {
    if (!this.team) { return; }
    const dialogRef = this.dialog.open(NewTransactionDialogComponent, {
      data: {
        team: this.team,
        players: this.selectedPlayers,
        all: this.team.players?.length == this.selectedPlayers.length
      }
    });
  }

  onAddPlayerClick() {
    if (!this.team) { return; }
    const dialogRef = this.dialog.open(CreatePlayerDialogComponent, {
      data: { },
      width: '350px'
    });

    dialogRef.afterClosed().subscribe(result => {
      if (result && this.team) {
        this.teamsService.createNewPlayer(this.team.id, result).subscribe({
          next: () => { this.loadTeamDetails()},
          error: () => { this.onPlayerCreateError();}
        })
      }  
    })
  }

  onPlayerCreateError() {
    this._snackBar.open('Spieler konnte nicht erstellt werden', undefined, {
      duration: 10000,
      panelClass: 'snackbar_error'
    })
  }

  async onCreateLink() {
    if (!this.team) { return; }

    try {
      const invite: TeamInvite = {
        teamId: this.team.id,
        teamName: this.team.name,
        playerId: this.selectedPlayers[0].id,
        playerName: this.selectedPlayers[0].firstName + ' ' + this.selectedPlayers[0].lastName
      }
      const token = await this.getInviteFromServer(invite);

      const link = location.origin + '/auth/register/' + token
      
      await navigator.clipboard.writeText(link);
      this._snackBar.open('Einladungslink für ' + invite.playerName + ' in die Zwischenablage kopiert. Der Link ist auf den gewählten Spieler personalisiert und darf nicht an mehrere Spieler verteilt werden.', undefined, {
        duration: 10000,

      });

    } catch {
      this._snackBar.open('Der Einladungslink konnte nicht erzeugt werden.', undefined, {
        panelClass: 'snackbar_error',
        duration: 5000,
      });
    }
  }

  private async getInviteFromServer(invite: TeamInvite): Promise<any> {
    return new Promise<any>((resolve, reject) => {
      this.teamsService.createRegisterLink(invite).subscribe({
        next: token => { return resolve(token.token); },
        error: () => { return reject(null); }
      })
    })
  }
  
  findCorrespondingPlayer() {
    if (!this.team || !this.team.players) { return; }
    const id = this.authService.user?.id;
    this.usersPlayers = this.team.players.filter((p: any) => { return p.user?.id == id });
    this.canInvite = this.authService.isAdmin || this.usersPlayers.find(p => p.teamRole.id > 2) != null;
    this.canDoTransactions = this.authService.isAdmin || this.usersPlayers.find(p => p.teamRole.id >= 2) != null;

    this.roleName = this.usersPlayers.reduce((prev, curr) => { return (prev.teamRole.id > curr.teamRole.id) ? prev : curr})?.teamRole.name;

    for (let u of this.usersPlayers) {
      u.usersPlayer = true;
    }
  }

  onShowPrivileges() {
    const dialogRef = this.dialog.open(PrivilegesInfoDialogComponent, {
      data: null
    });

    
  }

  translateRolename(roleName: string): string {
    switch (roleName) {
      case 'treasurer':
        return 'Kassenwart'
      case 'scnd_treasurer':
          return 'zweiter Kassenwart'
      case 'captain':
        return 'Kapitän'
      case 'coach':
        return 'Trainer'
      default:
        return 'Spieler'
    }
  }

  

  async onShowTeamTransactions() {
    if (!this.team) { return; }

    const { ShowTeamTransactionsComponent } = await import(
      'src/app/shared/dialog/show-team-transactions/show-team-transactions.component'
    );

    this.dialog.open(ShowTeamTransactionsComponent, {
      data: {
        id: this.team.id
      }
    });
  }

  openPlayerdetails(player: Player) {
    if (!player) { return; }
    const dialogRef = this.dialog.open(PlayerDetailsComponent, {
      data: {
        player
      }
    });

    dialogRef.componentInstance.changed.subscribe(() => {
      this.loadTeamDetails();
    })
  }

  filter(event: any) {
    const search = event.target.value;
    const s = search.toLowerCase().trim();
    this.team?.players?.map(p => {
      const n = p.firstName.toLowerCase().trim() + '' + p.lastName.toLowerCase().trim();
      p.hide = !n.includes(s);
    });
  }

  get activePlayerCount(): number {
    if (!this.team || !this.team.players) { return 0; }
    return this.team.players.filter(p => p.active).length;
  }
}
