import { SignOffAction } from 'src/app/auth/store/auth.actions';
import { LoginDialogComponent } from '../../auth/login/login-dialog/login-dialog.component';
import { HttpErrorBody } from '../../model/httpErrorBody';
import { AuthState } from '../../auth/store/auth.reducers';
import { AppState } from '../../store/app.reducers';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpErrorResponse } from "@angular/common/http";
import { Observable } from "rxjs";
import { Store } from "@ngrx/store";
import { Injectable } from '@angular/core';
import { take, switchMap, tap } from 'rxjs/operators';
import { MatSnackBar } from '@angular/material/snack-bar';
import { MatDialog, MatDialogRef } from '@angular/material/dialog';
import { InitLoginDialogAction } from '../../auth/store/auth.actions';
import { Router } from '@angular/router';

@Injectable()
export class AuthInterceptor implements HttpInterceptor{

    constructor(private store: Store<AppState>, private snackBar: MatSnackBar, private dialog: MatDialog, private router: Router){}

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        return this.store.select('authState').pipe(
            take(1),
            switchMap(
                (state: AuthState) => {
                    let token = state.token;
                    let reqClone = req.clone( token !== null ? { headers: req.headers.set('Authorization', 'Bearer ' + token).set('Access-Control-Allow-Origin', '*') } : {});
                    return next.handle(reqClone).pipe(
                        tap(
                            () => {},
                            (errorResponse: HttpErrorResponse) => {
                                let error: HttpErrorBody = errorResponse.error;
                                switch(errorResponse.status){
                                    case 400:
                                        this.snackBar.open('Váš požadavek není validní!', 'zavřít',{
                                            duration: 3500
                                        });
                                        return;
                                    case 401:
                                        if (error.error === 'Unauthorized'){
                                            this.store.dispatch(new SignOffAction());
                                        }
                                        //error.error === 'Invalid Credentials' is handled in login effect
                                        return;
                                    case 403:
                                        this.snackBar.open('Na provedení požadované operace nemáte dostatečné oprávnění', 'zavřít',{
                                            duration: 3500
                                        });
                                        return;
                                    case 409:
                                        //this error is handler in registration effect
                                        return;
                                    case 500:
                                        this.snackBar.open('Oops! Něco nefunguje, nelze zpracovat váš požadavek.', 'zavřít',{
                                            duration: 5000
                                        });
                                        return;
                                    case 503:
                                        if ((!error.error || error.error !== "Mapbox API Error") && (req.url !== "/tadis/auth/available")){
                                            this.router.navigate(['/unavailable']);
                                            return; 
                                        }
                                    case 504:
                                        if (req.url !== "/tadis/auth/available")
                                            this.router.navigate(['/unavailable']);
                                        return;
                                    default:
                                        this.snackBar.open('Nelze provést požadovaný dotaz, objevila se neočekávaná chyba.', 'zavřít',{
                                            duration: 5000
                                        });
                                        return;
                                }
                            }
                        )
                    );
                }
            )
        );
    }
}