import { Injectable } from '@angular/core';
import { HttpRequest, HttpResponse, HttpHandler, HttpEvent, HttpInterceptor, HTTP_INTERCEPTORS } from '@angular/common/http';
import { Observable, of, throwError } from 'rxjs';
import { delay, mergeMap, materialize, dematerialize } from 'rxjs/operators';

@Injectable()
export class FakeBackendInterceptor implements HttpInterceptor {

    constructor() { }

    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        // array in local storage for registered users
        // tslint:disable-next-line: max-line-length
        // const users: any[] = JSON.parse(localStorage.getItem('users')) || [{ username: 'admin', email: 'prashantj@veramatictech.com', password: 'hello' }];

        // wrap in delayed observable to simulate server api call
        return of(null).pipe(mergeMap(() => {

            // // authenticate
            // if (request.url.endsWith('/users/authenticate') && request.method === 'POST') {
            //     const filteredUsers = users.filter(user => {
            //         return user.email === request.body.email && user.password === request.body.password;
            //     });
            //     if (filteredUsers.length) {
            //         // if login details are valid return 200 OK with user details and fake jwt token
            //         const user = filteredUsers[0];
            //         const body = {
            //             id: user.id,
            //             email: user.email,
            //             username: user.username,
            //             firstName: user.firstName,
            //             lastName: user.lastName,
            //             token: 'fake-jwt-token'
            //         };

            //         return of(new HttpResponse({ status: 200, body }));
            //     } else {
            //         // else return 400 bad request
            //         return throwError({ error: { message: 'Username or password is incorrect' } });
            //     }
            // }

            // get users
            // if (request.url.endsWith('/users') && request.method === 'GET') {
            //     // tslint:disable-next-line: max-line-length
            //     // check for fake auth token in header and return users if valid, this security is implemented server side in a real application
            //     if (request.headers.get('Authorization') === 'Bearer fake-jwt-token') {
            //         return of(new HttpResponse({ status: 200, body: users }));
            //     } else {
            //         // return 401 not authorised if token is null or invalid
            //         return throwError({ status: 401, error: { message: 'Unauthorised' } });
            //     }
            // }

            // // get user by id
            // if (request.url.match(/\/users\/\d+$/) && request.method === 'GET') {
            //     // tslint:disable-next-line: max-line-length
            //     // check for fake auth token in header and return user if valid, this security is implemented server side in a real application
            //     if (request.headers.get('Authorization') === 'Bearer fake-jwt-token') {
            //         // find user by id in users array
            //         const urlParts = request.url.split('/');
            //         // tslint:disable-next-line: radix
            //         const id = parseInt(urlParts[urlParts.length - 1]);
            //         // tslint:disable-next-line: no-shadowed-variable
            //         const matchedUsers = users.filter(user => user.id === id);
            //         const user = matchedUsers.length ? matchedUsers[0] : null;

            //         return of(new HttpResponse({ status: 200, body: user }));
            //     } else {
            //         // return 401 not authorised if token is null or invalid
            //         return throwError({ status: 401, error: { message: 'Unauthorised' } });
            //     }
            // }

            // // register user
            // if (request.url.endsWith('/users/register') && request.method === 'POST') {
            //     // get new user object from post body
            //     const newUser = request.body;

            //     // validation
            //     const duplicateUser = users.filter(user => user.username === newUser.username).length;
            //     if (duplicateUser) {
            //         return throwError({ error: { message: 'Username "' + newUser.username + '" is already taken' } });
            //     }

            //     // save new user
            //     newUser.id = users.length + 1;
            //     users.push(newUser);
            //     localStorage.setItem('users', JSON.stringify(users));

            //     // respond 200 OK
            //     return of(new HttpResponse({ status: 200 }));
            // }

            // // delete user
            // if (request.url.match(/\/users\/\d+$/) && request.method === 'DELETE') {
            //     // tslint:disable-next-line: max-line-length
            //     // check for fake auth token in header and return user if valid, this security is implemented server side in a real application
            //     if (request.headers.get('Authorization') === 'Bearer fake-jwt-token') {
            //         // find user by id in users array
            //         const urlParts = request.url.split('/');
            //         // tslint:disable-next-line: radix
            //         const id = parseInt(urlParts[urlParts.length - 1]);
            //         for (let i = 0; i < users.length; i++) {
            //             const user = users[i];
            //             if (user.id === id) {
            //                 // delete user
            //                 users.splice(i, 1);
            //                 localStorage.setItem('users', JSON.stringify(users));
            //                 break;
            //             }
            //         }

            //         // respond 200 OK
            //         return of(new HttpResponse({ status: 200 }));
            //     } else {
            //         // return 401 not authorised if token is null or invalid
            //         return throwError({ status: 401, error: { message: 'Unauthorised' } });
            //     }
            // }

            // pass through any requests not handled above
            return next.handle(request);

        }))

            // tslint:disable-next-line: max-line-length
            // call materialize and dematerialize to ensure delay even if an error is thrown (https://github.com/Reactive-Extensions/RxJS/issues/648)
            .pipe(materialize())
            .pipe(delay(500))
            .pipe(dematerialize());
    }
}
