import { Injectable } from '@angular/core';
import * as moment from 'moment';
import { AppSettings, AppSettingsContract, defaultSettings } from '../models-legacy';
import { NetworkService } from './network.service';

@Injectable({ providedIn: 'root' })
export class AppSettingsService {
    private ready$: Promise<AppSettings>;

    constructor(private networkService: NetworkService) {
        this.ready$ = this.load();
    }

    getSettings() {
        return this.ready$;
    }

    private async load(): Promise<AppSettings> {
        const contract = await this.networkService.getAppSettings();

        return this.fromContract(contract);
    }

    private fromContract(contract: AppSettingsContract): AppSettings {
        const boardSearchFrom = this.getBoardSearchFrom(contract);
        const boardSearchTo = this.getBoardSearchTo(contract);
        const scheduleSearchFrom = this.getScheduleSearchFrom(contract);
        const scheduleSearchTo = this.getScheduleSearchTo(contract);

        const boardMaxDate = moment().startOf('day').add(boardSearchTo, 'day').toDate();
        const boardMinDate = moment().startOf('day').add(-boardSearchFrom, 'day').toDate();
        const scheduleMaxDate = moment().startOf('day').add(scheduleSearchTo, 'day').toDate();
        const scheduleMinDate = moment().startOf('day').add(-scheduleSearchFrom, 'day').toDate();

        return {
            ...defaultSettings,
            showDebugVersion: contract.showDebugVersion === 'True',
            buyPeriod: this.getBuyPeriod(contract),
            flightStatusAvailableFrom: this.getFlightStatusAvailableFrom(contract),
            boardSearchFrom,
            boardSearchTo,
            scheduleSearchFrom,
            scheduleSearchTo,            
            boardMaxDate,
            boardMinDate,
            scheduleMaxDate,
            scheduleMinDate,
        };
    }

    private getMonthsFromSetting(setting: string): number {
        if (setting.endsWith('M')) {
            const val = setting.substring(0, setting.length - 1);
            return Number(val);
        }
        return 0;
    }

    private getHoursFromSetting(setting: string): number {
        if (setting.endsWith('h')) {
            const val = setting.substring(0, setting.length - 1);
            return Number(val);
        }
        if (setting.endsWith('d')) {
            const val = setting.substring(0, setting.length - 1);
            return Number(val) * 24;
        }
        return 0;
    }

    private getDaysFromSetting(setting: string): number {
        if (setting.endsWith('d')) {
            const val = setting.substring(0, setting.length - 1);
            return Number(val);
        }
        return 0;
    }


    private getFlightStatusAvailableFrom(settings: AppSettingsContract) {
        return this.getHoursFromSetting(settings.uiOptions.buttons.flightStatus.availableFrom);
    }

    private getBoardSearchTo(settings: AppSettingsContract) {
        return Math.abs(this.getDaysFromSetting(settings.uiOptions.filter.onlineboard.searchTo));
    }

    private getBoardSearchFrom(settings: AppSettingsContract) {
        return Math.abs(this.getDaysFromSetting(settings.uiOptions.filter.onlineboard.searchFrom));
    }

    private getScheduleSearchTo(settings: AppSettingsContract) {
        return Math.abs(this.getDaysFromSetting(settings.uiOptions.filter.schedule.searchTo));
    }

    private getScheduleSearchFrom(settings: AppSettingsContract) {
        return Math.abs(this.getDaysFromSetting(settings.uiOptions.filter.schedule.searchFrom));
    }

    private getBuyPeriod(settings: AppSettingsContract) {
        const min = this.getHoursFromSetting(settings.uiOptions.buttons.buyTicket.period.min);
        const max = this.getHoursFromSetting(settings.uiOptions.buttons.buyTicket.period.max);
        return { min, max };
    }
}
