import { Component, OnInit, OnChanges, Input, Output, EventEmitter, ViewChild, ElementRef,
    ChangeDetectionStrategy, OnDestroy, Renderer2 } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { MatSelect } from '@angular/material/select';
import { SessionService, LAYOUT_TYPE, CustomizationService } from '@pepperi/lib';

@Component({
    // tslint:disable-next-line: component-selector
    selector: 'pepperi-select',
    templateUrl: './select.component.html',
    styleUrls: ['./select.component.scss'],
    changeDetection: ChangeDetectionStrategy.OnPush,
})
export class PepperiSelectComponent implements OnChanges, OnInit, OnDestroy {
    @Input() key = '';
    @Input() value = '';
    @Input() formattedValue = '';
    @Input() label = '';
    @Input() type = 'select';
    @Input() required = false;
    @Input() disabled = false;
    @Input() readonly = false;
    @Input() xAlignment = '0';
    @Input() rowSpan = 1;
    @Input() options: any = null;

    controlType = 'select';

    // @Input() field: PepperiFieldBase;
    @Input() form: FormGroup = null;
    @Input() layoutType: LAYOUT_TYPE = LAYOUT_TYPE.PepperiForm;
    @Input() parentField: any = false;
    @Input() isActive = false;
    @Input() showTitle = true;
    @Input() emptyOption = true;

    @Output() valueChanged: EventEmitter<any> = new EventEmitter<any>();
    @Output() formValidationChanged: EventEmitter<boolean> = new EventEmitter<boolean>();

    @ViewChild('select') select: MatSelect;

    LAYOUT_TYPE = LAYOUT_TYPE;
    standAlone = false;
    isInEditMode = false;
    // isFocus: boolean = false;
    isMulti = false;
    selectedValuesModel: string[];
    selectedValueModel: string;
    fieldFormattedValue = '';

    constructor(public sessionService: SessionService, private customizationService: CustomizationService,
        private renderer: Renderer2, public _eref: ElementRef) { }

    private addOptionsIfNeeded() {
        if (this.isMulti) {
            // Go gor all selected and add to options if not exist
            for (let i = 0; i < this.selectedValuesModel.length; i++) {
                let valueNotExist = false;

                if (!this.options.find((opt) => opt.Key === this.selectedValuesModel[i])) {
                    valueNotExist = true;
                }

                // Add it to options.
                if (valueNotExist) {
                    this.options.push({ Key: this.selectedValuesModel[i], Value: this.selectedValuesModel[i] });
                }
            }
        } else {
            if (this.value && this.value !== '' && !this.options.find((opt) => opt.Key === this.value)) {
                this.options.push({ Key: this.value, Value: this.formattedValue });
            }
        }
    }

    ngOnInit() {
        if (this.form === null) {
            this.standAlone = true;
            this.form = this.customizationService.getDefaultFromGroup(this.key, this.value, this.required, this.readonly, this.disabled);

            this.renderer.addClass(this._eref.nativeElement, CustomizationService.STAND_ALONE_FIELD_CLASS_NAME);
        }
    }

    ngOnChanges(changes: any) {
        this.isMulti = this.type === 'multi';
        if (this.isMulti) {
            this.selectedValuesModel = this.value.length > 0 ? this.value.split(';') : [];
        } else {
            this.selectedValueModel = this.value;
        }
        this.fieldFormattedValue = typeof this.value === 'string' ? this.value.replace(new RegExp(';', 'g'), ', ') : '';

        this.addOptionsIfNeeded();
    }

    ngOnDestroy() {
        if (this.valueChanged) {
            this.valueChanged.unsubscribe();
        }

        if (this.formValidationChanged) {
            this.formValidationChanged.unsubscribe();
        }
    }

    selectionChange(event: any) {
        // this.isFocus = false;
        if (!this.isMulti) {
            this.changeValue(this.selectedValueModel);
        }
    }

    openedChange(event: any) {
        // Only on close.
        if (!event) {
            if (this.isMulti) {
                // this.isFocus = false;
                this.changeValue(this.selectedValuesModel.join(';'));
            }

            if (this.isInEditMode) {
                this.isInEditMode = false;
            }
        }
    }

    changeValue(value: any) {
        this.formattedValue = value;
        this.customizationService.updateFormFieldValue(this.form, this.key, value);

        if (this.required) {
            const fieldControl = this.form.controls[this.key];
            if (value) {
                fieldControl.setErrors(null);
            } else {
                fieldControl.setErrors({
                    serverError: 'Required',
                });
            }
            this.formValidationChanged.emit(this.form.valid);
        }

        this.valueChanged.emit({ apiName: this.key, value });
    }

    cardTemplateClicked(event: any) {
        const self = this;
        this.isInEditMode = true;

        setTimeout(() => {
            self.select.open();
        }, 0);
    }
}
