import {Parameter} from "../../models/Parameter";
import {Params} from "@angular/router";
import { UtilsService } from "../utils.service";

export interface IParameterResolver {
    type: string;
    allowedDataTypes: string[];
    description: string;
    parameter?: Parameter;
    queryParams?: Params;
    for(parameter: Parameter, queryParams: Params): IParameterResolver;
    resolve(): any;
}

export abstract class BaseParameterResolver {
    parameter?: Parameter;
    queryParams?: Params;
    public constructor(init?:Partial<BaseParameterResolver>) {
        Object.assign(this, init);
    }
    //ES: 2021-03-01 00:00:00
    protected formatDate(date?: Date) {
        if (!date) return null;

        let month = '' + (date.getMonth() + 1);
        let day = '' + date.getDate();
        let year = date.getFullYear();
        let second = '' + date.getSeconds();
        let minute = '' + date.getMinutes();
        let hour = '' + date.getHours();

        if (month.length < 2)
            month = '0' + month;

        if (day.length < 2)
            day = '0' + day;

        if (hour.length < 2)
            hour = '0' + hour;

        if (minute.length < 2)
            minute = '0' + minute;

        if (second.length < 2)
            second = '0' + second;

        return year + '-' + month + '-' + day + ' ' + hour + ":" + minute + ":" + second
    }
}

export class AnyDateParameterResolver extends BaseParameterResolver implements IParameterResolver {
    type = "any_date";
    allowedDataTypes = ["Date", "Timestamp"];
    description = "Data specifica";

    for(parameter: Parameter, queryParams: Params): IParameterResolver {
        return new AnyDateParameterResolver({ parameter, queryParams});
    }
    resolve(): any {
        if (!this.parameter?.value)
            return null;
        return this.formatDate(this.parameter.value ? new Date(this.parameter.value) : undefined);
    }
}

export class AnyIntervalParameterResolver extends BaseParameterResolver implements IParameterResolver {
    type = "any_interval";
    allowedDataTypes = ["Interval", "Date"];
    description = "Intervallo";

    for(parameter: Parameter, queryParams: Params): IParameterResolver {
        return new AnyIntervalParameterResolver({ parameter, queryParams});
    }
    resolve(): any {
        if (!this.parameter?.value)
            return null;
        return this.parameter?.value;;
    }
}

export class AnyIntervalChhosenByUserParameterResolver extends BaseParameterResolver implements IParameterResolver {
    type = "any_interval_choosen_by_user";
    allowedDataTypes = ["Interval", "Date"];
    description = "Intervallo scelto dall'utente";

    for(parameter: Parameter, queryParams: Params): IParameterResolver {
        return new AnyIntervalChhosenByUserParameterResolver({ parameter, queryParams});
    }
    resolve(): any {
        if (!this.parameter?.value)
            return null;
        return this.parameter?.value;;
    }
}


export class AnyDateChoosenByUserParameterResolver extends BaseParameterResolver implements IParameterResolver {
    type = "any_date_choosen_by_user";
    allowedDataTypes = ["Date", "Timestamp"];
    description = "Data scelta dall'utente";

    for(parameter: Parameter, queryParams: Params): IParameterResolver {
        return new AnyDateParameterResolver({ parameter, queryParams});
    }
    resolve(): any {
        if (!this.parameter?.value)
            return null;
        return this.formatDate(this.parameter.value ? new Date(this.parameter.value) : undefined);
    }
}


export class NowDateParameterResolver extends BaseParameterResolver implements IParameterResolver {
    type = "now";
    allowedDataTypes = ["Date", "Timestamp"];
    description = "Data istantanea";

    for(parameter: Parameter, queryParams: Params): IParameterResolver {
        return new NowDateParameterResolver({ parameter, queryParams});
    }
    resolve(): any {
        return this.formatDate(new Date());
    }
}

export class StartDayParameterResolver extends BaseParameterResolver implements IParameterResolver {
    type = "start_day";
    allowedDataTypes = ["Date", "Timestamp"];
    description = "Inizio giornata";

    for(parameter: Parameter, queryParams: Params): IParameterResolver {
        return new StartDayParameterResolver({ parameter, queryParams});
    }
    resolve(): any {
        let start = new Date();
        start.setUTCHours(0,0,0,0);
        return this.formatDate(start);
    }
}

export class EndDayParameterResolver extends BaseParameterResolver implements IParameterResolver {
    type = "end_day";
    allowedDataTypes = ["Date", "Timestamp"];
    description = "Fine giornata";

    for(parameter: Parameter, queryParams: Params): IParameterResolver {
        return new EndDayParameterResolver({ parameter, queryParams});
    }
    resolve(): any {
        let end = new Date();
        end.setUTCHours(23,59,59,999);
        return this.formatDate(end);
    }
}

export class AnyNumberParameterResolver extends BaseParameterResolver implements IParameterResolver {
    type = "any_number";
    allowedDataTypes = ["Integer"];
    description = "Numero specifico";
   

    for(parameter: Parameter, queryParams: Params): IParameterResolver {
        return new AnyNumberParameterResolver({ parameter, queryParams});
    }
    resolve(): any {
        return this.parameter?.value;
    }
}

export class AnyStringParameterResolver extends BaseParameterResolver implements IParameterResolver {
    type = "any_string";
    allowedDataTypes = ["String"];
    description = "Numero specifico";
   

    for(parameter: Parameter, queryParams: Params): IParameterResolver {
        return new AnyNumberParameterResolver({ parameter, queryParams});
    }
    resolve(): any {
        return this.parameter?.value;
    }
}


export class QueryStringParameterResolver extends BaseParameterResolver implements IParameterResolver {
    type = "querystring";
    allowedDataTypes = ["Integer", "Date", "Timestamp", "String"];
    description = "Parametro querystring";

    for(parameter: Parameter, queryParams: Params): IParameterResolver {
        return new QueryStringParameterResolver({ parameter, queryParams});
    }
    
    resolve(): any {
        if (!this.queryParams || !this.parameter?.value)
            return "";
        return this.parameter.value;
//        return this.queryParams[this.parameter?.value];
    }
}