import { observable, computed } from "mobx";
import { RowModel } from "./RowModel";
import { EventEmitter, EventHandler } from "./EventEmitter";

export enum GroupEvent {
    Initialized,
    ExpandedChanged,
    StatusChanged,
    ButtonClicked,
}

export class GroupModel extends EventEmitter<GroupEvent> {

    name : string;

    @observable
    expanded : boolean;

    @observable
    status : string;

    @observable
    rows : RowModel[];

    index : number;

    @observable
    showTitle : boolean;

    constructor(title : string, index : number, rows : RowModel[], handler? : EventHandler<GroupEvent>) {
        super();

        this.addEventHandler(handler);

        this.rows = rows;

        this.showTitle = true;
        this.index = index;
        this.name = title;
        this.expanded = true;
        this.status = "";

        this.toggleExpanded = this.toggleExpanded.bind(this);
        this.connectClicked = this.connectClicked.bind(this);
    }

    @computed
    get visibleRowCount() {
        return this.rows.reduce((accumulator, currentValue) => {
            return accumulator + (currentValue.isVisible ? 1 : 0);
        }, 0);
    }

    toggleExpanded() {
        this.expanded = !this.expanded;

        this.triggerEvent(GroupEvent.ExpandedChanged, {
            expanded: this.expanded
        });
    }

    insertRow(index : number, row : RowModel) {
        if (index >= this.rows.length) {
            this.rows.push(row);
            return;
        }

        this.rows.splice(index, 0, row);
    }

    removeRow(row : RowModel) {
        const index = this.rows.findIndex(r => r === row);

        if (index !== -1) {
            this.rows.splice(index, 1);
        }
    }

    setStatus(status : string) {
        this.status = status;

        this.triggerEvent(GroupEvent.StatusChanged, {
            status: this.status
        });
    }

    connectClicked(e : Event) {
        this.triggerEvent(GroupEvent.ButtonClicked, {
            clicked: true
        });

        e.stopPropagation();
        e.preventDefault();
    }

    clear() {
        this.rows = [];
    }

    sort(ascending : boolean, column : string) {
        this.rows = this.rows.sort((lhs, rhs) => {
            return lhs.compare(ascending, column, rhs);
        });
    }

    unsort() {
        this.rows = this.rows.sort((lhs, rhs) => {
            return lhs.index > rhs.index ? 1 : -1;
        });
    }

    setTitleVisibility(visible : boolean) {
        this.showTitle = visible;
    }

    handleEvent(event : GroupEvent, args) {

        switch (event) {
            case GroupEvent.ExpandedChanged:
                this.expanded = args[0];
                break;
            case GroupEvent.StatusChanged:
                this.status = args[0];
                break;
            default:
                break;
        }
    }

    serialize() {
        return {
            name: this.name,
            expanded: this.expanded,
            status: this.status,
            index : this.index
        };
    }
}
