import { baseUniDriverFactory } from '../../unidriver';
import { CheckboxUniDriver, DropdownUniDriver, FormFieldUniDriver, InputAreaUniDriver, InputUniDriver, NumberInputUniDriver, TimeInputUniDriver, } from '@wix/design-system/dist/testkit/unidriver';
import { dataHooks } from '../dataHooks';
import { DatePickerUniDriver } from '../../unidriver/DatePicker.uni.driver';
export default (base, body) => {
    const fieldType = () => base.attr('data-field-type');
    const inputBase = (suffix = '') => base.$(`[data-hook="${dataHooks.Input}${suffix}"]`);
    const dropdown = () => DropdownUniDriver(inputBase(), body);
    const checkbox = () => CheckboxUniDriver(inputBase(), body);
    const formField = () => FormFieldUniDriver(base.$(`[data-hook="${dataHooks.Label}"]`), body);
    return {
        /**
         * Gets field label
         */
        getLabel: async () => {
            const type = await fieldType();
            if (type === 'checkbox') {
                return checkbox().getLabel();
            }
            const element = await formField().getLabel();
            return element?.textContent;
        },
        /**
         * Gets field value
         */
        getValue: async () => {
            const type = await fieldType();
            switch (type) {
                case 'url':
                case 'shortText':
                    return InputUniDriver(inputBase(), body).getValue();
                case 'date':
                    return (await DatePickerUniDriver(inputBase(), body)).inputDriver.getValue();
                case 'dateTime':
                    const date = await (await DatePickerUniDriver(inputBase('-date'), body)).inputDriver.getValue();
                    const format = Intl.DateTimeFormat([], {
                        hour: 'numeric',
                        minute: 'numeric',
                    });
                    const time = await TimeInputUniDriver(inputBase('-time'), body).getValue();
                    if (isNaN(time.getTime())) {
                        return date;
                    }
                    return `${date} ${format.format(time)}`;
                case 'checkbox':
                    return checkbox().isChecked();
                case 'longText':
                    return InputAreaUniDriver(inputBase(), body).getValue();
                case 'dropdown':
                    return dropdown().inputDriver.getValue();
                case 'integer':
                case 'decimal':
                    return NumberInputUniDriver(inputBase(), body).getValue();
                default:
                    throw new Error(`Driver for type '${type}' not found.`);
            }
        },
        /**
         * Gets field status message
         */
        getStatusMessage: async () => {
            const type = await fieldType();
            switch (type) {
                case 'shortText':
                case 'url':
                    return FormFieldUniDriver(base, body).getStatusMessage();
                case 'date':
                    return (await DatePickerUniDriver(inputBase(), body)).inputDriver.getStatusMessage();
                case 'dateTime':
                    let dateStatusMessage;
                    let timeStatusMessage;
                    try {
                        dateStatusMessage = await (await DatePickerUniDriver(inputBase('-date'), body)).inputDriver.getStatusMessage();
                    }
                    catch { }
                    try {
                        timeStatusMessage = await TimeInputUniDriver(inputBase('-time'), body).getStatusMessage();
                    }
                    catch { }
                    return [dateStatusMessage, timeStatusMessage].join('\n').trim();
                case 'longText':
                    return InputAreaUniDriver(inputBase(), body).getStatusMessage();
                case 'dropdown':
                    return dropdown().inputDriver.getStatusMessage();
                case 'integer':
                case 'decimal':
                    return NumberInputUniDriver(inputBase(), body).getStatusMessage();
                default:
                    throw new Error(`Driver for type '${type}' not found.`);
            }
        },
        /**
         * Enters field value, handles different value types based on field type
         */
        enterValue: async (value, { locale = 'en' } = {}) => {
            const type = await fieldType();
            switch (type) {
                case 'url':
                    const inputDriver = InputUniDriver(inputBase(), body);
                    await inputDriver.enterText(value);
                    const { page } = await inputBase().getNative();
                    // jsdom
                    if (!page?.evaluate) {
                        await inputDriver.blur();
                    }
                    return;
                case 'shortText':
                    return InputUniDriver(inputBase(), body).enterText(value);
                case 'date':
                    const datePickerUniDriver = await DatePickerUniDriver(inputBase(), body);
                    await datePickerUniDriver.inputDriver.enterText(typeof value === 'string'
                        ? value
                        : `${Intl.DateTimeFormat().format(value)}`);
                    const { page: pageWithDate } = await inputBase().getNative();
                    // jsdom
                    if (!pageWithDate?.evaluate) {
                        await datePickerUniDriver.inputDriver.blur();
                    }
                    return;
                case 'dateTime':
                    let dateValue = '';
                    let timeValue = '';
                    if (typeof value === 'string') {
                        const parts = value.split('T');
                        dateValue = parts[0];
                        timeValue = parts[1];
                    }
                    else {
                        dateValue = `${Intl.DateTimeFormat([locale]).format(value)}`;
                        timeValue = Intl.DateTimeFormat([locale], {
                            hour: 'numeric',
                            minute: 'numeric',
                        }).format(value);
                    }
                    const datetimePickerUniDriver = await DatePickerUniDriver(inputBase('-date'), body);
                    await datetimePickerUniDriver.inputDriver.enterText(dateValue);
                    const { page: pageWithDatetime } = await inputBase('-date').getNative();
                    // jsdom
                    if (!pageWithDatetime?.evaluate) {
                        // We do it twice because we have a bug when removing the value in first time
                        await datetimePickerUniDriver.inputDriver.enterText(dateValue);
                        await datetimePickerUniDriver.inputDriver.blur();
                    }
                    const timeInput = TimeInputUniDriver(inputBase('-time'), body);
                    await timeInput.setValue(timeValue);
                    const element = await inputBase('-time').getNative();
                    if (!element.page?.evaluate) {
                        await timeInput.confirmValue();
                    }
                    return;
                case 'checkbox':
                    const checkboxDriver = checkbox();
                    const isChecked = await checkboxDriver.isChecked();
                    if (value && !isChecked) {
                        await checkboxDriver.click();
                    }
                    else if (isChecked && !value) {
                        await checkboxDriver.click();
                    }
                    return;
                case 'longText':
                    return InputAreaUniDriver(inputBase(), body).enterText(value);
                case 'dropdown':
                    const dropdownDriver = dropdown();
                    await dropdownDriver.dropdownLayoutDriver.click();
                    return dropdownDriver.dropdownLayoutDriver.clickAtOptionWithValue(value);
                case 'integer':
                case 'decimal':
                    return NumberInputUniDriver(inputBase(), body).enterText(value);
                default:
                    throw new Error(`Driver for type '${type}' not found.`);
            }
        },
        /**
         * Returns available dropdown options
         */
        getOptions: async () => {
            const type = await fieldType();
            if (type !== 'dropdown') {
                throw new Error(`Field type '${type}' does not support this method.`);
            }
            return dropdown().dropdownLayoutDriver.optionsContent();
        },
        /**
         * Returns remaining chars count on fields with maxLength
         */
        getLengthLeft: async () => {
            return formField().getLengthLeft();
        },
        ...baseUniDriverFactory(base),
    };
};
//# sourceMappingURL=Field.uni.driver.js.map