import { createElement, Dropdown, Popup, showAlert, createIcon, DateSelector, showConfirm, Grid, OptionBase, createCheckbox } from "../ui";
import { nullOrEmpty } from "../utility";
import AssetSelector from "./assetSelector";

const iconWorkOrder = 'data:image/png;base64, ';

/**
 * @private
 * @param {HTMLElement} element 
 * @param {boolean?} display 
 * @returns {HTMLElement}
 */
function displayElement(element, display) {
    element.style.display = display === false ? 'none' : '';
    return element;
}

/**
 * @private
 * @param {HTMLInputElement} element 
 * @param {string} pattern
 * @returns {HTMLInputElement}
 */
function patternValidation(element, pattern) {
    element.pattern = pattern;
    return element;
}

/**
 * @private
 * @param {"mile" | "mi" | "m" | "kilometre" | "km" | "kilometres"} uom 
 * @returns {"Mile" | "Kilometre"}
 */
function getOdometerUnit(uom) {
    if (nullOrEmpty(uom)) {
        return 'Mile';
    }
    switch (uom.toLowerCase()) {
        case 'mile':
        case 'mi':
        case 'm':
            return 'Mile';
        case 'kilometre':
        case 'km':
        case 'kilometres':
            return 'Kilometre';
        default:
            return 'Mile';
    }
}

export default class AddWorkOrder extends OptionBase {
    _var = {
        /**
         * @private
         * @type {HTMLElement}
         */
        container: null,
        /**
         * @private
         * @type {Popup}
         */
        assetSelectorPopup: null,
        /**
         * @private
         * @property {number} Id 
         * @property {string} VIN 
         * @property {string} DisplayName 
         * @property {boolean} OnRoad 
         * @property {boolean} Hide 
         * @property {number} [EngineHours] 
         * @property {number} [Odometer] 
         * @property {string} [OdometerUOM] 
         */
        asset: null,
        /**
         * @private
         * @property {string} Id 
         * @property {string} Name 
         * @property {string} Code 
         */
        customer: null,
        contacts: [],
        followers: [],
        params: {
            Locations: [],
            Departments: [],
            Advisors: [],
            OrderTypes: [],
            Statuses: [],
            Jobsites: [],
            Codes: []
        },
        el: {
            /**
             * @private
             * @type {HTMLTextAreaElement}
             */
            textComplaint: null,
            /**
             * @private
             * @type {Dropdown}
             */
            dropWorkOrderType: null,
            /**
             * @private
             * @type {Dropdown}
             */
            dropStatus: null,
            /**
             * @private
             * @type {DateSelector}
             */
            dateCompleted: null,
            /**
             * @private
             * @type {HTMLInputElement}
             */
            inputHours: null,
            /**
             * @private
             * @type {HTMLInputElement}
             */
            inputOdometer: null,
            /**
             * @private
             * @type {Dropdown}
             */
            dropOdometerUnit: null,
            /**
             * @private
             * @type {Dropdown}
             */
            dropAssetStatus: null,
            /**
             * @private
             * @type {DateSelector}
             */
            dropAssignedTo: null,
            /**
             * @private
             * @type {Dropdown}
             */
            dropAdvisor: null,
            /**
             * @private
             * @type {Dropdown}
             */
            dropLocation: null,
            /**
             * @private
             * @type {Dropdown}
             */
            dropDepartment: null
        }
    };

    onAssetAdded;
    onAssetSelected;
    onSave;

    static IconWorkOrder = iconWorkOrder;

    constructor(opt = {
        allowCustomer: false,
        assetFullcontrol: false,
        /**
         * @private
         * @type {(assetId: number) => Promise<{Id: number, VIN: string, DisplayName: string, OnRoad: boolean, Hide: boolean, EngineHours?: number, Odometer?: number, OdometerUOM?: string}>}
         */
        requestAssetInfo: null,
        /**
         * @private
         * @type {() => Promise<{Statuses: any[], Jobsites: any[], Codes: any[], Advisors: any[], Locations: any[], Departments: any[], OrderTypes: any[], AssetId: null}>}
         */
        requestWorkOrderParams: null,
        /**
         * @private
         * @type {(hidden: boolean, search?: string, groups?: string[], jobsites?: number[], codes?: string[]) => Promise<any[]>}
         */
        requestAssets: null,
        /**
         * @private
         * @type {() => Promise<any>}
         */
        requestAddAsset: null,
        /**
         * @private
         * @type {() => Promise<{Customer: any, Contacts: any[], Followers: any[]}>}
         */
        requestCustomers: null,
        /**
         * @private
         * @type {(assetId: number, locationId: number, departmentId: number) => Promise<any[]>}
         */
        requestAssignedTo: null,
        /**
         * @private
         * @type {(assetId: number) => Promise}
         */
        requestHideAsset: null,
        /**
         * @private
         * @type {(assetId: number) => Promise<any[]>}
         */
        requestOpenedWorkorder: null,
        zIndex: 999
    }) {
        super(opt);
    }

    async getItem() {
        const title = this.r('FLTL_02078', 'Open Work Order');
        const el = this._var.el;
        let status = el.dropStatus.selected;
        if (status != null) {
            status = {
                Status: status.Id,
                StatusType: status.StatusType,
                StatusName: status.Name,
                StatusAutoText: status.AutoText,
                StatusMessage: status.Message
            };
        } else {
            status = {
                Status: -1
            };
        }
        let assetstatus = el.dropAssetStatus.selected;
        if (assetstatus != null) {
            assetstatus = {
                AssetCustomStatus: assetstatus.Id,
                AssetCustomStatusType: assetstatus.Type,
                AssetCustomStatusName: assetstatus.Name
            };
        } else {
            assetstatus = {
                AssetCustomStatus: -1
            };
        }
        let machine = this._var.asset;
        if (machine == null) {
            showAlert(title, this.r('FLTL_00311', 'Asset cannot be empty.')).then(() => this._var.container.querySelector('.wo-asset>svg')?.focus());
            return null;
        }
        const item = {
            Id: -1,
            Description: el.textComplaint.value,
            WorkOrderType: el.dropWorkOrderType.selected?.Key ?? '',
            CompleteDate: el.dateCompleted.element.value,
            // MeterType: 
            HourMeter: el.inputHours.value || -1,
            Odometer: el.inputOdometer.value || -1,
            OdometerUnits: el.dropOdometerUnit.selected?.value ?? 'Mile',
            AssignedTo: el.dropAssignedTo.selected?.IID ?? '',
            AdvisorId: el.dropAdvisor.selected?.Key ?? '',
            LocationId: el.dropLocation.selected?.ID || -1,
            DepartmentId: el.dropDepartment.checked?.Id || -1,
            AssetID: machine.Id,
            VIN: machine.VIN,
            AssetName: machine.DisplayName,
            WorkOrderTotalCost: -1,
            HoursToComplete: -1,
            OtherCost: -1,
            PartsCost: -1,
            TravelTimeCost: -1,
            LaborCost: -1,
            HourlyRate: -1,
            InspectionTemplateId: -1,
            ...status,
            ...assetstatus
        };
        item.CustomerId = this._var.customer?.Id ?? -1;
        item.Contacts = this._var.contacts ?? [];
        item.Followers = this._var.followers ?? [];
        if (nullOrEmpty(el.textComplaint?.value)) {
            showAlert(title, this.r('FLTL_00602', 'Complaint is required.')).then(() => el.textComplaint.focus());
            return null;
        }
        item.MeterType = machine.OnRoad ? 'Odometer' : 'HourMeter';
        if (el.dropStatus.selected?.Completed) {
            if (!el.dateCompleted.element.validity.valid) {
                showAlert(title, this.r('FLTL_00613', 'Completed Date cannot be empty.')).then(() => el.dateCompleted.element.focus());
                return null;
            }
            if (machine.OnRoad) {
                if (nullOrEmpty(item.Odometer) || isNaN(item.Odometer) || item.Odometer < 0) {
                    showAlert(title, this.r('FLTL_02044', 'Odometer format error.')).then(() => el.inputOdometer.focus());
                    return null;
                }
            } else {
                if (nullOrEmpty(item.HourMeter) || isNaN(item.HourMeter) || item.HourMeter < 0) {
                    showAlert(title, this.r('FLTL_01516', 'Hour Meter format error.')).then(() => el.inputHours.focus());
                    return null;
                }
            }
        }
        return item;
    }

    async show() {
        const option = this._option;
        const allowCustomer = option.allowCustomer === true;
        const allowCommunicate = option.allowCommunicate === true;
        const commReadOnly = option.commReadOnly === true;
        const msgVariables = option.msgVariables || [];
        const title = this.r('FLTL_02078', 'Open Work Order');
        const tabIndex = Math.max.apply(null, [...document.querySelectorAll('[tabindex]')].map(e => e.tabIndex ?? 0)) + 3;
        const textComplaint = createElement('textarea', textarea => {
            textarea.tabIndex = tabIndex + 2;
            textarea.className = 'ui-text wo-complaint';
            textarea.placeholder = this.r('FLTL_01155', 'Enter Complaint');
        });
        const baseOption = {
            search: true,
            textKey: 'Value',
            valueKey: 'Key'
        };
        const dropWorkOrderType = new Dropdown({
            tabIndex: tabIndex + 3,
            input: true,
            ...baseOption
        });
        const dropStatus = new Dropdown({
            tabIndex: tabIndex + 5,
            htmlTemplate: it => createElement('span', 'wo-color-line',
                createElement('em', em => em.style.backgroundColor = it.Color),
                createElement('label', label => label.innerText = it.Name)
            ),
            search: true,
            textKey: 'Name',
            valueKey: 'Id'
        });
        const dateCompleted = new DateSelector({
            tabIndex: tabIndex + 6,
            className: 'wo-status-closed'
        });
        const inputHours = createElement('input', input => {
            input.type = 'text';
            input.tabIndex = tabIndex + 7;
            input.className = 'ui-input wo-hours input-hours';
        });
        const inputOdometer = createElement('input', input => {
            input.type = 'text';
            input.tabIndex = tabIndex + 8;
            input.className = 'ui-input wo-odometer input-odometer';
        });
        const dropOdometerUnit = new Dropdown({
            tabIndex: tabIndex + 9,
            selected: 'Mile'
        });
        dropOdometerUnit.source = [
            { value: 'Mile', text: this.r('FLTL_01922', 'Mile') },
            { value: 'Kilometre', text: this.r('FLTL_01694', 'Kilometer') }
        ]
        const dropAssetStatus = new Dropdown({
            tabIndex: tabIndex + 5,
            htmlTemplate: it => createElement('span', 'wo-color-line',
                createElement('em', em => em.style.backgroundColor = it.Color),
                createElement('label', label => label.innerText = it.Name)
            ),
            search: true,
            textKey: 'Name',
            valueKey: 'Id'
        });
        const dropAssignedTo = new Dropdown({
            tabIndex: tabIndex + 10,
            selected: '',
            search: true,
            valueKey: 'IID',
            textKey: 'DisplayName'
        });
        dropAssignedTo.source = [{ IID: '', DisplayName: '' }];
        const dropAdvisor = new Dropdown({
            tabIndex: tabIndex + 11,
            selected: '',
            ...baseOption
        });
        const dropLocation = new Dropdown({
            tabIndex: tabIndex + 12,
            selected: -1,
            search: true,
            valueKey: 'ID',
            textKey: 'Name'
        });
        const dropDepartment = new Dropdown({
            tabIndex: tabIndex + 13,
            selected: -1,
            search: true,
            valueKey: 'Id',
            textKey: 'Name'
        });
        const dropMSGVariables = new Dropdown({
            selected: -1,
            search: true,
            valueKey: 'Id',
            textKey: 'Name'
        });
        dropMSGVariables.source = msgVariables.map(v => { return { Id: v.Name, Name: v.Name }; });
        const textMessage = createElement('textarea', textarea => {
            textarea.className = 'ui-text wo-message';
        });
        const dropMSGVariablesElement = dropMSGVariables.create();
        dropMSGVariablesElement.style.width = '200px';

        // save variables
        this._var.el = {
            textComplaint,
            dropWorkOrderType,
            dropStatus,
            dateCompleted,
            inputHours,
            inputOdometer,
            dropOdometerUnit,
            dropAssetStatus,
            dropAssignedTo,
            dropAdvisor,
            dropLocation,
            dropDepartment
        }

        const container = createElement('div', 'open-wo-container',
            createElement('div', 'open-wo-header',
                createElement('img', img => img.src = iconWorkOrder),
                createElement('h3', h3 => h3.innerText = title)
            ),
            createElement('div', 'open-wo-content',
                createElement('div', 'wo-combined wo-asset',
                    createElement('span', span => {
                        span.className = 'wo-title wo-title-required';
                        span.innerText = this.r('FLTL_00361', 'Asset:');
                    }),
                    createIcon('fa-light', 'search', svg => {
                        svg.tabIndex = tabIndex + 1;
                        svg.addEventListener('click', async () => {
                            let popup = this._var.assetSelectorPopup;
                            if (popup == null) {
                                const selector = new AssetSelector({
                                    assetFullcontrol: option.assetFullcontrol,
                                    loading: flag => this._var.assetSelectorPopup.loading = flag,
                                    close: () => this._var.assetSelectorPopup.close(),
                                    requestAssets: option.requestAssets,
                                    requestAddAsset: option.requestAddAsset,
                                    dataSource: this._var.params
                                });
                                selector.onSelected = async it => {
                                    const el = this._var.el;
                                    if (typeof option.requestAssetInfo === 'function') {
                                        const a = await option.requestAssetInfo(it.Id);
                                        if (a != null) {
                                            it = a;
                                            if (it.OnRoad) {
                                                el.inputHours.value = '';
                                                el.inputOdometer.value = it.Odometer;
                                                el.dropOdometerUnit.select(getOdometerUnit(it.OdometerUOM));
                                            } else {
                                                el.inputHours.value = it.EngineHours;
                                                el.inputOdometer.value = '';
                                                el.dropOdometerUnit.select('Mile');
                                            }
                                            el.dropAssetStatus.select(it.CustomStatus);
                                        }
                                    }
                                    this._var.asset = it;
                                    if (typeof this.onAssetSelected === 'function') {
                                        this.onAssetSelected(it);
                                    }
                                    this._var.container.querySelector('.wo-asset-name').innerText = it.DisplayName;
                                    // get assigned to
                                    if (typeof option.requestAssignedTo === 'function') {
                                        const data = await option.requestAssignedTo(it.Id, el.dropLocation.selected?.ID ?? -1, el.dropDepartment.selected?.Id ?? -1)
                                        el.dropAssignedTo.source = [{ IID: '', DisplayName: '' }, ...data];
                                        el.dropStatus.onSelected(el.dropStatus.selected);
                                    }
                                };
                                popup = new Popup({
                                    title: this.r('FLTL_02645', 'Select Asset'),
                                    content: selector.create(),
                                    persistent: true,
                                    buttons: [
                                        {
                                            key: 'ok',
                                            text: this.r('FLTL_02057', 'OK'),
                                            trigger: () => selector.select()
                                        },
                                        { text: this.r('FLTL_00499', 'Cancel') }
                                    ]
                                });
                                this._var.assetSelectorPopup = popup;
                                popup.create();
                                popup.rect = { width: 1220 };
                                const mask = await popup.show();
                                mask.style.zIndex = option.zIndex ?? 999;
                                await selector.init();
                            } else {
                                await popup.show();
                            }
                        });
                    })
                ),
                createElement('span', 'wo-asset-name'),
                createElement('div', 'wo-line wo-combined',
                    createElement('span', span => {
                        span.className = 'wo-title wo-title-required';
                        span.innerText = this.r('FLTL_00603', 'Complaint:');
                    })
                ),
                createElement('div', div => {
                    div.className = 'wo-line wo-combined wo-sub-line';
                    div.style.marginBottom = '2px';
                    div.style.width = 'calc(100% - 10px)';
                },
                    textComplaint
                ),
                createElement('span', span => {
                    span.className = 'wo-title';
                    span.innerText = this.r('FLTL_03359', 'Work Order Type:');
                }),
                dropWorkOrderType.create(),
                createElement('div', div => {
                    div.className = 'wo-combined wo-customer-record';
                    if (!allowCustomer) {
                        displayElement(div, false);
                    }
                },
                    createElement('span', span => {
                        span.className = 'wo-title';
                        span.innerText = this.r('FLTL_00598', 'Company Name:');
                    }),
                    createIcon('fa-light', 'search', svg => {
                        svg.tabIndex = tabIndex + 4;
                        svg.addEventListener('click', async () => {
                            if (typeof option.requestCustomers === 'function') {
                                popup.loading = true;
                                const data = await option.requestCustomers();
                                popup.loading = false;
                                if (data != null) {
                                    this._var.customer = data.Customer;
                                    this._var.contacts = data.Contacts;
                                    this._var.followers = data.Followers;
                                    let name = data.Customer.Name;
                                    if (!nullOrEmpty(data.Customer.Code)) {
                                        name += ' / ' + data.Customer.Code;
                                    }
                                    this._var.container.querySelector('.wo-company-name').innerText = name;
                                }
                            }
                        });
                    })
                ),
                displayElement(createElement('span', 'wo-company-name'), allowCustomer),
                createElement('span', span => {
                    span.className = 'wo-title';
                    span.innerText = this.r('FLTL_02834', 'Status:');
                }),
                dropStatus.create(),
                createElement('span', span => {
                    span.className = 'wo-title wo-title-required wo-sub-line wo-status-closed';
                    span.innerText = this.r('FLTL_00617', 'Completed Date:');
                    displayElement(span, false);
                }),
                displayElement(dateCompleted.create(), false),
                createElement('span', span => {
                    span.className = 'wo-title wo-title-required wo-sub-line wo-hours';
                    span.innerText = this.r('FLTL_01530', 'Hours:');
                    displayElement(span, false);
                }),
                displayElement(
                    patternValidation(inputHours, '\\d+\\.?\\d*'),
                    false
                ),
                createElement('span', span => {
                    span.className = 'wo-title wo-title-required wo-sub-line wo-odometer';
                    span.innerText = this.r('FLTL_02054', 'Odometer:');
                    displayElement(span, false);
                }),
                createElement('div', div => {
                    div.className = 'wo-combined wo-odometer';
                    displayElement(div, false);
                },
                    patternValidation(inputOdometer, '\\d+\\.?\\d*'),
                    dropOdometerUnit.create()
                ),
                createElement('span', span => {
                    span.className = 'wo-title';
                    span.innerText = this.r('FLTL_03590', 'Asset Availability:');
                }),
                dropAssetStatus.create(),
                createElement('span', span => {
                    span.className = 'wo-title';
                    span.innerText = this.r('FLTL_00382', 'Assigned Tech:');
                }),
                dropAssignedTo.create(),
                createElement('span', span => {
                    span.className = 'wo-title wo-customer-record';
                    span.innerText = this.r('FLTL_00199', 'Advisor:');
                    if (!allowCustomer) {
                        displayElement(span, false);
                    }
                }),
                displayElement(dropAdvisor.create(), allowCustomer),
                createElement('span', span => {
                    span.className = 'wo-title wo-customer-record';
                    span.innerText = this.r('FLTL_01796', 'Location:');
                    if (!allowCustomer) {
                        displayElement(span, false);
                    }
                }),
                displayElement(dropLocation.create(), allowCustomer),
                createElement('span', span => {
                    span.className = 'wo-title wo-customer-record';
                    span.innerText = this.r('FLTL_00869', 'Department:');
                    if (!allowCustomer) {
                        displayElement(span, false);
                    }
                }),
                displayElement(dropDepartment.create(), allowCustomer)
            )
        );
        dropStatus.onSelected = item => {
            if (item == null) {
                return;
            }
            container.querySelectorAll('.wo-status-closed').forEach(it => it.style.display = item.Completed ? '' : 'none');
            if (item.Completed) {
                const onRoad = this._var.asset?.OnRoad;
                container.querySelectorAll('.wo-hours').forEach(it => it.style.display = onRoad ? 'none' : '');
                container.querySelectorAll('.wo-odometer').forEach(it => it.style.display = onRoad ? '' : 'none');
            } else {
                container.querySelectorAll('.wo-hours').forEach(it => it.style.display = 'none');
                container.querySelectorAll('.wo-odometer').forEach(it => it.style.display = 'none');
            }
        };
        dropLocation.onSelected = async loc => {
            // get assigned to
            const asset = this._var.asset;
            if (asset != null && typeof option.requestAssignedTo === 'function') {
                const data = await option.requestAssignedTo(asset.Id, loc?.ID ?? -1, this._var.el.dropDepartment.selected?.Id ?? -1)
                this._var.el.dropAssignedTo.source = [{ IID: '', DisplayName: '' }, ...data];
            }
            this.filterStatuses();
        };
        dropDepartment.onSelected = async dep => {
            // get assigned to
            const asset = this._var.asset;
            if (asset != null && typeof option.requestAssignedTo === 'function') {
                const data = await option.requestAssignedTo(asset.Id, this._var.el.dropLocation.selected?.ID ?? -1, dep?.Id ?? -1)
                this._var.el.dropAssignedTo.source = [{ IID: '', DisplayName: '' }, ...data];
            }
            this.filterStatuses();
        }
        dropWorkOrderType.onSelected = async loc => {
            this.filterStatuses();
        };
        dateCompleted.value = new Date();
        this._var.container = container;
        const popup = new Popup({
            title,
            content: container,
            buttons: [
                {
                    key: 'open',
                    text: this.r('FLTL_00700', 'Create Work Order'),
                    trigger: async () => {
                        popup.loading = true;
                        try {
                            const item = await this.getItem();
                            if (item == null) {
                                return false;
                            }
                            if (this._var.asset.Hide) {
                                if (!option.assetFullcontrol) {
                                    await showAlert(title, this.r('FLTL_02992', 'The selected asset is hidden and a work order cannot be created.') + '\n\n' + this.r('FLTL_02213', 'Please contact your Fleet Manager to Unhide the asset if you require a work order.'));
                                    return false;
                                }
                                const next = await showConfirm(title, this.r('FLTL_02992', 'The selected asset is hidden and a work order cannot be created.') + '\n\n' + this.r('FLTL_00999', 'Do you wish to "Un-Hide" the asset?'), [
                                    { key: 'unhide', text: this.r('FLTL_03378', 'Yes') },
                                    { key: 'cancel', text: this.r('FLTL_00502', 'Cancel Work Order') }
                                ]);
                                if (next.result !== 'unhide') {
                                    return false;
                                }
                                // hide
                                if (typeof option.requestHideAsset === 'function') {
                                    await option.requestHideAsset(this._var.asset.Id);
                                    this._var.asset.Hide = false;
                                }
                            }
                            if (typeof option.requestOpenedWorkorder === 'function') {
                                const wos = await option.requestOpenedWorkorder(this._var.asset.Id);
                                if (wos == null) {
                                    return false;
                                }
                                if (wos.length > 0) {
                                    const next = await new Promise(resolve => {
                                        const popWorkorders = new Popup({
                                            title,
                                            content: createElement('div', 'wo-opened-workorder',
                                                createElement('header', header => header.innerText = this.r('FLTL_02991', 'The selected asset has the following open work orders:')),
                                                createElement('div', 'wo-grid-opened')
                                            ),
                                            resolve,
                                            buttons: [
                                                { key: 'create', text: this.r('FLTL_00700', 'Create Work Order'), trigger: () => resolve('create') },
                                                { key: 'cancel', text: this.r('FLTL_00502', 'Cancel Work Order'), trigger: () => resolve('cancel') }
                                            ]
                                        });
                                        popWorkorders.show().then(mask => {
                                            const grid = new Grid(mask.querySelector('.wo-grid-opened'), this.r);
                                            grid.columns = [
                                                { key: 'WorkOrderNumber', caption: 'WO #', width: 100 },
                                                { key: 'CreateDateStr', caption: this.r('FLTL_00703', 'Created Date'), width: 120 },
                                                { key: 'Description', caption: this.r('FLTL_00600', 'Complaint'), width: 360 }
                                            ];
                                            grid.init();
                                            grid.source = wos.map(w => ({
                                                WorkOrderNumber: w.WorkOrderNumber,
                                                CreateDateStr: { DisplayValue: w.CreateDateStr, Value: w.CreateDate },
                                                Description: w.Description
                                            }));
                                            // default focus
                                            const button = mask.querySelector('.ui-popup-container .ui-popup-footer .ui-popup-button:last-child');
                                            button?.focus();
                                        });
                                    });
                                    if (next !== 'create') {
                                        return false;
                                    }

                                    if ((item.Status == 100 || item.StatusType == 100)
                                        && (item.AssetCustomStatus == 10 || item.AssetCustomStatusType == 10)) {
                                        let msgdiv = createElement('div', div => {
                                            div.style.minWidth = "300px";
                                            div.style.marginLeft = "50px";
                                            div.style.fontSize = "14px";
                                            let msghtml = this.r('FLTL_03591', 'Asset Availability is set to');
                                            msghtml += '&nbsp;<b style="color:#3d7892;">' + item.AssetCustomStatusName + '</b>';
                                            msghtml += '<br/><br/>' + this.r('FLTL_03592', 'Would you like to update?');
                                            div.innerHTML = msghtml;
                                        }
                                        );
                                        const nextassetstatus = await showConfirm(title, msgdiv, [
                                            { key: 'yes', text: this.r('FLTL_03378', 'Yes') },
                                            { key: 'no', text: this.r('FLTL_01978', 'No') }
                                        ]);
                                        if (nextassetstatus.result !== 'no') {
                                            return false;
                                        }
                                    }
                                }
                            }
                            const el = this._var.el;
                            if (item.Status > 0 && item.CustomerId > 0 && item.StatusMessage && allowCommunicate && !commReadOnly) {
                                const next = await new Promise(resolve => {
                                    let addButton;
                                    const chkSend = createCheckbox({
                                        label: this.r('FLTL_02700', 'Send Update To Customer'),
                                        onchange: () => {
                                            const chk = chkSend.querySelector('input');
                                            el.chkLink.querySelector('input').disabled = !chk.checked;
                                            el.txtMessage.disabled = !chk.checked;
                                            el.txtPhoneNumber.disabled = !chk.checked;
                                            dropMSGVariables.disabled = !chk.checked;
                                            addButton.disabled = !chk.checked;
                                        }
                                    });
                                    el.chkSend = chkSend;
                                    chkSend.style.paddingLeft = '0px';

                                    const chkLink = createCheckbox({
                                        label: this.r('FLTL_01580', 'Include Status Link')
                                    });
                                    el.chkLink = chkLink;
                                    chkLink.style.paddingLeft = '0px';
                                    el.txtMessage = textMessage;

                                    const iconmobile = createIcon('fa-solid', 'mobile-alt');
                                    const sPopup = new Popup({
                                        title: this.r('FLTL_02824', 'Status Change') + " - " + item.StatusName,
                                        content: createElement('div', 'wo-send-status-msg',
                                            createElement('label'),
                                            chkSend,
                                            createElement('div', div => {
                                                div.style.textAlign = 'right';
                                                div.style.paddingRight = '5px';
                                                div.appendChild(iconmobile);
                                            }),
                                            createElement('input', input => {
                                                input.type = 'text';
                                                el.txtPhoneNumber = input;
                                            }),
                                            createElement('label'),
                                            chkLink,
                                            createElement('label', label => {
                                                label.innerText = this.r('FLTL_01912', 'Message:');
                                                label.style.textAlign = 'right';
                                                label.style.paddingRight = '5px';
                                            }),
                                            createElement('div', div => {
                                                div.style.display = 'flex';
                                                div.style.alignItems = 'center';
                                                div.appendChild(dropMSGVariablesElement);
                                                addButton = createElement('input', input => {
                                                    input.type = 'button';
                                                    input.style.marginLeft = "10px";
                                                    input.style.height = "24px";
                                                    input.value = this.r('FLTL_00083', 'Add');
                                                })
                                                addButton.addEventListener('click', () => {
                                                    const text = dropMSGVariables.selected?.Name;
                                                    if (!text) return;
                                                    textMessage.focus();
                                                    const startPos = textMessage.selectionStart;
                                                    const endPos = textMessage.selectionEnd;
                                                    textMessage.value = textMessage.value.substring(0, startPos) + text + textMessage.value.substring(endPos, textMessage.value.length);
                                                    textMessage.selectionStart = textMessage.selectionEnd = startPos + text.length;
                                                });
                                                div.appendChild(addButton);
                                            }),
                                            createElement('label'),
                                            textMessage
                                        ),
                                        resolve,
                                        buttons: [
                                            { key: 'ok', text: this.r('FLTL_02582', 'Save Work Order and Send'), trigger: () => resolve('ok') },
                                            { key: 'cancel', text: this.r('FLTL_00499', 'Cancel'), trigger: () => resolve('cancel') }
                                        ]
                                    });

                                    var names = "";
                                    for (var i = 0; i < item.Contacts.length; i++) {
                                        var c = item.Contacts[i];
                                        if (c.OptOut || c.OptOut_BC) continue;
                                        var mp = $.trim(c.MobilePhone);
                                        var email = $.trim(c.Email);
                                        if ((c.ContactPreference == "0" && (checkPhoneNumber(mp))
                                            || (c.ContactPreference == "1" && isEmail(email)))) {
                                            if (names == "")
                                                names = c.Name;
                                            else
                                                names += ";" + c.Name;
                                        }
                                    }
                                    el.txtPhoneNumber.value = names;
                                    el.chkSend.querySelector('input').checked = item.StatusAutoText;
                                    el.chkSend.querySelector('input').dispatchEvent(new Event('change'));
                                    el.txtMessage.value = item.StatusMessage;
                                    dropMSGVariables.select(dropMSGVariables.source[0].Name);

                                    sPopup.show().then(mask => {
                                    });
                                });
                                if (next !== 'ok') {
                                    return false;
                                }
                            }
                            if (typeof this.onSave === 'function') {
                                const sendStatusInfo = (item.Status > 0 && item.CustomerId > 0 && item.StatusMessage && el.chkSend) ? {
                                    SendUpdateToCustomer: el.chkSend.querySelector('input').checked,
                                    IncludeStatusLink: el.chkLink.querySelector('input').checked,
                                    PhoneEmails: el.txtPhoneNumber.value,
                                    Comment: el.txtMessage.value,
                                } : null;
                                this.onSave(item, sendStatusInfo);
                            }
                        } finally {
                            popup.loading = false;
                        }
                    }
                },
                { text: this.r('FLTL_00499', 'Cancel') }
            ]
        });
        popup.create();
        popup.rect = { width: 600 };
        const mask = await popup.show();
        mask.style.zIndex = option.zIndex ?? 999;
        if (typeof option.requestWorkOrderParams === 'function') {
            popup.loading = true;
            const data = await option.requestWorkOrderParams()
            dropAssetStatus.source = data.AssetAvailabilities;
            if (!isNaN(data.AssetId) && data.AssetId > 0 && typeof option.requestAssetInfo === 'function') {
                const it = await option.requestAssetInfo(data.AssetId);
                if (it != null) {
                    if (it.OnRoad) {
                        inputOdometer.value = it.Odometer;
                        dropOdometerUnit.select(getOdometerUnit(it.OdometerUOM));
                    } else {
                        inputHours.value = it.EngineHours;
                    }
                    this._var.asset = it;
                    // if (typeof this.onAssetSelected === 'function') {
                    //     this.onAssetSelected(it);
                    // }
                    this._var.container.querySelector('.wo-asset-name').innerText = it.DisplayName;
                    // get assigned to
                    if (typeof option.requestAssignedTo === 'function') {
                        const data = await option.requestAssignedTo(it.Id, dropLocation.selected?.ID ?? -1, dropDepartment.selected?.Id ?? -1)
                        dropAssignedTo.source = [{ IID: '', DisplayName: '' }, ...data];
                        // dropStatus.onSelected(dropStatus.selected);
                    }
                    dropAssetStatus.select(it.CustomStatus);
                }
            }
            popup.loading = false;

            dropWorkOrderType.source = data.OrderTypes;
            dropAdvisor.source = [{ Key: '', Value: '' }, ...data.Advisors];
            dropLocation.source = [{ ID: -1, Name: '' }, ...data.Locations];
            dropDepartment.source = [{ Id: -1, Name: '' }, ...data.Departments];

            this._var.params = data;
            this.filterStatuses();
            //dropStatus.source = data.Statuses;
            const defaultStatus = dropStatus.source.find(s => s.DefaultOnOpen);
            if (defaultStatus != null) {
                dropStatus.select(defaultStatus.Id);
            }
        }
        textComplaint.focus();
        return mask;
    }

    filterStatuses() {
        const wotype = this._var.el.dropWorkOrderType.selected?.Key;

        let locs = [];
        const loc = this._var.el.dropLocation.selected?.ID;
        if (loc > 0)
            locs.push(loc);
        const subLocs = this._var.params?.Locations.filter(l => l.PId == loc).map(l => l.Id);
        locs = locs.concat(subLocs);

        let depts = [];
        const dept = this._var.el.dropDepartment.selected?.Id;
        if (dept > 0)
            depts.push(dept);
        const subDepts = this._var.params?.Departments.filter(d => d.PId == dept).map(d => d.Id);
        depts = depts.concat(subDepts);

        const workOrderStatus = this._var.params?.Statuses;

        const ss = workOrderStatus.filter((s) => {
            if (s.WorkOrderTypes?.length > 0 && !s.WorkOrderTypes.some(t => t.toLowerCase() == wotype?.toLowerCase()))
                return false;

            if (s.Locations?.length > 0 && !s.Locations.some(l => locs.includes(Number(l)))) {
                return false
            }

            if (s.Departments?.length > 0 && !s.Departments.some(l => depts.includes(Number(l)))) {
                return false
            }
            return true;
        });
        this._var.el.dropStatus.source = ss;
    }
}