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

import { Errors, Jump, User } from 'src/app/core/models';
import { JumpsService, UserService } from 'src/app/core/services';
import { JumpDeleteDialogComponent, JumpEditDialogComponent } from 'src/app/components/jump/dialogs'

@Component({
    standalone: true,
    imports: [
        CommonModule, RouterModule,
        MatButtonModule, MatDialogModule, MatIconModule, MatNativeDateModule, MatSnackBarModule,
        JumpDeleteDialogComponent, JumpEditDialogComponent
    ],
    selector: 'huapp-jump',
    templateUrl: './jump.component.html',
    styleUrls: ['./jump.component.scss']
})
export class JumpComponent implements OnInit, OnDestroy {
    private _currentUser: Subscription = new Subscription();
    private _data: Subscription = new Subscription();
    public errors!: Errors;
    public jump: Jump = {} as Jump;
    public currentUser: User = {} as User;
    public canModify = false;

    constructor(
        private route: ActivatedRoute,
        private router: Router,
        private dialog: MatDialog,
        private _jumpsService: JumpsService,
        private _userService: UserService,
        private _snackBar: MatSnackBar
    ) { }

    ngOnInit() {
        // Retreive the prefetched jump
        const data$: Observable<any> = this.route.data;
        this._data = data$.subscribe((data: { jump: Jump }) => {
            this.jump = data.jump;
        });
        // Load the current user's data
        const currentUser$: Observable<User> = this._userService.currentUser;
        this._currentUser = currentUser$.subscribe((userData: User) => {
            this.currentUser = userData;
            this.canModify = this.currentUser.username === this.jump.author.username;
        });
    }

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

    openDeleteDialog(jump: Jump): void {
        const dialogRef = this.dialog.open(JumpDeleteDialogComponent, {
            width: '60vw',
            data: jump
        });
        dialogRef.afterClosed().pipe(take(1))
        .subscribe(result => {
            if (result != undefined) {
                this._onDelete(result.slug);
            }
        });
    }

    openEditDialog(jump: Jump): void {
        const dialogRef = this.dialog.open(JumpEditDialogComponent, {
            width: '70vw',
            data: jump
        });
        dialogRef.afterClosed().pipe(take(1))
        .subscribe(result => {
            if (result != undefined) {
                this._onEdit(result);
            }
        });
    }

    private _onDelete(slug: string): void {
        try {
            this._jumpsService.destroy(slug)
                .pipe(take(1))
                .subscribe({
                    next: () => {
                        this.router.navigateByUrl('/logbook');
                    },
                    error: (err) => {
                        this.errors = err;
                    }
                });
        } catch (error) {
            console.error(error);
        }
    }

    private _onEdit(jump: Jump): void {
        try {
            let previousValues: Jump = {} as Jump;
            Object.assign(previousValues, this.jump);
            this._jumpsService.update(jump)
                .pipe(take(1))
                .subscribe({
                    next: (jump) => {
                        this._resetErrors();
                        this._openSnackBar(`Le saut n°${jump.numero} a été mis à jour !`, 'Annuler');
                        this.jump = jump;
                    },
                    error: (err) => {
                        this.errors = err;
                    }
                });
        } catch (error) {
            console.error(error);
        }
    }

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

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

}
