import { Component, ElementRef, OnInit, OnChanges, Input, Output, EventEmitter, ChangeDetectionStrategy, ViewChild, Renderer2, OnDestroy } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { DateAdapter, MAT_DATE_FORMATS } from '@angular/material/core';
import { DatetimeAdapter, MAT_DATETIME_FORMATS } from '@mat-datetimepicker/core';
import { MomentDateAdapter } from '@angular/material-moment-adapter';
import { MomentDatetimeAdapter } from '@mat-datetimepicker/moment';
import { TranslateService } from '@ngx-translate/core';
import { SessionService, UtilitiesService, LAYOUT_TYPE, CustomizationService } from '@pepperi/lib';

@Component({
    selector: 'pepperi-date',
    templateUrl: './date.component.html',
    styleUrls: ['./date.component.scss'],
    providers: [
        // CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR,
        // The locale would typically be provided on the root module of your application. We do it at
        // the component level here, due to limitations of our example generation script.
        //{ provide: MAT_DATE_LOCALE, useValue: 'en-US' },

        // `MomentDateAdapter` and `MAT_MOMENT_DATE_FORMATS` can be automatically provided by importing
        // `MatMomentDateModule` in your applications root module. We provide it at the component level
        // here, due to limitations of our example generation script.
        //{ provide: DateAdapter, useClass: MomentDateAdapter, deps: [MAT_DATE_LOCALE] },
        //{ provide: MAT_DATE_FORMATS, useValue: MAT_MOMENT_DATE_FORMATS },
        { provide: DateAdapter, useClass: MomentDateAdapter },
        {
            provide: MAT_DATE_FORMATS,
            useValue: {
                parse: {
                    dateInput: 'L',
                    monthInput: 'MMMM',
                    timeInput: 'LT',
                    datetimeInput: 'L LT',
                },
                display: {
                    dateInput: 'L',
                    monthInput: 'MMMM',
                    datetimeInput: 'L LT',
                    timeInput: 'LT',
                    monthYearLabel: 'MMM YYYY',
                    dateA11yLabel: 'LL',
                    monthYearA11yLabel: 'MMMM YYYY',
                    popupHeaderDateLabel: 'ddd, DD MMM',
                },
            },
        },
        { provide: DatetimeAdapter, useClass: MomentDatetimeAdapter },
        //{ provide: MAT_DATETIME_FORMATS, useValue: MAT_NATIVE_DATETIME_FORMATS }
        {
            provide: MAT_DATETIME_FORMATS,
            useValue: {
                parse: {
                    dateInput: 'L',
                    monthInput: 'MMMM',
                    timeInput: 'LT',
                    datetimeInput: 'L LT',
                },
                display: {
                    dateInput: 'L',
                    monthInput: 'MMMM',
                    datetimeInput: 'L LT',
                    timeInput: 'LT',
                    monthYearLabel: 'MMM YYYY',
                    dateA11yLabel: 'LL',
                    monthYearA11yLabel: 'MMMM YYYY',
                    popupHeaderDateLabel: 'ddd, DD MMM',
                },
            },
        },
    ],
    changeDetection: ChangeDetectionStrategy.OnPush,
})
export class PepperiDateComponent implements OnChanges, OnInit, OnDestroy {
    @Input() key: string = '';
    @Input() value: string = '';
    @Input() formattedValue: string = '';
    @Input() label: string = '';
    @Input() type: string = 'date';
    @Input() required: boolean = false;
    @Input() disabled: boolean = false;
    @Input() readonly: boolean = false;
    @Input() textColor: string = '';
    @Input() xAlignment: string = '0';
    @Input() rowSpan: number = 1;
    @Input() minValue: number = 0;
    @Input() maxValue: number = 0;

    controlType = 'date';

    @Input() form: FormGroup = null;
    @Input() isActive: boolean = false;
    @Input() showTitle: boolean = true;
    @Input() layoutType: LAYOUT_TYPE = LAYOUT_TYPE.PepperiForm;

    @Output() valueChanged: EventEmitter<any> = new EventEmitter<any>();
    @ViewChild('datetimePicker') datetimePicker: any;

    @ViewChild('input') input: ElementRef;

    LAYOUT_TYPE = LAYOUT_TYPE;
    standAlone = false;
    isInEditMode: boolean = false;
    dateModel: Date;
    minDate: Date;
    maxDate: Date;
    showDatepicker: boolean = false;
    showTime: boolean = false;

    constructor(
        public _eref: ElementRef,
        public sessionService: SessionService,
        private utilitiesService: UtilitiesService,
        private customizationService: CustomizationService,
        private renderer: Renderer2,
        private translate: TranslateService,
        private adapter: DateAdapter<any>
    ) { }

    ngOnInit() {
        if (this.form === null) {
            this.standAlone = true;
            this.form = this.customizationService.getDefaultFromGroup(this.key, this.value, this.required, this.readonly, this.disabled);
            this.formattedValue = this.formattedValue || this.value;

            this.renderer.addClass(this._eref.nativeElement, CustomizationService.STAND_ALONE_FIELD_CLASS_NAME);
        }

        this.showTime = this.type === 'datetime';

        if (this.minValue > 0) {
            this.minDate = new Date(this.minValue * 1000 * 60 * 60 * 24);
        }

        if (this.maxValue > 0) {
            this.maxDate = new Date(this.maxValue * 1000 * 60 * 60 * 24);
        }

        this.initDate();
    }

    ngOnChanges(changes: any) { }

    ngOnDestroy() {
        if (this.valueChanged) {
            this.valueChanged.unsubscribe();
        }
    }

    initDate() {
        const culture = this.translate.getBrowserCultureLang() || 'en-US'; // this.userLang,
        this.adapter.setLocale(culture);

        if (this.value.indexOf('1900-1-1') >= 0 || this.value.indexOf('1900-01-01') >= 0 || this.value.indexOf('1970-1-1') >= 0 || this.value.indexOf('1970-01-01') >= 0) {
            this.value = '';
            this.formattedValue = '';
            this.dateModel = null;
        } else {
            this.dateModel = this.utilitiesService.parseDate(this.value, this.showTime);
        }
    }

    openDatetimePicker(datetimePicker) {
        datetimePicker.opened = false;
        datetimePicker.open();
    }

    onBlur(event: any) {
        if (this.isInEditMode && !this.datetimePicker.opened) {
            this.isInEditMode = false;
        }
    }

    onDateChange(event: any) {
        let value = '';
        if (event.value != null) {
            value = this.utilitiesService.stringifyDateWithOffset(event.value.toDate(), this.showTime);
        }

        this.customizationService.updateFormFieldValue(this.form, this.key, value);
        this.valueChanged.emit({ apiName: this.key, value: value });

        if (this.isInEditMode) {
            setTimeout(() => {
                this.isInEditMode = false;
            }, 0);
        }
    }

    cardTemplateClicked(event) {
        const self = this;
        this.isInEditMode = true;

        setTimeout(() => {
            self.input.nativeElement.focus();
            self.openDatetimePicker(self.datetimePicker);
        }, 0);
    }
}
