import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpResponse } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable, of, throwError } from 'rxjs';
import { mergeMap, materialize, dematerialize } from 'rxjs/operators';
import { SortField, DIRECTION } from '@xdf/commons';

import * as source from '../../assets/fake-data/table-data.json';

const basePath = '/dashboard/operative/sentence-by-intent';

@Injectable()
export class TableFakeBackendInterceptor implements HttpInterceptor {
    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        const { url, method, headers, body } = request;
        let data = (source as any).default;
        
        
        return of(null)
            .pipe(mergeMap(handleRoute))
            .pipe(materialize())
            .pipe(dematerialize());

        function handleRoute() {
            
            switch (true) {
                case url.endsWith(basePath + '/page') && method === 'POST':
                    return pagination(body);
                case url.match('.*' + basePath) && method === 'GET':
                    return getOne(url);
                case url.match('.*' + basePath + '/\\d+$') && method === 'DELETE':
                    return deleteOperation(url);
                default:
                    // pass through any requests not handled above
                    return next.handle(request);
            }
        }

        function pagination(body) {
            body.totalPages = 3;
            body.totalItems = 14;

            const page_number = body.currentPage;
            const page_size = body.itemsPerPage ? body.itemsPerPage : 5;

            if (body.sortFields.length > 0) {
                const sortField: SortField = body.sortFields[0];
                const sign = sortField.direction === DIRECTION.asc ? 1 : -1;
                data.sort(function (a, b) {
                    if ((typeof a[sortField.field] === 'number') && (typeof b[sortField.field] === 'number')) {
                        if (a[sortField.field] > b[sortField.field]) {
                            return 1 * sign;
                        } else if (a[sortField.field] < b[sortField.field]) {
                            return -1 * sign;
                        }
                        return 0;
                    } else {
                        return a[sortField.field].localeCompare(b[sortField.field]) * sign;
                    }
                });
            }

            body.data = data.slice(page_number * page_size, (page_number + 1) * page_size);
            return ok(body);
        }

        function deleteOperation(url) {
            const n = url.lastIndexOf("/") + 1;
            const id = url.substring(n);

            (source as any).default = data.filter(item => item.id !== id);
            
            return ok();
        }

        function getOne(url) {
            const n = url.lastIndexOf("/") + 1;
            const id = url.substring(n);
            return ok(data.filter(x => x.id === id)[0]);
        }

        // helper functions
        function ok(bodyContent?) {
            return of(new HttpResponse({ status: 200, body: bodyContent }));
        }

        function error(message: string) {
            return throwError({ error: { message } });
        }

    }
}
