import { MatDialogRef, MAT_DIALOG_DATA } from "@angular/material";
import { Inject, Component, OnInit } from "@angular/core";
import { FormBuilder, FormGroup, Validators } from "@angular/forms";
import { I18nService } from "../../services/internationalisation/internationalisation.service";
import { NgParameter } from "../../formulaire/ngparam";
import { ParamValueMode } from "jalhyd";
import { sprintf } from "sprintf-js";

@Component({
    selector: "dialog-edit-param-values",
    templateUrl: "dialog-edit-param-values.component.html",
    styleUrls: ["dialog-edit-param-values.component.scss"]
})
export class DialogEditParamValuesComponent implements OnInit {

    /** the related parameter to change the "variable" value of */
    public param: NgParameter;

    /** available value modes (min / max, list) */
    public valueModes;

    /** available decimal separators */
    public decimalSeparators;

    /** current decimal separator */
    public decimalSeparator;

    public valuesListForm: FormGroup;

    constructor(
        public dialogRef: MatDialogRef<DialogEditParamValuesComponent>,
        private intlService: I18nService,
        private fb: FormBuilder,
        @Inject(MAT_DIALOG_DATA) public data: any
    ) {
        this.param = data.param;
        if (this.isListe) {
            console.log("PARAM LIST VALUE", this.param.valueList);
        }

        // an explicit ReactiveForm is required for file input component
        this.valuesListForm = this.fb.group({
            file: [null, null]
        });

        this.valueModes = [
            {
                value: ParamValueMode.MINMAX,
                label: this.intlService.localizeText("INFO_PARAMMODE_MINMAX")
            },
            {
                value: ParamValueMode.LISTE,
                label: this.intlService.localizeText("INFO_PARAMMODE_LIST")
            }
        ];
        this.decimalSeparators = [
            {
                label: this.intlService.localizeText("INFO_PARAMFIELD_PARAMVARIER_SEPARATEUR_POINT"),
                value: "."
            },
            {
                label: this.intlService.localizeText("INFO_PARAMFIELD_PARAMVARIER_SEPARATEUR_VIRGULE"),
                value: ","
            }
        ];
        this.decimalSeparator = this.decimalSeparators[0].value;
    }

    /** regular expression pattern for values list validation (depends on decimal separator) */
    public get valuesListPattern() {
        const escapedDecimalSeparator = (this.decimalSeparator === "." ? "\\." : this.decimalSeparator);
        const numberSubPattern = "-?([0-9]+" + escapedDecimalSeparator + ")?[0-9E]+";
        const re = numberSubPattern + "(" + this.separatorPattern + numberSubPattern + ")*";
        // console.log("Re PAT", re);
        return re;
    }

    /** accepted separator: everything but [numbers, E, +, -, decimal separator], any length */
    public get separatorPattern() {
        return "[^0-9-+E" + this.decimalSeparator  + "]+";
    }

    public get selectedValueMode() {
        return this.param.valueMode;
    }

    public set selectedValueMode(v) {
        this.param.valueMode = v;
    }

    public get uiTextModeSelection() {
        return this.intlService.localizeText("INFO_PARAMFIELD_PARAMVARIER_MODE");
    }

    public get uitextValeurMini() {
        return this.intlService.localizeText("INFO_PARAMFIELD_VALEURMINI");
    }

    public get uitextValeurMaxi() {
        return this.intlService.localizeText("INFO_PARAMFIELD_VALEURMAXI");
    }

    public get uitextPasVariation() {
        return this.intlService.localizeText("INFO_PARAMFIELD_PASVARIATION");
    }

    public get uitextClose() {
        return this.intlService.localizeText("INFO_OPTION_CLOSE");
    }

    public get uitextEditParamVariableValues() {
        return this.intlService.localizeText("INFO_PARAMFIELD_PARAMVARIER_TITLE");
    }

    public get uitextListeValeurs() {
        return this.intlService.localizeText("INFO_PARAMFIELD_PARAMVARIER_VALUES_FORMAT");
    }

    public get uitextMustBeANumber(): string {
        return this.intlService.localizeText("ERROR_PARAM_MUST_BE_A_NUMBER");
    }

    public get uitextMustBeListOfNumbers() {
        return sprintf(this.intlService.localizeText("INFO_PARAMFIELD_PARAMVARIER_VALUES_FORMAT_ERROR"), this.separatorPattern);
    }

    public get uitextDecimalSeparator() {
        return this.intlService.localizeText("INFO_PARAMFIELD_PARAMVARIER_SEPARATEUR_DECIMAL");
    }

    public get uitextImportFile() {
        return this.intlService.localizeText("INFO_PARAMFIELD_PARAMVARIER_IMPORT_FICHIER");
    }

    public get isMinMax() {
        return this.param.valueMode === ParamValueMode.MINMAX;
    }

    public get isListe() {
        return this.param.valueMode === ParamValueMode.LISTE;
    }

    public get valuesList() {
        return (this.param.valueList || []).join(";");
    }

    public set valuesList(list: string) {
        const vals = [];
        list.split(";").forEach((e) => {
            if (e.length > 0) {
                vals.push(Number(e));
            }
        });
        this.param.valueList = vals;
    }

    public onFileSelected(event: any) {
        if (event.target.files && event.target.files.length) {
            const fr = new FileReader();
            fr.onload = () => {
                console.log("CHARJAY", fr.result);
                this.valuesList = String(fr.result);
            };
            fr.onerror = () => {
                fr.abort();
                throw new Error("Erreur de lecture du fichier");
            };
            fr.readAsText(event.target.files[0]);
        }
    }

    public dumperr(obj) {
        if (obj) { return Object.keys(obj).join(", "); }
    }

    public onValueModeChange(event) {
        this.initVariableValues();
    }

    public ngOnInit() {
        this.initVariableValues();
    }

    private initVariableValues() {
        // init min / max / step
        if (this.isMinMax) {
            if (this.param.minValue === undefined) {
                this.param.minValue = this.param.getValue() / 2;
            }
            if (this.param.maxValue === undefined) {
                this.param.maxValue = this.param.getValue() * 2;
            }
            let step = this.param.stepValue;
            if (step === undefined) {
                step = (this.param.maxValue - this.param.minValue) / 20;
            }
            this.param.stepValue = step;
        }
        // init values list
        if (this.isListe) {
            if (this.param.valueList === undefined) {
                if (this.param.isDefined) {
                    console.log("SET LIST", [ this.param.getValue() ]);
                    this.param.valueList = [ this.param.getValue() ];
                } else {
                    console.log("SET LIST", [ ]);
                    this.param.valueList = [];
                }
            }
        }
    }


  /*   protected validateModelValue(v: any): { isValid: boolean, message: string } {
      let msg: string;
      let valid = false;

      if (this.param === undefined) {
          msg = "internal error, model undefined";
      } else {
          if (!this.param.checkMin(v)) {
              msg = "La valeur n'est pas dans [" + this.param.domain.minValue + " , " + this.param.maxValue + "[";
          } else {
              valid = true;
          }
      }

      return { isValid: valid, message: msg };
  }
  protected validateModelValue(v: any): { isValid: boolean, message: string } {
      let msg: string;
      let valid = false;

      if (this.param === undefined) {
          msg = "internal error, model undefined";
      } else {
          if (!this.param.checkMax(v)) {
              msg = "La valeur n'est pas dans ]" + this.param.minValue + " , " + this.param.domain.maxValue + "]";
          } else {
              valid = true;
          }
      }

      return { isValid: valid, message: msg };
  }
  protected validateModelValue(v: any): { isValid: boolean, message: string } {
      let msg: string;
      let valid = false;

      if (! this.param) {
          msg = "internal error, model undefined";
      } else {
          if (this.param.isMinMaxValid) {
              if (!this.param.checkStep(v)) {
                  msg = "La valeur n'est pas dans " + this.param.stepRefValue.toString();
              } else {
                  valid = v > 0;
                  if (!valid) {
                      msg = "La valeur ne peut pas ĂȘtre <= 0";
                  }
              }
          } else {
              msg = "Veuillez corriger le min/max";
          }
      }

      return { isValid: valid, message: msg };
  } */
}