import { MapWorkingTime, WorkingTime } from '../types/schedule';

export const WEEK_DAY = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'];
const MAX_DAY_TIME = 24 * 60; // min

const addWeekDay = (weekDay?: string): string => {
    const ind = weekDay ? WEEK_DAY.indexOf(weekDay) + 1 : 0;
    return WEEK_DAY[ind >= WEEK_DAY.length ? 0 : ind];
}

const subWeekDay = (weekDay?: string): string => {
    const ind = weekDay ? WEEK_DAY.indexOf(weekDay) - 1 : 0;
    return WEEK_DAY[ind < 0 ? WEEK_DAY.length - 1 : ind];
}

export const getCurrentTime = (data: WorkingTime, timeZone: string): MapWorkingTime => {
    let startDay = data.startDayOfWeekUtc;
    let endDay = data.endDayOfWeekUtc;
    const startUtc = data.startTimeUtc / (1000 * 1000 * 60);
    const endUtc = data.endTimeUtc / (1000 * 1000 * 60);
    const matches = timeZone.match(/(\+|-)([0-9]{2}):([0-9]{2})/) || [];
    const sign = matches[1];
    const h = matches[2];
    const m = matches[3];
    let startMin;
    let endMin;

    if (sign === '+') {
        startMin = startUtc + (Number(h) * 60) + Number(m);
        endMin = endUtc + (Number(h) * 60) + Number(m);
        // startMin = startUtc;
        // endMin = endUtc;
    }

    if (sign === '-') {
        startMin = startUtc - (Number(h) * 60) - Number(m);
        endMin = endUtc - (Number(h) * 60) - Number(m);
    }

    if (startMin >= MAX_DAY_TIME) {
        startMin = 0;
        // startMin = startMin - MAX_DAY_TIME;
        // const ind = startDay ? WEEK_DAY.indexOf(startDay) + 1 : 0;
        // startDay = WEEK_DAY[ind >= WEEK_DAY.length ? 0 : ind];
    }

    if (endMin >= MAX_DAY_TIME) {
        endMin = 0;
        // endMin = endMin - MAX_DAY_TIME;
        // const ind = endDay ? WEEK_DAY.indexOf(endDay) + 1 : 0;
        // endDay = WEEK_DAY[ind >= WEEK_DAY.length ? 0 : ind];
    }

    if (startMin <= 0) {
        startMin = 0;
        // startMin = MAX_DAY_TIME - startMin;
        // const ind = startDay ? WEEK_DAY.indexOf(startDay) - 1 : 0;
        // startDay = WEEK_DAY[ind < 0 ? WEEK_DAY.length - 1 : ind];
    }

    if (endMin <= 0) {
        endMin = 0;
        // endMin = MAX_DAY_TIME - endMin;
        // const ind = endDay ? WEEK_DAY.indexOf(endDay) - 1 : 0;
        // endDay = WEEK_DAY[ind < 0 ? WEEK_DAY.length - 1 : ind];
    }

    return {
        startDay,
        startTimeMin: startMin,
        endDay: endDay,
        endTimeMin: endMin
    }
};

export const getTimeString = (min: number) => {
    const timeH = `${(min - min % 60)/60}`;

    return `${timeH.length === 1 ? `0${timeH}` : timeH}:${min % 60 || '00'}`;
}

export const formattedSchedule = (workingTimes: WorkingTime[], timeZone: string): MapWorkingTime[] => (
    workingTimes.map((time) => getCurrentTime(time, timeZone)) || []
);

export const getNewTime = (time: string): number => {
    const timeArr = time.split(':');

    return Number(timeArr[0]) * 60 + Number(timeArr[1]);
};

export const getTimeZoneOffset = (oldTime: string, newTime: string): { sign: string, offset: number } => {
    // старая таймзона
    const matches1 = oldTime.match(/(\+|-)([0-9]{2}):([0-9]{2})/) || [];
    const sign1 = matches1[1];
    const min1 = Number(matches1[2]) * 60 + Number(matches1[3]);
    // новая таймзона
    const matches2 = newTime.match(/(\+|-)([0-9]{2}):([0-9]{2})/) || [];
    const sign2 = matches2[1];
    const min2 = Number(matches2[2]) * 60 + Number(matches2[3]);

    if (sign1 === '+' && sign2 === '+') {
        if (min1 < min2) {
            return {
                sign: '+',
                offset: min2 - min1
            }
        } else {
            return {
                sign: '-',
                offset: min1 - min2
            }
        }
    }

    if (sign1 === '-' && sign2 === '-') {
        if (min1 < min2) {
            return {
                sign: '-',
                offset: min2 - min1
            }
        } else {
            return {
                sign: '+',
                offset: min1 - min2
            }
        }
    }

    if (sign1 === '+' && sign2 === '-') {
        return {
            sign: '-',
            offset: min1 + min2
        }
    }

    if (sign1 === '-' && sign2 === '+') {
        return {
            sign: '+',
            offset: min1 + min2
        }
    }
}

export const formattedTimeByOffset = (workTime: MapWorkingTime, objOffset: { sign: string, offset: number }): MapWorkingTime => {
    if (objOffset.sign === '+') {
        const resStartMin = workTime.startTimeMin + objOffset.offset;
        const resEndMin = workTime.endTimeMin ? workTime.endTimeMin + objOffset.offset : workTime.endTimeMin;

        return {
            ...workTime,
            startTimeMin: resStartMin >= MAX_DAY_TIME ? 0 : resStartMin,
            endTimeMin: resEndMin >= MAX_DAY_TIME ? 0 : resEndMin
        }
    }

    if (objOffset.sign === '-') {
        const resStartMin = workTime.startTimeMin - objOffset.offset;
        const resEndMin = workTime.endTimeMin ? workTime.endTimeMin - objOffset.offset : workTime.endTimeMin;

        return {
            ...workTime,
            startTimeMin: resStartMin < 0 ? 0 : resStartMin,
            endTimeMin: resEndMin < 0 ? 0 : resEndMin
        }
    }

    return workTime;
};

const getResultTime = (data: MapWorkingTime, timeZone: string): WorkingTime => {
    let startDayOfWeekUtc = data.startDay;
    let endDayOfWeekUtc = data.startDay;
    const matches = timeZone.match(/(\+|-)([0-9]{2}):([0-9]{2})/) || [];
    const sign = matches[1];
    const offset = (Number(matches[2]) * 60) + Number(matches[3]);
    let startTime = data.startTimeMin;
    let endTime = data.endTimeMin === 0 ? MAX_DAY_TIME : data.endTimeMin;

    if (sign === '+') {
        startTime = startTime - offset;
        endTime = endTime - offset;
    }

    if (sign === '-') {
        startTime = startTime + offset;
        endTime = endTime + offset;
    }

    if (startTime >= MAX_DAY_TIME) {
        startTime = startTime - MAX_DAY_TIME;
        startDayOfWeekUtc = addWeekDay(startDayOfWeekUtc);
    }

    if (endTime >= MAX_DAY_TIME) {
        endTime = endTime - MAX_DAY_TIME;
        endDayOfWeekUtc = addWeekDay(endDayOfWeekUtc);
    }

    if (startTime < 0) {
        startTime = MAX_DAY_TIME - Math.abs(startTime || 0);
        startDayOfWeekUtc = subWeekDay(startDayOfWeekUtc);
    }

    if (endTime < 0) {
        endTime = MAX_DAY_TIME - Math.abs(endTime || 0);
        endDayOfWeekUtc = subWeekDay(endDayOfWeekUtc);
    }

    return {
        startDayOfWeekUtc,
        startTimeUtc: startTime * 1000 * 1000 * 60,
        endDayOfWeekUtc,
        endTimeUtc: endTime * 1000 * 1000 * 60
    };
}

export const formattedWorkList = (workingList: MapWorkingTime[], timeZone: string): WorkingTime[] => (
    workingList
        .filter(({ startTimeMin, endTimeMin }) => !(!startTimeMin && !endTimeMin))
        .map((time) => getResultTime(time, timeZone)) || []
);
