import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpResponse } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable, of, throwError } from 'rxjs';
import { delay, mergeMap, materialize, dematerialize } from 'rxjs/operators';
import { ok, error } from '../functions-utils.interceptor';
import { SortField, DIRECTION } from '@xdf/commons';

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


const basePath = '/service/settings/calendar-exception';

@Injectable()
export class CalendarExceptionFakeBackendInterceptor implements HttpInterceptor {
    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

        const { url, method, headers, body } = request;
        const data = (source as any).default;

        return of(null)
            .pipe(mergeMap(handleRoute))
            .pipe(materialize())
            .pipe(delay(50))
            .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);
                case url.match('.*' + basePath) && method === 'GET':
                    return ok(data.data[0]);
                default:
                    // pass through any requests not handled above
                    return next.handle(request);
            }
        }
        function pagination(body) {
            body.totalPages = 1;
            body.totalItems = 2;

            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 getOne(url) {
            const n = url.lastIndexOf("/") + 1;
            const id: Number = Number(url.substring(n));
            return ok(data.filter(x => x.id === id)[0]);
        }
        function deleteOperation(url) {
            const n = url.lastIndexOf("/") + 1;
            const id: Number = Number(url.substring(n));

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

            return ok();
        }
    }
}
