import DateRange from "../dateSelection/daterangepicker/DateRange";
import { EsgfDataset } from './EsgfDataArchive'

export interface DataArchive {

    getQueryProperties(supportedProperties: string[]): Promise<QueryProperty[]>;
    queryDatasets(props: QueryProperty[]): Promise<Dataset[]>;

}

export interface Dataset {
    getName(): string;
    getUrl(): string;
    getStartDate(): Date;
    getEndDate(): Date;
}

export class DatasetGroup {
    name: string = '';
    color: string = 'primary';
    datasets: Dataset[] = [];
    dateRange: DateRange = new DateRange();

    constructor(name: string, color: string) {
        this.name = name;
        this.color = color;
    }

    public addDataset(dataset: Dataset): void {
        this.datasets.push(dataset);
        // this.updateDateRange();
    }

    private alignDateRange(dataset: Dataset): void {
        this.dateRange.minDate = dataset.getStartDate();
        this.dateRange.maxDate = dataset.getEndDate();
        this.dateRange.selectedMinDate = dataset.getStartDate();
        this.dateRange.selectedMaxDate = dataset.getEndDate();
    }

    private updateDateRange(): void {
        if (this.datasets.length < 1) {
            // nothing to do
            return;
        } else if (this.datasets.length == 1) {
            // align date ranges to single dataset
            this.alignDateRange(this.datasets[0]);
        } else {
            // find min max bounds
            let minDate = this.datasets[0].getStartDate()
            let maxDate = this.datasets[0].getStartDate()
            for (let dataset of this.datasets) {
                if (minDate < dataset.getStartDate()) {
                    minDate = dataset.getStartDate();
                }
                if (maxDate > dataset.getEndDate()) {
                    maxDate = dataset.getEndDate();
                }
            }

            this.dateRange.minDate = minDate;
            this.dateRange.maxDate = maxDate;
        }


    }

}

export interface HasDataArchive {
    getQueryProperties(fn: (props: QueryProperty[]) => void): void;
    queryDatasets(props: QueryProperty[], onFinish?: () => void): void;
    getDatasetGroups(): DatasetGroup[];
}

export class QueryProperty {
    private _name: string;
    private _values: string[];
    private _selected: string[];

    constructor(name: string, values: string[] = [], selected: string[] = []) {
        this._name = name;
        this._values = values;
        this._selected = selected;
    }

    public get name(): string {
        return this._name;
    }

    public get values(): string[] {
        return this._values;
    }

    public get selected(): string[] {
        return this._selected;
    }

    public set selected(selected: string[]) {
        this._selected = selected;
    }

    public addValue(value: string) {
        this._values.push(value);
    }

    public addSelected(selectedValue: string) {
        this._selected.push(selectedValue);
    }

    public hasSelected(): boolean {
        return this._selected.length > 0;
    }
}

export abstract class EnsembleItem {

    constructor(public isActive: boolean = false) {
    }

    public toggleActive(): void {
        this.isActive = !this.isActive;
    }

    public abstract getLabel(): string;
    public abstract getTitle(): string;
}

export class Ensemble {
    private static refCount = 0;

    private _index: number;
    private _name: string;
    private _items: EnsembleItem[] = [];
    public isActive: boolean = false;

    constructor(name: string, items: EnsembleItem[]) {
        this._index = ++Ensemble.refCount;
        this._name = name;
        this._items = items;
    }

    public get name(): string {
        return this._name;
    }

    public get items(): EnsembleItem[] {
        return this._items;
    }

    public toggleActive(): void {
        this.isActive = !this.isActive;
    }

    public hasSelectedItem(): boolean {
        for (let item of this._items) {
            if (item.isActive) {
                return true
            }
        }

        return false;
    }
}
