import { action, computed, observable } from "mobx";
import { GridColumns } from "../types";
import { GridColumnModel } from "../model";

export class ChooseColumnsModel {

    @observable
    selectedColumn : GridColumnModel;

    @observable
    columns : GridColumnModel[];

    @observable
    searchString : string;

    private selectedIndex : number;

    constructor(columns : GridColumns) {
        const colNames = Object.keys(columns);
        const numCols = colNames.length;

        this.searchString = "";
        this.columns = new Array(numCols);

        for (let i = 0; i < numCols; i++) {
            this.columns[i] = columns[colNames[i]];
        }

        this.selectedColumn = this.columns[0];
        this.selectedIndex = 0;

        this.select = this.select.bind(this);

        this.moveSelectedUp = this.moveSelectedUp.bind(this);
        this.moveSelectedDown = this.moveSelectedDown.bind(this);

        this.showSelected = this.showSelected.bind(this);
        this.hideSelected = this.hideSelected.bind(this);

        this.setToDefault = this.setToDefault.bind(this);

        this.selectAll = this.selectAll.bind(this);
        this.deselectAll = this.deselectAll.bind(this);
    }

    @computed
    get searchIcon() {
        if (this.searchString.length === 0) {
            return "search";
        }
        else {
            return "highlight_off";
        }
    }

    @computed
    get filteredColumns() {
        const upperCase = this.searchString.toUpperCase();

        return this.columns.filter((col : GridColumnModel) => {
            return col.title.toUpperCase().includes(upperCase);
        });
    }

    @computed
    get canMoveDown() {
        return this.selectedColumn.order !== this.columns.length - 1;
    }

    @computed
    get canMoveUp() {
        return this.selectedColumn.order !== 0;
    }

    @action
    select(column : GridColumnModel) {
        const idx = this.columns.indexOf(column)
        if (idx !== -1) {
            this.selectedIndex = idx;
            this.selectedColumn = column;
        }
    }

    @action
    goToNextColumn() {
        if (this.selectedIndex === this.columns.length - 1) {
            return;
        }

        this.selectedColumn = this.columns[++this.selectedIndex];
    }

    @action
    goToPreviousColumn() {
        if (this.selectedIndex === 0) {
            return;
        }

        this.selectedColumn = this.columns[--this.selectedIndex];
    }

    @action
    moveSelectedUp() {
        const currOrder = this.selectedColumn.order;

        const prevCol = this.columns.find(function(col : GridColumnModel) {
            return col.order == currOrder - 1;
        });

        if (prevCol !== undefined) {
            this.selectedColumn.order--;
            prevCol.order++;
        }

        this.columns = this.columns.sort(function(lhs, rhs) {
            return lhs.order - rhs.order;
        });
    }

    @action
    moveSelectedDown() {
        const currOrder = this.selectedColumn.order;

        const prevCol = this.columns.find(function(col : GridColumnModel) {
            return col.order == currOrder + 1;
        });

        if (prevCol !== undefined) {
            this.selectedColumn.order++;
            prevCol.order--;
        }

        this.columns = this.columns.sort(function(lhs, rhs) {
            return lhs.order - rhs.order;
        });
    }

    @action
    showSelected() {
        this.selectedColumn.setVisible(true);
    }

    @action
    hideSelected() {
        this.selectedColumn.setVisible(false);
    }

    @action
    selectAll() {
        for (const col of this.columns) {
            col.setVisible(true);
        }
    }

    @action
    deselectAll() {
        for (const col of this.columns) {
            col.setVisible(false);
        }
    }

    setToDefault() {

    }
}