/**
 * Search Context
 */

import { WidgetLayout } from "./layout";
import type { WidgetBean } from "./models/WidgetBean";

export class SearchContext {
    widget: WidgetBean;
    q: string = "";
    page: number = 1;
    filters: Array<SearchFilter> = [];
    query: number = 0;
    sort: string = "";
    itemsPerPage: number = 20;

    public constructor(widget: WidgetBean, q: string, page: number, filters: Array<SearchFilter>, query: number, sort: string) {
        this.widget = widget;
        this.q = q;
        this.page = page;
        this.filters = filters;
        this.query = query;
        this.sort = sort;

        //@ts-ignore
        var ps = WidgetLayout.parse(widget.layout).getAttribute('results', 'pagesize-' + this.query)
        this.itemsPerPage = +ps || 20
    }

    toUrl(): string {
        var url = "";
        if (this.q)
            url += "&q=" + encodeURIComponent(this.q);
        //@ts-ignore
        if (this.query > 0 && this.query != this.widget.queries[0].id)
            url += "&i=" + this.query;
        if (this.filters.length > 0)
            url += "&" + this.filters.map(f => encodeURIComponent(f.name) + "=" + encodeURIComponent(f.value)).join("&");
        if (this.page > 1)
            url += "&p=" + this.page;
        if (this.sort)
            url += "&sort_by_f=" + encodeURIComponent(this.sort);
        return url ? url.substring(1) : url;
    }

    static fromUrl(widget: WidgetBean, queryString: string): SearchContext {
        const PNAMES = ["q", "p", "i", "sort_by_f"];
        const params = new URLSearchParams(queryString);
        var q = params.get("q") || "";
        //@ts-ignore
        var page = +params.get("p") || 1;
        //@ts-ignore
        var query = +params.get("i") || widget.queries[0].id;
        var sort = params.get("sort_by_f") || "";
        var filters: Array<SearchFilter> = [];
        params.forEach((value, key) => {
            if (PNAMES.indexOf(key) < 0) {
                filters.push(new SearchFilter(key, value, params.get(key + ".interval") || ""))
            }
        });
        //@ts-ignore
        var context = new SearchContext(widget, q, page, filters, query, sort);
        return context;
    }

    getFromIndex(): number {
        return (this.page - 1) * this.itemsPerPage
    }

    setq(q: string): void {
        this.q = q;
    }

    getq(): string {
        return this.q;
    }

    setPage(p: number): void {
        this.page = p;
    }

    getPage(): number {
        return this.page;
    }

    setQuery(q: number): void {
        this.query = q;
    }

    getQuery(): number {
        return this.query;
    }

    setSort(s: string): void {
        this.sort = s;
    }

    getSort(): string {
        return this.sort;
    }

    getFilters(): Array<SearchFilter> {
        return this.filters;
    }

    addFilter(f: SearchFilter): void {
        if (f.multiple) {
            this.filters.push(f);
        }
    }

    deleteFilter(f: SearchFilter): void {
        this.filters = this.filters.filter(tf => tf.name != f.name || tf.value != f.value);
    }

}

export class SearchFilter {
    name: string = "";
    value: string = "";
    interval: string = "";
    multiple: boolean = false;

    public constructor(name: string, value: string, interval: string, multiple = false) {
        this.name = name;
        this.value = value;
        this.interval = interval;
        this.multiple = multiple;
    }

}