import { Component, Input, ViewChild, Output, EventEmitter, OnInit, Inject } from '@angular/core';
import { OverlayPanel } from 'primeng/overlaypanel';
import { TranslateService } from '@ngx-translate/core';
import { TabView } from 'primeng/tabview';
import { APP_SETTINGS, LocalizationService } from '@app/shared/services';
import { AppSettings } from '@app/shared/models-legacy';

@Component({
    selector: 'download-schedule-dialog',
    templateUrl: './download-schedule-dialog.component.html',
})
export class DownloadScheduleDialogComponent implements OnInit {
    @Output() onChangeDate = new EventEmitter();
    @Output() onDownloadSchedule = new EventEmitter();

    @Input() set startDate(value: any) {
        if (!this.dates) {
            this.dates = new DatePair();
            this.dates.mode = DownloadScheduleMode.DAY;
        }
        this.dates.startDate = new Date(value);
    }

    @Input() set endDate(value: any) {
        if (!this.dates) {
            this.dates = new DatePair();
            this.dates.mode = DownloadScheduleMode.DAY;
        }
        this.dates.endDate = new Date(value);
    }

    isScheduleDownload = false;

    dateForDay: Date;
    rangeDatesMonth: Date[];
    rangeDatesWeek: Date[];
    dates: DatePair;

    @ViewChild('op')
    panel: OverlayPanel;

    @ViewChild('tv')
    tabView: TabView;

    minDate: Date;
    maxDate: Date;

    ofMonthTerms = [];
    isTranslationsLoaded = false;

    constructor(
        private translate: TranslateService,
        @Inject(APP_SETTINGS) private settings: AppSettings,
        public localizationService: LocalizationService,
    ) {}

    ngOnInit() {
        this.initTranslate();
        this.initFormEnvironment();
    }

    initTranslate() {
        this.translate
            .get([
                'OF-MONTH.undefined',
                'OF-MONTH.1',
                'OF-MONTH.2',
                'OF-MONTH.3',
                'OF-MONTH.4',
                'OF-MONTH.5',
                'OF-MONTH.6',
                'OF-MONTH.7',
                'OF-MONTH.8',
                'OF-MONTH.9',
                'OF-MONTH.10',
                'OF-MONTH.11',
                'OF-MONTH.12',
            ])
            .toPromise()
            .then((values) => {
                this.ofMonthTerms[0] = values['OF-MONTH.undefined'];
                this.ofMonthTerms[1] = values['OF-MONTH.1'];
                this.ofMonthTerms[2] = values['OF-MONTH.2'];
                this.ofMonthTerms[3] = values['OF-MONTH.3'];
                this.ofMonthTerms[4] = values['OF-MONTH.4'];
                this.ofMonthTerms[5] = values['OF-MONTH.5'];
                this.ofMonthTerms[6] = values['OF-MONTH.6'];
                this.ofMonthTerms[7] = values['OF-MONTH.7'];
                this.ofMonthTerms[8] = values['OF-MONTH.8'];
                this.ofMonthTerms[9] = values['OF-MONTH.9'];
                this.ofMonthTerms[10] = values['OF-MONTH.10'];
                this.ofMonthTerms[11] = values['OF-MONTH.11'];
                this.ofMonthTerms[12] = values['OF-MONTH.12'];
                this.isTranslationsLoaded = true;
            });
    }

    initFormEnvironment() {
        this.minDate = new Date();
        const [scheduleSearchFrom, scheduleSearchTo] = [
            this.settings.scheduleSearchFrom,
            this.settings.scheduleSearchTo,
        ];

        this.minDate.setDate(this.minDate.getDate() - scheduleSearchFrom);
        this.minDate.setHours(0, 0, 0, 0);
        this.maxDate = new Date();

        this.maxDate.setDate(this.maxDate.getDate() + scheduleSearchTo);
        this.maxDate.setHours(0, 0, 0, 0);

        let now = new Date();
        now.setHours(0, 0, 0, 0);

        if (this.dates == null) {
            this.dates = {
                startDate: this.startDate ? new Date(this.startDate) : new Date(now),
                endDate: this.endDate ? new Date(this.endDate) : new Date(now),
                mode: DownloadScheduleMode.PERIOD,
            };
            this.dates.endDate.setMonth(now.getMonth() + 1);
        }

        this.dateForDay = new Date(now);

        let firstDayMonth = new Date(now.getFullYear(), now.getMonth(), 1);
        if (firstDayMonth.getTime() < this.minDate.getTime()) {
            firstDayMonth = this.minDate;
        }
        const lastDayMonth = new Date(now.getFullYear(), now.getMonth() + 1, 0);
        this.rangeDatesMonth = [firstDayMonth, lastDayMonth];

        const dayOfWeek = now.getDay() == 0 ? 7 : now.getDay();
        let firstDateWeek = new Date(now.setDate(now.getDate() - dayOfWeek + 1));
        now = new Date();
        now.setHours(0, 0, 0, 0);
        if (firstDateWeek.getTime() < this.minDate.getTime()) {
            firstDateWeek = this.minDate;
        }
        const lastDateWeek = new Date(now.setDate(now.getDate() - dayOfWeek + 7));
        this.rangeDatesWeek = [firstDateWeek, lastDateWeek];
    }

    show(event: MouseEvent) {
        this.panel.toggle(event, event.currentTarget);
    }

    hide() {
        this.panel.hide();
    }

    validate() {
        const dataPair = this.getDatePair();
        if (!dataPair.startDate || !dataPair.endDate) return false;

        if (dataPair.startDate.getTime() > dataPair.endDate.getTime()) return false;

        return true;
    }

    getDatePair(): DatePair {
        const datePair: DatePair = {
            startDate: this.dates.startDate,
            endDate: this.dates.endDate,
            mode: this.selectedDownloadScheduleMode,
        };

        if (this.selectedDownloadScheduleMode == DownloadScheduleMode.DAY) {
            datePair.startDate = this.dateForDay;
            datePair.endDate = this.dateForDay;
        }
        if (this.selectedDownloadScheduleMode == DownloadScheduleMode.CURRENT_WEEK) {
            datePair.startDate = this.rangeDatesWeek[0];
            datePair.endDate = this.rangeDatesWeek[1];
        }
        if (this.selectedDownloadScheduleMode == DownloadScheduleMode.CURRENT_MONTH) {
            datePair.startDate = this.rangeDatesMonth[0];
            datePair.endDate = this.rangeDatesMonth[1];
        }
        if (datePair.startDate) {
            datePair.startDate.setHours(0, 0, 0, 0);
        }
        if (datePair.endDate) {
            datePair.endDate.setHours(23, 59, 59, 900);
        }
        return datePair;
    }

    onPressDownload() {
        this.onDownloadSchedule.emit(this.getDatePair());
        this.hide();
    }

    // TODO: 7350
    get datesToString() {
        if (this.selectedDownloadScheduleMode == DownloadScheduleMode.DAY) {
            return this.getDateFormatString(this.dateForDay);
        }

        if (this.selectedDownloadScheduleMode == DownloadScheduleMode.CURRENT_WEEK) {
            return `${this.getDateFormatString(this.rangeDatesWeek[0])} - ${this.getDateFormatString(this.rangeDatesWeek[1])}`;
        }

        if (this.selectedDownloadScheduleMode == DownloadScheduleMode.CURRENT_MONTH) {
            return `${this.getDateFormatString(this.rangeDatesMonth[0])} - ${this.getDateFormatString(this.rangeDatesMonth[1])}`;
        }

        if (this.selectedDownloadScheduleMode == DownloadScheduleMode.PERIOD) {
            if (this.dates && this.dates.endDate) {
                return `${this.getDateFormatString(this.dates.startDate)} - ${this.getDateFormatString(this.dates.endDate)}`;
            } else {
                return '';
            }
        }
        return this.getDateFormatString(this.dateForDay);
    }

    getDateFormatString(date: Date) {
        if (!date) {
            return '';
        }
        return `${date.getDate()} ${this.ofMonthTerms[date.getMonth() + 1]} ${date.getFullYear()}`;
    }

    get selectedDownloadScheduleMode() {
        if (!this.tabView) {
            return DownloadScheduleMode.DAY;
        }
        if (this.tabView.tabs[0].selected) {
            return DownloadScheduleMode.DAY;
        }
        if (this.tabView.tabs[1].selected) {
            return DownloadScheduleMode.CURRENT_WEEK;
        }
        if (this.tabView.tabs[2].selected) {
            return DownloadScheduleMode.CURRENT_MONTH;
        }
        if (this.tabView.tabs[3].selected) {
            return DownloadScheduleMode.PERIOD;
        }
    }
}

export class DatePair {
    startDate: Date;
    endDate: Date;
    mode: DownloadScheduleMode;
}

export enum DownloadScheduleMode {
    DAY,
    CURRENT_WEEK,
    CURRENT_MONTH,
    PERIOD,
}
