import {
    genericFoldersAreEqual,
    getGenericIceboxFolderForIdentityOrNull,
    getParsedJsonOrDefaultValue,
    localFolderToGenericFolder
} from '../../../modules/core-utils.mjs.js';
import {
    clearContents,
    createRemindMeBeforePicker,
    createTimePresetPicker,
    isDarkMode,
    selectDefaultActionPreset,
    selectDefaultTimePreset
} from '../../../modules/ui-utils.mjs.js';
import {
    createCorrelationId,
    createLogger
} from '../../../modules/logger.mjs.js';
import { translateDocument } from '../../../modules/ui-utils.mjs.js';

const logger = createLogger('views/popups/create-outgoing-mindr');

const getDialogParameters = () => {
    const correlationId = createCorrelationId(`getDialogParameters`);
    logger.log('BEGIN getDialogParameters', { correlationId });
    const params = new URLSearchParams(window.location.search.substr(1));
    const result = {
        dialogId: params.get('dialogId'),
        headerMessageId: params.get('headerMessageId'),
        author: params.get('author'),
        subject: params.get('subject'),
        folderAccountId: params.get('folderAccountId'),
        folderName: params.get('folderName'),
        folderPath: params.get('folderPath'),
        folderType: params.get('folderType'),
        guid: params.get('guid'),
        folderAccountIdentityMailAddress: params.get(
            'folderAccountIdentityMailAddress'
        )
    };

    logger.log('dialog result', { correlationId, result });
    logger.log('END getDialogParameters', { correlationId });

    return result;
};

const closePopup = async () => {
    const correlationId = createCorrelationId('closePopup');
    logger.log(`BEGIN closePopup`, { correlationId });
    logger.log(`try to get dialog parameters`);
    try {
        const { dialogId } = getDialogParameters();
        logger.log(`closing dialog ${dialogId}`);
        window.close();
    } catch (e) {
        logger.error('create-outgoing-mindr::closePopup', e);
    }
    logger.log('END closePopup', { correlationId });
};

const doCancel = async () => await closePopup();

const resetComposeActionIconAndLabel = async id => {
    const path = isDarkMode()
        ? '/images/mailmindr-flag--white.svg'
        : '/images/mailmindr-flag.svg';
    await Promise.all([
        messenger.composeAction.setIcon({
            path,
            tabId: id
        }),
        messenger.composeAction.setLabel({
            label: messenger.i18n.getMessage('mailmindrComposeMessageButton'),
            tabId: id
        })
    ]);
};

const handleChangeTimePreset = event => {
    const {
        target: { value }
    } = event;

    const preset = getParsedJsonOrDefaultValue(value, {});
    const { days, hours, minutes, isRelative, isSelectable } = preset;

    if (!isSelectable) {
        logger.log('nothing to change here');
        return;
    }

    const millisecondsForDays = days * 24 * 60 * 60 * 1000;
    let now = Date.now() + millisecondsForDays;

    if (isRelative) {
        now +=
            hours * 60 * 60 * 1000 /* add hours */ +
            minutes * 60 * 1000; /* add minutes */
    }

    const nowAsDate = new Date(now);
    const newDate = new Date(
        Date.UTC(
            nowAsDate.getFullYear(),
            nowAsDate.getMonth(),
            nowAsDate.getDate()
        )
    );
    /** @type {HTMLInputDateElement} */
    const datePicker = document.getElementById('mailmindr--date-picker');
    /** @type {HTMLInputTimeElement} */
    const timePicker = document.getElementById('mailmindr--time-picker');

    datePicker.valueAsDate = newDate;

    if (isRelative) {
        const hourString = `0${nowAsDate.getHours()}`.substr(-2);
        const minuteString = `0${nowAsDate.getMinutes()}`.substr(-2);
        const newTimePickerValue = `${hourString}:${minuteString}`;

        timePicker.value = newTimePickerValue;
    } else {
        const hourString = `0${hours}`.substr(-2);
        const minuteString = `0${minutes}`.substr(-2);
        const newTimePickerValue = `${hourString}:${minuteString}`;

        timePicker.value = newTimePickerValue;

        const pickedDateTime = getDateTimefromPickers();

        logger.info(pickedDateTime, new Date());

        if (pickedDateTime <= new Date()) {
            logger.info(
                'adjusting time by adding a day, adjusted to: ',
                getDateTimefromPickers()
            );
            // 
            datePicker.valueAsDate = new Date(Date.now() + 24 * 60 * 60 * 1000);
        }
    }
};

const getDateTimefromPickers = () => {
    /** @type {HTMLInputDateElement} */
    const datePicker = document.getElementById('mailmindr--date-picker');
    /** @type {HTMLInputTimeElement} */
    const timePicker = document.getElementById('mailmindr--time-picker');

    const timePickerValue = timePicker.value;
    const [hours, minutes] = timePickerValue
        .split(':')
        .map(item => Number.parseInt(item, 10));

    const [year, month, day] = datePicker.value.split('-');
    const newDate = new Date(year, month - 1, day, hours, minutes, 0, 0);

    logger.warn(
        'current date from datepicker without adjusting time and timezone',
        newDate
    );

    return newDate;
};

const getActionTemplateFromPicker = () => {
    const actionTemplatePicker = /** @type {HTMLInputElement} */ (document.getElementById(
        'mailmindr--preset-action'
    ));
    const actionTemplate = JSON.parse(actionTemplatePicker.value);

    return actionTemplate;
};

const doRemove = async () => {
    const { windowId, id } = await messenger.tabs.getCurrent();
    const sender = { windowId, id };
    const removed = await messenger.runtime.sendMessage({
        action: 'mindr:remove-outgoing-mindr',
        payload: { sender }
    });

    if (removed && removed.status && removed.status === 'ok') {
        await resetComposeActionIconAndLabel(id);
        doCancel();
    }
};

const onLoad = async () => {
    const { windowId, id } = await messenger.tabs.getCurrent();
    const result = await messenger.runtime.sendMessage({
        action: 'dialog:open',
        payload: { name: 'set-outgoing-mindr', sender: { windowId, id } }
    });

    const {
        payload: {
            settings,
            presets: { time, actions, remindMeMinutesBefore },
            draft
        }
    } = result;

    const editMindr = Boolean(draft);
    const removeButton = document.getElementById('mailmindr--do-remove-mindr');
    removeButton.addEventListener('click', doRemove);
    removeButton.setAttribute(
        'style',
        editMindr ? 'display: block;' : 'display: none;'
    );

    const cancelButton = document.getElementById(
        'mailmindr--do-cancel-create-mindr'
    );
    cancelButton.addEventListener('click', doCancel);

    const acceptButton = document.getElementById('mailmindr--do-create-mindr');
    acceptButton.addEventListener('click', async (
        source,
        /** @type{ MouseEvent} */ event
    ) => {
        const sender = await messenger.windows.getLastFocused({
            windowTypes: ['messageCompose']
        });
        doAccept(sender);
    });

    /** @type {HTMLInputDateElement} */
    const datePicker = document.getElementById('mailmindr--date-picker');
    /** @type {HTMLInputTimeElement} */
    const timePicker = document.getElementById('mailmindr--time-picker');

    const now = new Date();
    const hours = `0${now.getHours()}`.substr(-2);
    const minutes = `0${now.getMinutes()}`.substr(-2);

    timePicker.value = [hours, minutes].join(':');
    datePicker.valueAsDate = now;

    const actionPresets = document.getElementById('mailmindr--preset-action');
    actions.map(actionPreset => {
        const actionOption = document.createElement('option');
        actionOption.value = JSON.stringify(actionPreset);
        actionOption.innerText = actionPreset.text;

        actionPresets.appendChild(actionOption);
    });

    const timePresets = createTimePresetPicker(
        document.getElementById('mailmindr--preset-time'),
        time
    );
    const handlePickerChange = () => {
        const presetTimePicker = /** @type {HTMLSelectElement} */ (document.getElementById(
            'mailmindr--preset-time'
        ));
        presetTimePicker.selectedIndex = 0;
    };

    datePicker.addEventListener('change', handlePickerChange);
    timePicker.addEventListener('change', handlePickerChange);
    timePresets.addEventListener('change', handleChangeTimePreset);

    if (editMindr) {
        const { mindr } = draft;
        const due = mindr.due;
        const dueHours = `0${due.getHours()}`.substr(-2);
        const dueMinutes = `0${due.getMinutes()}`.substr(-2);

        timePicker.value = [dueHours, dueMinutes].join(':');
        datePicker.valueAsDate = due;

        timePresets.selectedIndex = 0;

        const preselectedAction = mindr?.actionTemplate
            ? { ...mindr?.actionTemplate, moveMessageTo: undefined }
            : undefined;

        selectDefaultActionPreset(actionPresets, preselectedAction);
    } else {
        const defaultTimePreset = settings?.defaultTimePreset;
        const defaultActionPreset = settings?.defaultActionPreset;

        selectDefaultTimePreset(timePresets, defaultTimePreset);
        selectDefaultActionPreset(actionPresets, defaultActionPreset);

        const changeEvent = new Event('change');
        timePresets.dispatchEvent(changeEvent);
    }

    const remindMe = document.getElementById('mailmindr--preset-remind-me');
    // 
    createRemindMeBeforePicker(
        document,
        remindMe,
        remindMeMinutesBefore,
        settings.defaultRemindMeMinutesBefore
    );

    translateDocument(document);
};

document.addEventListener('DOMContentLoaded', onLoad, { once: true });
document.addEventListener('keydown', async event => {
    if (event.code === 'Escape') {
        await doCancel();
    }
});

const doAccept = async (/** @type {Window} */ sender) => {
    // 
    const remindMe = document.getElementById('mailmindr--preset-remind-me');
    const remindMeMinutesBefore = parseInt(
        /** @type {HTMLInputElement} */ (remindMe).value || '0',
        10
    );

    const due = getDateTimefromPickers();
    const actionTemplate = getActionTemplateFromPicker();

    // 
    // 
    // 
    // 
    // 
    // 
    // 
    // 
    // 

    // 

    const {
        guid,
        headerMessageId,
        author,
        subject,
        folderAccountId,
        folderName,
        folderPath,
        folderType,
        folderAccountIdentityMailAddress
    } = getDialogParameters();

    if (remindMeMinutesBefore) {
        if (remindMeMinutesBefore >= 0) {
            actionTemplate.showReminder = true;
        } else {
            actionTemplate.showReminder = false;
        }
    }

    const { windowId, id } = await messenger.tabs.getCurrent();
    const payload = {
        mindr: {
            guid,
            headerMessageId,
            due,
            remindMeMinutesBefore,
            actionTemplate,
            notes: '',
            metaData: {
                headerMessageId,
                author,
                subject,
                folderAccountId,
                folderName,
                folderPath,
                folderType,
                folderAccountIdentityMailAddress
            },
            isWaitingForReply: true,
            doMoveToIcebox: false
        },
        sender: { windowId, id }
    };
    const result = await messenger.runtime.sendMessage({
        action: 'mindr:create-outgoing',
        payload
    });
    if (result && result.status === 'ok') {
        // 
        const path = isDarkMode()
            ? '/images/mailmindr-flag_marker--white.svg'
            : '/images/mailmindr-flag_marker.svg';
        const currentLocale = navigator.language;
        const formattedTime = new Intl.DateTimeFormat(currentLocale, {
            timeStyle: 'short'
        }).format(due);
        const formattedDate = new Intl.DateTimeFormat(currentLocale, {
            dateStyle: 'short'
        }).format(due);
        const formattedDateAndTime = new Intl.DateTimeFormat(currentLocale, {
            dateStyle: 'medium',
            timeStyle: 'short'
        }).format(due);

        await Promise.all([
            messenger.composeAction.setIcon({
                path,
                tabId: id
            }),
            messenger.composeAction.setLabel({
                label: messenger.i18n.getMessage(
                    'mailmindrComposeMessageButton.detailed',
                    [formattedDate, formattedTime, formattedDateAndTime]
                ),
                tabId: id
            })
        ]);

        doCancel();
    } else {
        await resetComposeActionIconAndLabel(id);
    }
};
