import { Grid, GridColumn, createElement, setTooltip, createIcon, createCheckbox, createRadiobox, showAlert, showConfirm, Popup } from "../../ui";
import { r as lang, nullOrEmpty, formatUrl, escapeEmoji, isEmail, isPhone } from "../../utility";
import { createBox, appendMedia, fileSupported, insertFile, getMessageSendTo, getMessageStatus, updateCustomerName } from "./lib";
import { Contact, CustomerRecordContact } from "./contact";
import Follower from "./follower";

class NoteCol extends GridColumn {
    static create() {
        const wrapper = createElement('div', 'contact-wrapper',
            createElement('div', 'contact-name'),
            createElement('div', 'contact-note')
        );
        return wrapper;
    }

    static setValue(element, _val, item, _col, grid) {
        const name = element.querySelector('.contact-name');
        name.innerText = item.Name;
        if (name.scrollWidth > name.offsetWidth) {
            setTooltip(name, item.Name, false, grid.element);
        }

        const notes = element.querySelector('.contact-note');
        notes.innerText = item.Notes;
        if (notes.scrollWidth > notes.offsetWidth) {
            setTooltip(notes, item.Notes, false, grid.element);
        }
    }
}

let r = lang;

export default class CustomerCommunication {
    _var = {
        data: {}
    };

    constructor(opt) {
        this._var.option = opt ?? {};
        const getText = opt?.getText;
        if (typeof getText === 'function') {
            r = getText;
        }
    }

    get _autoUpdates() { return this._var.container.querySelector('.check-auto-update>input') }
    get autoUpdatesEnabled() { return this._autoUpdates?.disabled !== true }
    set autoUpdatesEnabled(flag) {
        const element = this._autoUpdates;
        if (element == null) {
            return;
        }
        if (flag === false) {
            element.disabled = true;
            element.parentElement?.classList?.add('disabled');
        } else {
            element.disabled = false;
            element.parentElement?.classList?.remove('disabled');
        }
    }
    get autoUpdates() { return this._autoUpdates?.checked }
    set autoUpdates(flag) {
        const element = this._autoUpdates;
        if (element == null) {
            return;
        }
        element.checked = flag;
        element.dispatchEvent(new Event('change'));
    }

    get _statusLink() { return this._var.container.querySelector('.check-status-link>input') }
    get statusLinkEnabled() { return this._statusLink?.disabled !== true }
    set statusLinkEnabled(flag) {
        const element = this._statusLink;
        if (element == null) {
            return;
        }
        if (flag === false) {
            element.disabled = true;
            element.parentElement?.classList?.add('disabled');
        } else {
            element.disabled = false;
            element.parentElement?.classList?.remove('disabled');
        }
    }
    get statusLink() { return this._statusLink?.checked }
    set statusLink(flag) {
        const element = this._statusLink;
        if (element == null) {
            return;
        }
        element.checked = flag;
        element.dispatchEvent(new Event('change'));
    }

    /**
     * @param {boolean} flag
     */
    set loading(flag) {
        if (this._var.container == null) {
            return;
        }
        this._var.enter.disabled = flag;
        this._var.container.querySelector('.customer-name>.ui-input').disabled = flag;
        this._var.container.querySelector('.button-send-message').disabled = flag;
        this._var.container.querySelector('.button-edit-contacts').disabled = flag;
        this._var.container.querySelector('.button-edit-followers').disabled = flag;
    }

    get text() { return this._var.enter?.value }
    set text(s) {
        const element = this._var.enter;
        if (element != null) {
            element.value = s
            s = String(nullOrEmpty(s) ? 0 : val.length) + '/' + String(this._var.option.maxLength);
            this._var.container.querySelector('.message-bar .prompt-count').innerText = s;
        }
    }

    get file() { return this._var.file || this._var.fileControl?.files?.[0] }
    set file(f) {
        this._var.fileControl?.remove();
        const label = this._var.container.querySelector('.file-selector>.selector-name');
        if (f == null) {
            this._var.fileControl = null;
            this._var.file = null;
            if (label != null) {
                label.style.display = 'none';
                label.innerText = '';
                label.querySelector('.ui-tooltip-wrapper')?.remove();
            }
        } else {
            if (f instanceof HTMLInputElement) {
                this._var.fileControl = f;
                this._var.file = f.files[0];
                const link = this._var.container.querySelector('.file-selector>.selector-link');
                if (link != null) {
                    link.appendChild(f);
                }
            } else {
                this._var.fileControl = null;
                this._var.file = f;
            }
            if (label != null) {
                label.style.display = '';
                label.innerText = f.name;
                setTooltip(label, f.name);
            }
        }
    }

    get customerName() { return this._var.container.querySelector('.customer-name>.ui-input')?.value }
    set customerName(name) {
        const element = this._var.container.querySelector('.customer-name>.ui-input');
        if (element == null) {
            return;
        }
        element.value = name;
    }

    get contacts() {
        return [...this._var.contacts.children].filter(el => {
            return el.querySelector('span').dataset.notsend == "false";
        }).map(el => {
            const span = el.querySelector('span');
            return { 'Key': span.dataset.to, 'Value': span.dataset.name };
        });
    }
    set contacts(contacts) {
        this.setData('contacts', contacts);
        this._var.contacts.replaceChildren();
        if (contacts?.length > 0) {
            var cs = contacts.sort(function (a, b) {
                if (a.Name == b.Name) {
                    return 0;
                }
                return a.Name > b.Name ? 1 : -1;
            });
            const messages = this._var.data.messages;
            if (this._var.contactsUpdated !== true && messages?.length > 0) {
                updateCustomerName(messages, contacts);
                this._var.contactsUpdated = true;
            }
            for (let c of cs) {
                //if (c.OptOut || c.OptOut_BC || c.selected === false) {
                //    continue;
                //}
                const mp = String(c.MobilePhoneDisplayText).trim();
                const email = String(c.Email).trim();
                const pref = String(c.ContactPreference);
                if ((pref !== '1') && !isPhone(mp) ||
                    pref === '1' && !isEmail(email)) {
                    continue;
                }
                const to = pref === '1' ? email : mp;
                let icon;
                let method;
                let tipstr;
                if (c.OptOut || c.OptOut_BC || c.selected === false) {
                    icon = 'times';
                    tipstr = r('P_CU_OPTEDOUT_PROMPT', 'User has opted out of messages');
                }
                else {
                    switch (pref) {
                        case '0':
                            if (c.MobilePhoneStatus !== 0) {
                                icon = 'times';
                                if (c.MobilePhoneStatus === 412) {
                                    // landline
                                    tipstr = r('P_CU_LANDLINE', 'Landline');
                                }
                            } else {
                                icon = 'comment-lines';
                            }
                            method = r('P_CU_TEXTSTO_COLON', 'Texts to:');
                            break;
                        case '2':
                            icon = 'phone';
                            tipstr = r('P_CU_NOMESSAGE', 'No Messages Sent');
                            break;
                        default:
                            icon = 'envelope';
                            method = r('P_CU_EMAILSTO_COLON', 'Emails to:');
                            break;
                    }
                }
                const span = createElement('span', span => {
                    span.dataset.to = to;
                    span.dataset.name = c.Name;
                    span.dataset.notsend = c.OptOut || c.OptOut_BC || c.selected === false;
                    span.innerText = c.Name;
                });
                const item = createElement('div', 'contact-item',
                    createIcon('fa-light', icon, { 'fill': (c.OptOut || c.OptOut_BC || c.selected === false) ? 'red' : '' }),
                    span
                );
                this._var.contacts.appendChild(item);
                let tip = tipstr || `${method} ${to}`;
                if (span.scrollWidth > span.offsetWidth) {
                    tip = r('P_WO_NAME_COLON', 'Name:') + ` ${c.Name}\n${tip}`;
                }
                setTooltip(span, tip);
            }
            this._var.message.scrollTop = this._var.message.scrollHeight
        }
    }

    /**
     * @param {boolean} flag
     */
    set readonly(flag) {
        this._var.option.readonly = flag;
        if (this._var.container == null) {
            return;
        }
        const link = this._var.container.querySelector('.check-status-link');
        if (flag === true) {
            link.classList.add('disabled');
        } else {
            link.classList.remove('disabled');
        }
        link.querySelector('input').disabled = flag;
        const display = flag === true ? 'none' : '';
        this._var.container.querySelector('.button-edit-contacts').style.display = display;
        this._var.container.querySelector('.button-edit-followers').style.display = display;
        // this._var.enter.disabled = flag === true;
        this._var.container.querySelector('.message-bar').style.display = display;
        // this._var.container.querySelector('.button-send-message').style.display = display;
    }

    /**
     * @param {boolean} flag
     */
    set recordReadonly(flag) {
        this._var.option.recordReadonly = flag;
        if (this._var.container == null) {
            return;
        }
        this._var.container.querySelector('.button-edit-contacts').style.display = flag === true ? 'none' : '';
        this._var.container.querySelector('.button-edit-followers').style.display = flag === true ? 'none' : '';
    }

    /**
     * @param {String} name
     */
    set companyName(name) {
        this._var.option.companyName = name;
        const div = this._var.container.querySelector('.title-company');
        if (nullOrEmpty(name)) {
            div.style.display = 'none';
        } else {
            div.innerText = name;
            div.style.display = '';
        }
    }
    /**
     * @param {String} code
     */
    set companyCode(code) {
        const option = this._var.option;
        option.companyCode = code;
        const div = this._var.container.querySelector('.title-company');
        if (nullOrEmpty(option.companyName)) {
            div.style.display = 'none';
        } else {
            div.innerText = option.companyName;
            if (!nullOrEmpty(code))
                div.innerText = option.companyName + "/" + code;
            div.style.display = '';
        }
    }

    get followers() {
        return [...this._var.followers.children].map(el => {
            const span = el.querySelector('span');
            return { 'Email': span.dataset.email, 'MobilePhone': span.dataset.mp, 'Value': span.dataset.name };
        });
    }
    set followers(followers) {
        this._var.data.followers = followers;
        this._var.followers.replaceChildren();
        if (followers?.length > 0) {
            this._var.container.querySelector('.follower-bar').style.display = '';
            setTooltip(this._var.buttonFollower, r('P_CU_EDITFOLLOWERS', 'Edit Followers'));
            this._var.container.querySelector('.follower-bar>.bar-list').appendChild(this._var.buttonFollower);
            for (let f of followers) {
                if (f.OptOut) {
                    continue;
                }
                const mp = String(f.MobilePhone).trim();
                const mpDisplay = String(f.MobilePhoneDisplayText).trim();
                const email = String(f.Email).trim();
                const tips = [];
                if (f.SendEmail) {
                    tips.push(r('P_CU_EMAILSTO_COLON', 'Emails to:') + ` ${email}`);
                }
                if (f.SendText) {
                    tips.push(r('P_CU_TEXTSTO_COLON', 'Texts to:') + ` ${mpDisplay}`);
                }
                let icon;
                if (f.SendText && f.SendEmail) {
                    icon = 'at';
                } else {
                    icon = f.SendText ? 'comment-lines' : 'envelope';
                }
                const span = createElement('span', span => {
                    if (f.SendEmail) {
                        span.dataset.email = email;
                    }
                    if (f.SendText) {
                        span.dataset.mp = mp;
                    }
                    span.dataset.name = f.Name;
                    span.innerText = f.Name;
                });
                const item = createElement('div', 'contact-item',
                    createIcon('fa-light', icon),
                    span
                );
                this._var.followers.appendChild(item);
                if (span.scrollWidth > span.offsetWidth) {
                    tips.splice(0, 0, r('P_WO_NAME_COLON', 'Name:') + ` ${c.Name}`);
                }
                setTooltip(span, tips.join('\n'));
            }
        } else {
            this._var.container.querySelector('.follower-bar').style.display = 'none';
            setTooltip(this._var.buttonFollower, r('P_CR_ADDFOLLOWERS', 'Add Followers'));
            this._var.container.querySelector('.button-edit-contacts').insertAdjacentElement('beforebegin', this._var.buttonFollower)
        }
        this._var.message.scrollTop = this._var.message.scrollHeight
    }

    setData(key, data) {
        this._var.data[key] = data;
    }

    create() {
        const option = this._var.option;
        const readonly = option.readonly;
        // functions
        const checkAutoUpdate = createCheckbox({
            className: 'check-auto-update',
            checked: option.autoUpdates,
            checkedNode: createIcon('fa-regular', 'redo-alt'),
            uncheckedNode: createIcon('fa-regular', 'ban'),
            onchange: function () {
                setTooltip(checkAutoUpdate, this.checked ?
                    r('P_CU_AUTOUPDATESENABLED', 'Auto Updates Enabled') :
                    r('P_CU_AUTOUPDATESDISABLED', 'Auto Updates Disabled'));
            }
        });
        if (option.autoUpdatesVisible === false) {
            checkAutoUpdate.style.display = 'none';
        }
        const This = this;
        const checkLink = createCheckbox({
            className: 'check-status-link',
            enabled: !readonly,
            checked: option.statusLink,
            checkedNode: createIcon('fa-regular', 'link'),
            uncheckedNode: createIcon('fa-regular', 'unlink'),
            onchange: function () {
                setTooltip(checkLink, this.checked ?
                    r('P_WO_STATUSLINKINCLUDED', 'Status Link Included') :
                    r('P_WO_STATUSLINKEXCLUDED', 'Status Link Excluded'));
                if (typeof option.onStatusLinkChanged === 'function') {
                    option.onStatusLinkChanged.call(This, this.checked);
                }
            }
        });
        if (option.statusLinkVisible === false) {
            checkLink.style.display = 'none';
        }
        const container = createBox(
            createElement('div', null,
                createElement('div', div => {
                    div.className = 'title-module';
                    div.innerText = option.title ?? r('P_WO_CUSTOMERCOMMUNICATION', 'Customer Communication');
                }),
                createElement('div', div => {
                    div.className = 'title-company';
                    if (nullOrEmpty(option.companyName)) {
                        div.style.display = 'none';
                    } else {
                        if (nullOrEmpty(option.companyCode)) {
                            div.innerText = option.companyName;
                        } else {
                            div.innerText = option.companyName + "/" + option.companyCode;
                        }
                    }
                })
            ),
            [
                setTooltip(checkAutoUpdate, r('P_CU_AUTOUPDATESENABLED', 'Auto Updates Enabled')),
                setTooltip(checkLink, r('P_WO_STATUSLINKEXCLUDED', 'Status Link Excluded'))
            ]
        );
        // contacts
        this._var.contacts = this._createContacts(container, option);
        // followers
        this._var.followers = this._createFollowers(container, option);
        // enter box
        const enter = createElement('textarea', 'ui-text');
        enter.placeholder = r('P_CU_ENTERMESSAGEHERE', 'Enter Message Here');
        option.maxLength ??= 3000;
        enter.maxLength = option.maxLength;
        // if (readonly === true) {
        //     enter.disabled = true;
        // }
        enter.addEventListener('input', () => {
            const val = this.text;
            const s = String(nullOrEmpty(val) ? 0 : val.length) + '/' + String(option.maxLength);
            this._var.container.querySelector('.message-bar .prompt-count').innerText = s;
        });
        enter.addEventListener('paste', e => {
            if (option.customerNameVisible === true) {
                return;
            }
            const items = e.clipboardData.items;
            if (items?.length > 0) {
                const item = items[0];
                const entry = item.webkitGetAsEntry();
                if (item.kind === 'file' && (entry == null || entry.isFile)) {
                    const file = item.getAsFile();
                    if (file != null) {
                        e.preventDefault();
                        this.file = insertFile(container, file, r);
                    }
                }
            }
            // const file = e.clipboardData.files[0];
            // if (file != null) {
            //     e.preventDefault();
            //     this.file = insertFile(container, file, r);
            // }
        });
        this._var.enter = enter;
        container.appendChild(
            createElement('div', div => {
                div.className = 'message-bar';
                if (readonly === true) {
                    div.style.display = 'none';
                }
                div.addEventListener('dragover', e => {
                    if (option.readonly !== true) {
                        const item = e.dataTransfer.items[0];
                        if (item?.kind === 'file') {
                            e.preventDefault();
                            if (item.type.length > 0 && fileSupported.indexOf(item.type) < 0) {
                                e.dataTransfer.dropEffect = 'none';
                            } else {
                                e.dataTransfer.dropEffect = 'link';
                            }
                        }
                    }
                });
                div.addEventListener('drop', e => {
                    if (option.readonly !== true) {
                        const file = e.dataTransfer.files[0];
                        if (file != null) {
                            e.preventDefault();
                            this.file = insertFile(container, file, r);
                        }
                    }
                });
            },
                enter,
                createElement('div', div => div.style.textAlign = 'right',
                    createElement('div', 'customer-left',
                        createElement('div', div => {
                            div.className = 'customer-name';
                            if (option.customerNameVisible !== true) {
                                div.style.display = 'none';
                            }
                        },
                            createElement('span', span => span.innerText = r('P_WO_NAME_COLON', 'Name:')),
                            createElement('input', input => {
                                input.type = 'text';
                                input.className = 'ui-input';
                            })
                        ),
                        createElement('div', 'file-selector',
                            createElement('div', div => {
                                div.className = 'selector-link';
                                div.addEventListener('click', () => {
                                    this._var.fileControl?.remove();
                                    const file = createElement('input', input => {
                                        input.type = 'file';
                                        input.accept = fileSupported.join(',');
                                        input.addEventListener('change', () => {
                                            const file = insertFile(container, input.files?.[0], r);
                                            if (file != null) {
                                                this.file = file;
                                            }
                                        });
                                    });
                                    div.appendChild(this._var.fileControl = file);
                                    file.dispatchEvent(new MouseEvent('click'));
                                });
                            },
                                createIcon('fa-regular', 'link')
                            ),
                            createElement('span', span => {
                                span.className = 'selector-name';
                                span.style.display = 'none';
                            }),
                            createElement('layer', layer => {
                                layer.appendChild(createIcon('fa-regular', 'times'));
                                layer.addEventListener('click', () => this.file = null);
                            })
                        )
                    ),
                    createElement('div', 'prompt-count'),
                    createElement('button', button => {
                        button.className = 'roundbtn button-send-message';
                        button.style.backgroundColor = 'rgb(19, 150, 204)';
                        // if (readonly === true) {
                        //     button.style.display = 'none';
                        // }
                        button.appendChild(createIcon('fa-solid', 'paper-plane'));
                        setTooltip(button, r('P_M3_SENDMESSAGE', 'Send Message'));
                        button.addEventListener('click', () => {
                            const val = this.text;
                            if (nullOrEmpty(val?.trim())) {
                                const p = showAlert(r('P_WO_ERROR', 'Error'), r('P_WO_PLEASEINPUTTHEMESSAGE', 'Please input the message.'), 'warn');
                                if (typeof option.onMasking === 'function') {
                                    option.onMasking(true);
                                    p.then(() => option.onMasking(false));
                                }
                                return;
                            }
                            if (typeof option.onAddMessage === 'function') {
                                this.loading = true;
                                option.onAddMessage(this.text, this.file);
                            }
                        })
                    })
                )
            )
        );

        const message = createElement('div', 'list-bar');
        this._var.message = message;
        container.appendChild(message);
        return this._var.container = container;
    }

    _createContacts(container, option) {
        const readonly = option.readonly;
        const recordReadonly = option.recordReadonly;
        const contacts = createElement('div', 'bar-list-container');
        container.append(
            createElement('div', 'contact-bar',
                createElement('div', 'bar-icon',
                    createIcon('fa-solid', 'user-circle', {
                        'fill': 'lightgray'
                    })
                ),
                createElement('div', 'bar-list',
                    contacts,
                    createElement('button', button => {
                        button.className = 'roundbtn button-edit-contacts';
                        button.style.backgroundColor = 'rgb(1, 199, 172)';
                        if (readonly === true) {
                            button.style.display = 'none';
                        }
                        button.appendChild(createIcon('fa-solid', 'user-edit'));
                        setTooltip(button, r('P_CU_EDITCONTACTS', 'Edit Contacts'));
                        button.addEventListener('click', () => {
                            const pop = new Popup({
                                onMasking: option.onMasking,
                                title: createElement('div', div => {
                                    div.style.display = 'flex';
                                    div.style.alignItems = 'center';
                                    div.style.padding = '10px 0 6px 12px';
                                    div.append(
                                        createElement('div', div => {
                                            div.className = 'ui-popup-move';
                                            div.style.flex = '1 1 auto';
                                        },
                                            createElement('div', div => div.innerText = r('P_CU_EDITCONTACTS', 'Edit Contacts')),
                                            createElement('div', div => {
                                                div.className = 'title-company';
                                                div.style.maxWidth = '540px';
                                                if (nullOrEmpty(option.companyName)) {
                                                    div.style.display = 'none';
                                                } else {
                                                    if (nullOrEmpty(option.companyCode)) {
                                                        div.innerText = option.companyName;
                                                    } else {
                                                        div.innerText = option.companyName + "/" + option.companyCode;
                                                    }
                                                }
                                            })
                                        ),
                                        createElement('button', button => {
                                            button.style.flex = '0 0 auto';
                                            button.style.backgroundColor = 'rgb(1, 199, 172)';
                                            button.style.marginRight = '10px';
                                            button.className = 'roundbtn button-from-customer-record';
                                            if (recordReadonly) {
                                                button.style.display = 'none';
                                            }
                                            button.appendChild(createIcon('fa-solid', 'handshake', {
                                                width: '16px',
                                                height: '16px'
                                            }));
                                            button.addEventListener('click', () => {
                                                const sel = new CustomerRecordContact({
                                                    getText: option.getText,
                                                    // onMasking: option.onMasking,
                                                    contacts: [],
                                                    onOk: list => {
                                                        if (typeof option.onSelectCRContacts === 'function') {
                                                            list?.map(c => {
                                                                delete c.selected;
                                                                return c;
                                                            });
                                                            const result = option.onSelectCRContacts(list);
                                                        }
                                                        const r = this._var.data.contacts;
                                                        this._var.gridContact.source = r.filter(c => c.Id >= 0).map(c => {
                                                            if (c.OptOut || c.OptOut_BC) {
                                                                return c;
                                                            }
                                                            if (typeof c.selected === 'undefined') {
                                                                c.selected = true;
                                                            }
                                                            return c;
                                                        });
                                                        this._var.gridWo.source = r.filter(c => c.Id < 0).map(c => {
                                                            if (c.OptOut || c.OptOut_BC) {
                                                                return c;
                                                            }
                                                            if (typeof c.selected === 'undefined') {
                                                                c.selected = true;
                                                            }
                                                            return c;
                                                        });
                                                    }
                                                });
                                                var title = r('P_CU_SELECTFROMCUSTOMERRECORD', 'Select from Customer Record');
                                                sel.show(title, container);

                                                if (typeof option.onOpenSelectCRContacts === 'function') {
                                                    const result = option.onOpenSelectCRContacts();
                                                    if (typeof result?.then === 'function') {
                                                        return result.then(r => {
                                                            r.map(c => {
                                                                for (let cc of this._var.data.contacts) {
                                                                    if (c.Id === cc.Id) {
                                                                        c.selected = true;
                                                                        break;
                                                                    }
                                                                }
                                                                if (typeof c.selected === 'undefined') {
                                                                    c.selected = false;
                                                                }
                                                                return c;
                                                            });
                                                            this._var.data.contacts.filter(c => c.Id >= 0).map(c => {
                                                                if (c.OptOut || c.OptOut_BC) {
                                                                    return c;
                                                                }
                                                                if (typeof c.selected === 'undefined') {
                                                                    c.selected = true;
                                                                }
                                                                return c;
                                                            });

                                                            sel.source = r;
                                                            return r;
                                                        });
                                                    }
                                                    return false;
                                                }
                                            });
                                            setTooltip(button, r('P_CU_SELECTFROMCUSTOMERRECORD', 'Select from Customer Record'))
                                        }),
                                        createElement('button', button => {
                                            button.style.flex = '0 0 auto';
                                            button.style.backgroundColor = 'rgb(1, 199, 172)';
                                            button.style.marginRight = '10px';
                                            button.className = 'roundbtn button-add-contact';
                                            if (recordReadonly) {
                                                button.style.display = 'none';
                                            }
                                            button.appendChild(createIcon('fa-solid', 'user-plus', {
                                                width: '16px',
                                                height: '16px'
                                            }));
                                            button.addEventListener('click', () => {
                                                const add = new Contact({
                                                    getText: option.getText,
                                                    // onMasking: option.onMasking,
                                                    company: !nullOrEmpty(option.companyName),
                                                    onSave: item => {
                                                        const exists = this._var.gridContact.source.some(s => s.Name === item.Name && s.MobilePhone === item.MobilePhone);
                                                        if (exists) {
                                                            showAlert(r('P_CR_ADDCONTACT', 'Add Contact'), r('P_WO_CONTACTNAMEANDMOBILEUNIQUECOMBINATION', 'Contact name and contact mobile must be a unique combination.'), 'warn');
                                                            return false;
                                                        }
                                                        if (typeof option.onSave === 'function') {
                                                            const result = option.onSave(item, true);
                                                            if (typeof result?.then === 'function') {
                                                                return result.then(r => {
                                                                    this._var.gridContact.source = r.filter(c => c.Id >= 0).map(c => {
                                                                        if (c.OptOut || c.OptOut_BC) {
                                                                            return c;
                                                                        }
                                                                        if (typeof c.selected === 'undefined') {
                                                                            c.selected = true;
                                                                        }
                                                                        return c;
                                                                    });
                                                                    this._var.gridWo.source = r.filter(c => c.Id < 0).map(c => {
                                                                        if (c.OptOut || c.OptOut_BC) {
                                                                            return c;
                                                                        }
                                                                        if (typeof c.selected === 'undefined') {
                                                                            c.selected = true;
                                                                        }
                                                                        return c;
                                                                    });
                                                                    return r;
                                                                });
                                                            }
                                                            return false;
                                                        }
                                                    }
                                                });
                                                add.show(container);
                                            });
                                            setTooltip(button, r('P_CR_ADDCONTACT', 'Add Contact'))
                                        })
                                    )
                                }),
                                content: createElement('div', null,
                                    createElement('div', div => {
                                        if (nullOrEmpty(option.companyName)) {
                                            div.style.display = 'none';
                                        }
                                        div.style.fontWeight = 'bold';
                                        div.innerText = r('P_CU_CONTACTSFROMCUSTOMERRECORD', 'Contacts from Customer Record');
                                    }),
                                    createElement('div', div => {
                                        if (nullOrEmpty(option.companyName)) {
                                            div.style.display = 'none';
                                        }
                                        div.className = 'contacts-record';
                                        div.style.maxHeight = '200px';
                                        div.style.width = '675px';
                                        div.style.overflow = 'auto';
                                    }),
                                    createElement('div', div => {
                                        div.style.fontWeight = 'bold';
                                        div.innerText = r('P_CU_CONTACTSNOTCUSTOMERRECORD', 'Contacts not on Customer Record');
                                    }),
                                    createElement('div', div => {
                                        div.className = 'contacts-wo';
                                        div.style.maxHeight = '200px';
                                        div.style.width = '675px';
                                        div.style.overflow = 'auto';
                                    })
                                )
                            });
                            pop.show(container).then(() => {
                                const selectedCol = This => {
                                    return {
                                        key: 'selected',
                                        type: Grid.ColumnTypes.Checkbox,
                                        width: 50,
                                        enabled: item => !item.OptOut && !item.OptOut_BC,
                                        onChanged: function () {
                                            if (typeof option.onChanged === 'function') {
                                                option.onChanged([...This._var.gridContact.source, ...This._var.gridWo.source]);
                                            }
                                        },
                                        tooltip: item => item.selected ? r('P_CU_OPTEDIN', 'Opted In') : r('P_CU_OPTEDOUT', 'Opted Out')
                                    }
                                };
                                const iconCol = {
                                    key: 'type',
                                    type: Grid.ColumnTypes.Icon,
                                    width: 50,
                                    filter: c => {
                                        switch (String(c.ContactPreference)) {
                                            case '0': return 'comment-lines';
                                            case '2': return 'mobile';
                                            default: return 'envelope';
                                        }
                                    },
                                    className: 'icon-contact-type',
                                    iconType: 'fa-light'
                                };
                                const nameCol = { key: 'Name', type: NoteCol, width: 160 };
                                const buttonCol = {
                                    type: Grid.ColumnTypes.Icon,
                                    width: 40,
                                    visible: !recordReadonly,
                                    align: 'center',
                                    iconType: 'fa-light'
                                };
                                const createEditCol = (This) => {
                                    return {
                                        key: 'edit',
                                        ...buttonCol,
                                        text: 'edit',
                                        tooltip: r('P_WO_EDIT', 'Edit'),
                                        events: {
                                            onclick: function () {
                                                const edit = new Contact({
                                                    getText: option.getText,
                                                    // onMasking: option.onMasking,
                                                    contact: this,
                                                    company: !nullOrEmpty(option.companyName),
                                                    onSave: (item, _op) => {
                                                        const exists =
                                                            This._var.gridContact.source.some(s => s !== this && s.Name === item.Name && s.MobilePhone === item.MobilePhone) ||
                                                            This._var.gridWo.source.some(s => s !== this && s.Name === item.Name && s.MobilePhone === item.MobilePhone);
                                                        if (exists) {
                                                            showAlert(r('P_CR_EDITCONTACT', 'Edit Contact'), r('P_WO_CONTACTNAMEANDMOBILEUNIQUECOMBINATION', 'Contact name and contact mobile must be a unique combination.'), 'warn');
                                                            return false;
                                                        }
                                                        if (typeof option.onSave === 'function') {
                                                            const result = option.onSave(item);
                                                            if (typeof result?.then === 'function') {
                                                                return result.then(r => {
                                                                    This._var.gridContact.source = r.filter(c => c.Id >= 0).map(c => {
                                                                        if (c.OptOut || c.OptOut_BC) {
                                                                            return c;
                                                                        }
                                                                        if (typeof c.selected === 'undefined') {
                                                                            c.selected = true;
                                                                        }
                                                                        return c;
                                                                    });
                                                                    This._var.gridWo.source = r.filter(c => c.Id < 0).map(c => {
                                                                        if (c.OptOut || c.OptOut_BC) {
                                                                            return c;
                                                                        }
                                                                        if (typeof c.selected === 'undefined') {
                                                                            c.selected = true;
                                                                        }
                                                                        return c;
                                                                    });
                                                                    return r;
                                                                });
                                                            }
                                                            return false;
                                                        }
                                                    }
                                                });
                                                edit.show(container);
                                            }
                                        }
                                    }
                                };
                                // contacts from customer record
                                const grid = new Grid();
                                grid.height = 0;
                                grid.allowHtml = true;
                                grid.headerVisible = false;
                                grid.columns = [
                                    selectedCol(this),
                                    iconCol,
                                    nameCol,
                                    { key: 'Email', width: 180 },
                                    { key: 'MobilePhoneDisplayText', width: 130 },
                                    createEditCol(this),
                                    {
                                        key: 'delete',
                                        ...buttonCol,
                                        text: 'times',
                                        tooltip: r('P_WO_DELETE', 'Delete'),
                                        events: {
                                            onclick: function () {
                                                showConfirm(
                                                    r('P_CU_REMOVECONTACT', 'Remove Contact'),
                                                    createElement('div', null,
                                                        createElement('div', div => {
                                                            div.style.paddingLeft = '16px';
                                                            div.innerText = r('P_CU_REMOVEFROM', 'Remove {name} from').replace('{name}', this.Name);
                                                        }),
                                                        createElement('div', div => {
                                                            div.style.display = 'flex';
                                                            div.style.justifyContent = 'center';
                                                            div.style.marginTop = '10px';
                                                        },
                                                            createRadiobox({
                                                                name: 'remove-type',
                                                                label: r('P_CUSTOMERRECORD', 'Customer Record'),
                                                                checked: true,
                                                                className: 'radio-customer-record'
                                                            }),
                                                            createRadiobox({
                                                                name: 'remove-type',
                                                                label: r('P_WORKORDER', 'Work Order')
                                                            })
                                                        )
                                                    ),
                                                    [
                                                        { key: 'ok', text: r('P_WO_OK', 'OK') },
                                                        { key: 'cancel', text: r('P_WO_CANCEL', 'Cancel') }
                                                    ]
                                                ).then(result => {
                                                    if (result?.key === 'ok') {
                                                        const isRecord = result.popup.container.querySelector('.radio-customer-record>input').checked;
                                                        if (typeof option.onDelete === 'function') {
                                                            option.onDelete(result.key, this, isRecord);
                                                        }
                                                        const index = grid.source.indexOf(this);
                                                        if (index >= 0) {
                                                            const source = grid.source;
                                                            source.splice(index, 1);
                                                            grid.extraRows = source.filter(c => !nullOrEmpty(c.Notes)).length;
                                                            grid.source = source;
                                                        }
                                                    }
                                                });
                                            }
                                        }
                                    }
                                ];
                                grid.init(pop.container.querySelector('.contacts-record'));
                                const customerRecords = this._var.data.contacts.filter(c => c.Id >= 0).map(c => {
                                    if (c.OptOut || c.OptOut_BC) {
                                        return c;
                                    }
                                    if (typeof c.selected === 'undefined') {
                                        c.selected = true;
                                    }
                                    return c;
                                });
                                grid.extraRows = customerRecords.filter(c => !nullOrEmpty(c.Notes)).length;
                                grid.source = customerRecords;
                                grid.selectedRowChanged = index => {
                                    if (index >= 0 && this._var.gridWo.selectedIndexes?.length > 0) {
                                        this._var.gridWo.selectedIndexes = [];
                                    }
                                };
                                this._var.gridContact = grid;

                                // contacts from work order only
                                const gridWo = new Grid();
                                gridWo.height = 0;
                                gridWo.allowHtml = true;
                                gridWo.headerVisible = false;
                                gridWo.columns = [
                                    selectedCol(this),
                                    iconCol,
                                    nameCol,
                                    { key: 'Email', width: 180 },
                                    { key: 'MobilePhoneDisplayText', width: 130 },
                                    createEditCol(this),
                                    {
                                        key: 'delete',
                                        ...buttonCol,
                                        text: 'times',
                                        tooltip: r('P_WO_DELETE', 'Delete'),
                                        events: {
                                            onclick: function () {
                                                showConfirm(r('P_CU_REMOVECONTACT', 'Remove Contact'), r('P_CU_REMOVEFROMWORKORDER', 'You are removing {name} from work order.\n\nDo you want to Continue?').replace('{name}', this.Name), [
                                                    { key: 'continue', text: r('P_JS_CONTINUE', 'Continue') },
                                                    { key: 'cancel', text: r('P_WO_CANCEL', 'Cancel') }
                                                ]).then(result => {
                                                    if (result?.key === 'continue') {
                                                        if (typeof option.onDelete === 'function') {
                                                            option.onDelete(result.key, this);
                                                        }
                                                        const index = gridWo.source.indexOf(this);
                                                        if (index >= 0) {
                                                            const source = gridWo.source;
                                                            source.splice(index, 1);
                                                            gridWo.extraRows = source.filter(c => !nullOrEmpty(c.Notes)).length;
                                                            gridWo.source = source;
                                                        }
                                                    }
                                                });
                                            }
                                        }
                                    }
                                ];
                                gridWo.init(pop.container.querySelector('.contacts-wo'));
                                const workOrderOnly = this._var.data.contacts.filter(c => c.Id < 0).map(c => {
                                    if (c.OptOut || c.OptOut_BC) {
                                        return c;
                                    }
                                    if (typeof c.selected === 'undefined') {
                                        c.selected = true;
                                    }
                                    return c;
                                });
                                gridWo.extraRows = workOrderOnly.filter(c => !nullOrEmpty(c.Notes)).length;
                                gridWo.source = workOrderOnly;
                                gridWo.selectedRowChanged = index => {
                                    if (index >= 0 && this._var.gridContact.selectedIndexes?.length > 0) {
                                        this._var.gridContact.selectedIndexes = [];
                                    }
                                };
                                this._var.gridWo = gridWo;
                            });
                        });
                    })
                ),
                createElement('div', div => {
                    div.className = 'bar-info';
                    div.innerText = r('P_CR_CONTACTINFORMATION', 'Contact Information');
                }),
                createElement('div', div => {
                    if (option.contactCollapserVisible === false) {
                        div.style.display = 'none';
                        return;
                    }
                    if (option.contactCollapsed) {
                        container.classList.add('collapsed');
                        div.className = 'bar-collapser collapsed';
                    } else {
                        div.className = 'bar-collapser';
                    }
                    div.addEventListener('click', () => {
                        const collapsed = div.classList.contains('collapsed');
                        if (collapsed) {
                            div.classList.remove('collapsed');
                            container.classList.remove('collapsed');
                        } else {
                            div.classList.add('collapsed');
                            container.classList.add('collapsed');
                        }
                        if (typeof option.onContactCollapsed === 'function') {
                            option.onContactCollapsed.call(this, !collapsed);
                        }
                    });
                    div.append(createElement('span'));
                })
            )
        );
        return contacts;
    }

    _createFollowers(container, option) {
        const readonly = option.readonly;
        const recordReadonly = option.recordReadonly;
        const followers = createElement('div', 'bar-list-container');
        const buttonEditFollower = createElement('button', button => {
            button.className = 'roundbtn button-edit-followers';
            button.style.backgroundColor = 'rgb(48, 107, 255)';
            if (readonly === true || recordReadonly) {
                button.style.display = 'none';
            }
            button.appendChild(createIcon('fa-solid', 'pen'));
            setTooltip(button, r('P_CU_EDITFOLLOWERS', 'Edit Followers'));
            button.addEventListener('click', () => {
                if (typeof option.onInitFollower === 'function') {
                    option.onInitFollower(this._var.data.followers).then(data => {
                        if (typeof data === 'string') {
                            showAlert(r('P_CUSTOMERRECORD', 'Customer Record'), data, 'warn');
                            return;
                        }
                        const add = new Follower({
                            getText: option.getText,
                            onMasking: option.onMasking,
                            followers: data,
                            onOk: list => {
                                if (typeof option.onAddFollower === 'function') {
                                    const result = option.onAddFollower(list);
                                    if (typeof result?.then === 'function') {
                                        return result.then(r => {
                                            // this.followers = r;
                                            return r;
                                        });
                                    }
                                    return false;
                                }
                            }
                        });
                        var title = this._var.data.followers?.length > 0 ? r('P_CU_EDITFOLLOWERS', 'Edit Followers') : r('P_CR_ADDFOLLOWERS', 'Add Followers');
                        add.show(title, container);
                    });
                }
            });
        });
        this._var.buttonFollower = buttonEditFollower;
        container.append(
            createElement('div', div => {
                div.className = 'contact-bar follower-bar';
                div.style.display = 'none';
            },
                setTooltip(createElement('div', 'bar-icon',
                    createIcon('fa-solid', 'user-tag', {
                        'fill': '#fff',
                        'background-color': 'lightgray',
                        'box-sizing': 'border-box',
                        'border-radius': '15px',
                        'padding': '4px'
                    })
                ), r('P_CU_COPIED', 'Copied')),
                createElement('div', 'bar-list',
                    followers,
                    buttonEditFollower
                )
            )
        );
        return followers;
    }

    load(data, contacts, followers) {
        const children = [];
        if (data?.length > 0) {
            contacts ??= this._var.data.contacts;
            followers ??= this._var.data.allfollowers;
            this.setData('messages', data);
            if (this._var.contactsUpdated !== true) {
                const contacts = this._var.data.contacts;
                if (contacts?.length > 0) {
                    updateCustomerName(data, contacts);
                    this._var.contactsUpdated = true;
                }
            }
            for (let comm of data) {
                const div = createElement('div', 'item-div');
                let name;
                if (comm.IsReply && contacts?.length > 0) {
                    const c = isEmail(comm.Sender) ?
                        contacts.find(c => c.Email === comm.Sender) :
                        contacts.find(c => c.MobilePhone === comm.Sender);
                    name = c?.Name;
                }
                name ??= comm.IsReply && String(comm.FormatSender) !== '' ? comm.FormatSender : comm.Sender;
                const sendto = getMessageSendTo(comm, contacts, followers, r)
                div.appendChild(createElement('div', div => {
                    div.className = 'item-poster';
                    div.innerText = name;
                    if (!comm.IsReply && sendto?.length > 0) {
                        setTooltip(div, sendto);
                    }
                }));
                const content = createElement('div', 'item-content');
                const mmsParts = createElement('div', div => div.style.display = 'none');
                content.appendChild(createElement('span', span => {
                    if (/https?:\/\//i.test(comm.Message)) {
                        span.innerHTML = formatUrl(escapeEmoji(comm.Message));
                    } else {
                        span.innerText = escapeEmoji(comm.Message);
                    }
                    span.appendChild(mmsParts);
                }));
                if (comm.MMSParts?.length > 0) {
                    mmsParts.style.display = '';
                    for (let kv of comm.MMSParts) {
                        appendMedia(mmsParts, kv.Key, kv.Value);
                    }
                }
                if (comm.IsReply) {
                    div.classList.add('item-other');
                } else {
                    div.classList.add('item-self');
                    const [status, text, color, tips] = getMessageStatus(comm, r, this._var);
                    if (status !== -100) {
                        if (color != null) {
                            content.style.backgroundColor = color;
                        }
                        const divstatus = createElement('div', div => {
                            div.className = 'item-status';
                            div.innerText = text;
                            if (tips != null) {
                                setTooltip(div, tips);
                            }
                        });
                        content.appendChild(divstatus);
                    }
                }
                div.append(
                    content,
                    createElement('div', div => {
                        div.className = 'item-time';
                        div.innerText = comm.TimeStr;
                    })
                );
                children.push(div);
            }
            children[0].style.marginTop = '0';
        }
        this._var.message.replaceChildren(...children);
        this._var.message.scrollTop = this._var.message.scrollHeight
        // setTimeout(() => this._var.message.scrollTop = this._var.message.scrollHeight, 0);
    }
}