import { CommonModule } from '@angular/common';
import { Component, AfterContentChecked, OnInit, OnDestroy } from '@angular/core';
import { ActivatedRoute, Router, RouterModule } from '@angular/router';
import { MatButtonModule } from '@angular/material/button';
import { MatCardModule } from '@angular/material/card';
import { MatDialog, MatDialogModule } from '@angular/material/dialog';
import { MatIconModule } from '@angular/material/icon';
import { MatMenuModule } from '@angular/material/menu';
import { MatSnackBar, MatSnackBarConfig, MatSnackBarHorizontalPosition, MatSnackBarModule, MatSnackBarVerticalPosition } from '@angular/material/snack-bar';
import { Observable, Subscription } from 'rxjs';
import { take } from 'rxjs/operators';

import { MenuItems, JumpAddDialogComponent, JumpTableComponent } from 'src/app/components/shared';
import { Errors, Jump, JumpListConfig, User } from 'src/app/core/models';
import { JumpsService, JumpTableService, UserService } from 'src/app/core/services';
import data from 'src/jumps.json';
//import data from 'src/jumps_02.json';

@Component({
    standalone: true,
    imports: [
        CommonModule, RouterModule,
        MatButtonModule, MatCardModule, MatIconModule,
        MatMenuModule, MatDialogModule, MatSnackBarModule,
        JumpTableComponent
    ],
    selector: 'huapp-logbook',
    templateUrl: './logbook.component.html',
    styleUrls: ['./logbook.component.scss']
})
export class LogbookComponent implements OnInit, OnDestroy, AfterContentChecked {
    private _currentUser: Subscription = new Subscription();
    private _data: Subscription = new Subscription();
    private _lastjump: Subscription = new Subscription();
    private _lastjump$: Observable<Jump> = new Observable();
    public errors!: Errors;
    public title = 'Carnet de sauts';
    public jump: Jump = {} as Jump;
    public lastJump: Jump = {} as Jump;
    public currentUser: User = {} as User;
    public listConfig: JumpListConfig = { type: 'all', filters: {} };
    public isAuthenticated = false;
    public isUser = true;
    public canModify = false;
    public isSubmitting = false;
    public tableRefresh = false;
    public jumpRefresh = false;

    constructor(
        private route: ActivatedRoute,
        private router: Router,
        private dialog: MatDialog,
        private snackBar: MatSnackBar,
        private _jumpsService: JumpsService,
        private _jumpTableService: JumpTableService,
        private _userService: UserService,
        public menuItems: MenuItems
    ) { }

    ngOnInit() {
        //this.importJumps();
        const data$: Observable<any> = this.route.data;
        this._data = data$.subscribe((data: { isAuthenticated: boolean }) => {
            this.isAuthenticated = data.isAuthenticated;
            if (!this.isAuthenticated) {
                this.router.navigateByUrl('/login');
                return;
            }
            const currentUser$: Observable<User> = this._userService.currentUser;
            this._currentUser = currentUser$.subscribe((userData: User) => {
                this.currentUser = userData;
                this.canModify = this.currentUser.role === 'Admin';
            });

            this._lastjump$ = this._jumpsService.getLastJump();
            this._lastjump = this._lastjump$.subscribe((jump) => {
                this.lastJump = jump;
            });
        });
    }

    ngOnDestroy() {
        this._data.unsubscribe();
        this._currentUser.unsubscribe();
        this._lastjump.unsubscribe();
    }

    ngAfterContentChecked() {
        if (this.tableRefresh != this._jumpTableService.tableRefresh) {
            this.tableRefresh = this._jumpTableService.tableRefresh;
            this._lastjump$ = this._jumpsService.getLastJump();
            this._lastjump = this._lastjump$.subscribe((jump) => {
                this.lastJump = jump;
            });
            console.log('lastjump has been updated in logbook component');
        }
    }

    importJumps() {
        try {
            data.forEach((entry) => {
                Object.assign(this.jump, entry);
                this._jumpsService.save(this.jump)
                .pipe(take(1))
                .subscribe({
                    next: (jump) => {
                        console.log(`Le saut n°${jump.numero} a été ajouté !`, 'OK');
                    },
                    error: (err) => {
                        console.log(`Le saut n\'a pas été ajouté !`, 'Error', err);
                        this.errors = err;
                    }
                });
            });
        } catch (error) {
            console.error(error);
        }
    }

    openAddDialog(): void {
        this.jump = <Jump>{};
        this.jump.numero = (this.lastJump.numero + 1);
        this.jump.sautants = [];
        this.jump.participants = 1;
        const dialogRef = this.dialog.open(JumpAddDialogComponent, {
            width: '70vw',
            data: {jump: this.jump, lastJump: this.lastJump}
        });
        dialogRef.afterClosed().pipe(take(1))
        .subscribe(result => {
            if (result != undefined) {
                this._onEntry(result);
            }
        });
    }

    private _onEntry(jumps: Array<Jump>): void {
        const max: number = jumps.length;
        let refresh: boolean = false;
        jumps.forEach((jump: Jump, index: number) => {
            console.log('Ajout du saut', jump.numero);
            Object.assign(this.jump, jump);
            if (max == index+1) {
                refresh = true;
            }
            this._saveJump(jump, refresh);
        });
    }

    private _saveJump(jump: Jump, refresh: boolean) {
        this._jumpsService.save(jump)
        .pipe(take(1))
        .subscribe({
            next: (jump) => {
                this._openSnackBar(`Le saut n°${jump.numero} a été ajouté !`, 'Annuler');
                this._resetErrors();
                if (refresh) {
                    this.jumpRefresh = !this.jumpRefresh;
                    this._jumpTableService.updateJumpRefresh(this.jumpRefresh);
                    this._lastjump$ = this._jumpsService.getLastJump();
                    this._lastjump = this._lastjump$.subscribe((jump) => {
                        this.lastJump = jump;
                    });
                }
            },
            error: (err) => {
                this.errors = err;
                this.isSubmitting = false;
            }
        });
    }

    private _openSnackBar(content: string, title: string) {
        const config: MatSnackBarConfig = {
            horizontalPosition: <MatSnackBarHorizontalPosition>'end',
            verticalPosition: <MatSnackBarVerticalPosition>'bottom',
            duration: 4000
        };
        this.snackBar.open(content, title, config);
    }

    private _resetErrors(): void {
        this.errors = { errors: {} };
    }

}
