import { Grid, GridColumn, createElement, setTooltip, createIcon, createCheckbox, createRadiobox, showAlert, showConfirm, Popup, requestAnimationFrame } from "../../ui";
import { r as lang, nullOrEmpty, formatUrl, escapeEmoji, isEmail, isPhone } from "../../utility";
import { createBox, appendMedia, fileSupported, insertFile, getMessageSendTo, getMessageStatus, updateCustomerName, createHideMessageTitleButton, createHideMessageCommentTail } 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, it, _col, grid) {
        const item = it.values;
        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;
        } else if (typeof GetTextByKey === 'function') {
            r = GetTextByKey;
        }
    }

    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'));
    }

    /**
     * @param {boolean} flag
     */
    set messageHidden(flag) {
        const el = this._var.container.querySelector('.msgadminsetting');
        if (el == null) {
            return;
        }
        this._var.option.showMessageHidden = flag;
        // TODO: 是否与参数 flag 无关
        el.classList.remove('iconview');
        el.classList.add('iconnotview');
    }

    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) {
                return String(a.Name).localeCompare(String(b.Name));
            });
            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('FLTL_03200', 'User has opted out of messages');
                }
                else {
                    switch (pref) {
                        case '0':
                            if (c.MobilePhoneStatus !== 0) {
                                icon = 'times';
                                if (c.MobilePhoneStatus === 412) {
                                    // landline
                                    tipstr = r('FLTL_01707', 'Landline');
                                }
                            } else {
                                icon = 'comment-lines';
                            }
                            method = r('FLTL_02924', 'Texts to:');
                            break;
                        case '2':
                            icon = 'phone';
                            tipstr = r('FLTL_01991', 'No Messages Sent');
                            break;
                        default:
                            icon = 'envelope';
                            method = r('FLTL_01109', '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('FLTL_01970', '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('.title-company').style.display = display;
        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;
        }
        const display = flag === true ? 'none' : '';
        const companySelector = this._var.container.querySelector('.title-company .title-company-selector');
        if (companySelector != null) {
            companySelector.querySelector('.title-company-selector').style.display = display;
        }
        this._var.container.querySelector('.button-edit-contacts').style.display = display;
        this._var.container.querySelector('.button-edit-followers').style.display = display;
    }

    /**
     * @param {String} name
     */
    set companyName(name) {
        this._var.option.companyName = name;
        this._var.container.querySelector('.button-edit-contacts').style.display =
            this._var.option.recordReadonly && nullOrEmpty(name) ? 'none' : '';
        const div = this._var.container.querySelector('.title-company');
        const companyCode = div.querySelector('.title-company-code');
        if (companyCode != null) {
            if (nullOrEmpty(name)) {
                if (this._var.option.customerReadonly === true) {
                    div.style.display = 'none';
                } else {
                    div.querySelector('.title-company-name').innerText = r('FLTL_01985', 'No Customer Assigned');
                    companyCode.innerText = ' /\n' + r('FLTL_02654', 'Select Customer');
                    companyCode.style.display = '';
                }
            } else {
                div.style.display = '';
                div.querySelector('.title-company-name').innerText = name;
                companyCode.style.display = 'none';
            }
        }
        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');
        const companyCode = div.querySelector('.title-company-code');
        if (companyCode != null) {
            if (nullOrEmpty(option.companyName)) {
                div.querySelector('.title-company-name').innerText = r('FLTL_01985', 'No Customer Assigned');
                companyCode.innerText = ' /\n' + r('FLTL_02654', 'Select Customer');
                companyCode.style.display = '';
            } else {
                div.querySelector('.title-company-name').innerText = option.companyName;
                if (nullOrEmpty(code)) {
                    companyCode.style.display = 'none';
                } else {
                    companyCode.innerText = ' / ' + code;
                    companyCode.style.display = '';
                }
            }
        }
        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('FLTL_01054', '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('FLTL_01109', 'Emails to:') + ` ${email}`);
                }
                if (f.SendText) {
                    tips.push(r('FLTL_02924', '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('FLTL_01970', 'Name:') + ` ${f.Name}`);
                }
                setTooltip(span, tips.join('\n'));
            }
        } else {
            this._var.container.querySelector('.follower-bar').style.display = 'none';
            setTooltip(this._var.buttonFollower, r('FLTL_00116', '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('FLTL_00420', 'Auto Updates Enabled') :
                    r('FLTL_00419', '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('FLTL_02830', 'Status Link Included') :
                    r('FLTL_02829', '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('FLTL_00732', 'Customer Communication');
                },
                    createHideMessageTitleButton(this, 'showMessageHidden')
                ),
                // option.allowCustomer === false ? createElement('div', 'title-company') :
                createElement('div', div => {
                    div.className = 'title-company';
                    // div.style.display = 'none';
                },
                    createElement('span', span => {
                        span.className = 'title-company-name';
                        if (nullOrEmpty(option.companyName)) {
                            span.innerText = r('FLTL_01985', 'No Customer Assigned');
                        } else {
                            span.innerText = option.companyName;
                        }
                    }),
                    createElement('span', span => {
                        span.className = 'title-company-code';
                        if (option.customerReadonly === true) {
                            span.style.display = 'none';
                        } else if (nullOrEmpty(option.companyName)) {
                            span.innerText = ' /\n' + r('FLTL_02654', 'Select Customer');
                        } else if (!nullOrEmpty(option.companyCode)) {
                            span.innerText = ' / ' + option.companyCode;
                        } else {
                            span.style.display = 'none';
                        }
                    }),
                    createElement('span', span => {
                        span.className = 'title-company-selector';
                        if (option.recordReadonly) {
                            span.style.display = 'none';
                        }
                        setTooltip(span, r('FLTL_02654', 'Select Customer'));
                        if (typeof option.onAddCompany === 'function') {
                            span.addEventListener('click', () => option.onAddCompany.call(this));
                        }
                    },
                        createIcon('fa-light', 'search')
                    )
                )
            ),
            [
                setTooltip(checkAutoUpdate, r('FLTL_00420', 'Auto Updates Enabled')),
                setTooltip(checkLink, r('FLTL_02829', '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('FLTL_01157', '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('FLTL_01970', '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('FLTL_02692', 'Send Message'));
                        button.addEventListener('click', () => {
                            const val = this.text;
                            if (nullOrEmpty(val?.trim())) {
                                const p = showAlert(r('FLTL_01165', 'Error'), r('FLTL_02233', '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 || (recordReadonly && nullOrEmpty(option.companyName))) {
                            button.style.display = 'none';
                        }
                        button.appendChild(createIcon('fa-solid', 'user-edit'));
                        setTooltip(button, r('FLTL_01043', 'Edit Contacts'));
                        button.addEventListener('click', () => {
                            const editContacts = () => {
                                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('FLTL_01043', 'Edit Contacts')),
                                                createElement('div', div => {
                                                    div.className = 'title-company';
                                                    div.style.maxWidth = '540px';
                                                    if (nullOrEmpty(option.companyName)) {
                                                        div.style.display = 'none';
                                                    }
                                                },
                                                    createElement('span', span => {
                                                        span.className = 'title-company-name';
                                                        if (!nullOrEmpty(option.companyName)) {
                                                            span.innerText = option.companyName;
                                                        }
                                                    }),
                                                    createElement('span', span => {
                                                        span.className = 'title-company-code';
                                                        if (!nullOrEmpty(option.companyCode)) {
                                                            span.innerText = '/' + 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 || nullOrEmpty(option.companyName)) {
                                                    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('FLTL_02657', '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('FLTL_02657', '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('FLTL_00099', 'Add Contact'), r('FLTL_00638', '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('FLTL_00099', 'Add Contact'))
                                            })
                                        )
                                    }),
                                    content: createElement('div', null,
                                        createElement('div', div => {
                                            if (nullOrEmpty(option.companyName)) {
                                                div.style.display = 'none';
                                            }
                                            div.style.fontWeight = 'bold';
                                            div.innerText = r('FLTL_00657', '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('FLTL_00659', '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('FLTL_02090', 'Opted In') : r('FLTL_02091', '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('FLTL_01032', '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('FLTL_01041', 'Edit Contact'), r('FLTL_00638', '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('FLTL_00791', 'Delete'),
                                            events: {
                                                onclick: function () {
                                                    showConfirm(
                                                        r('FLTL_02417', 'Remove Contact'),
                                                        createElement('div', null,
                                                            createElement('div', div => {
                                                                div.style.paddingLeft = '16px';
                                                                div.innerText = r('FLTL_02412', '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('FLTL_00747', 'Customer Record'),
                                                                    checked: true,
                                                                    className: 'radio-customer-record'
                                                                }),
                                                                createRadiobox({
                                                                    name: 'remove-type',
                                                                    label: r('FLTL_03317', 'Work Order')
                                                                })
                                                            )
                                                        ),
                                                        [
                                                            { key: 'ok', text: r('FLTL_02057', 'OK') },
                                                            { key: 'cancel', text: r('FLTL_00499', 'Cancel') }
                                                        ]
                                                    ).then(r => {
                                                        if (r.result === 'ok') {
                                                            const isRecord = r.popup.container.querySelector('.radio-customer-record>input').checked;
                                                            if (typeof option.onDelete === 'function') {
                                                                option.onDelete(r.result, 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.onSelectedRowChanged = 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('FLTL_00791', 'Delete'),
                                            events: {
                                                onclick: function () {
                                                    showConfirm(r('FLTL_02417', 'Remove Contact'), r('FLTL_03382', 'You are removing {name} from work order.\n\nDo you want to Continue?').replace('{name}', this.Name), [
                                                        { key: 'continue', text: r('FLTL_00661', 'Continue') },
                                                        { key: 'cancel', text: r('FLTL_00499', 'Cancel') }
                                                    ]).then(r => {
                                                        if (r.result === 'continue') {
                                                            if (typeof option.onDelete === 'function') {
                                                                option.onDelete(r.result, 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.onSelectedRowChanged = index => {
                                        if (index >= 0 && this._var.gridContact.selectedIndexes?.length > 0) {
                                            this._var.gridContact.selectedIndexes = [];
                                        }
                                    };
                                    this._var.gridWo = gridWo;
                                });
                            };
                            if (nullOrEmpty(option.companyName)) {
                                showConfirm(
                                    r('FLTL_01043', 'Edit Contacts'),
                                    r('FLTL_03008', 'There is no company associated with this work order. Would you like to add one?\n\nIf no company is indicated, contacts must be added as "Work Order Only".'),
                                    [
                                        { key: 'add', text: r('FLTL_00098', 'Add Company') },
                                        { key: 'skip', text: r('FLTL_02777', 'Skip This Step') }
                                    ]
                                ).then(r => {
                                    if (r.result === 'add') {
                                        if (typeof option.onAddCompany === 'function') {
                                            option.onAddCompany.call(this);
                                        }
                                    } else if (r.result === 'skip') {
                                        editContacts();
                                    }
                                });
                            } else {
                                editContacts();
                            }
                        });
                    })
                ),
                createElement('div', div => {
                    div.className = 'bar-info';
                    div.innerText = r('FLTL_00635', '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('FLTL_01054', 'Edit Followers'));
            button.addEventListener('click', () => {
                if (typeof option.onInitFollower === 'function') {
                    option.onInitFollower(this._var.data.followers).then(data => {
                        if (typeof data === 'string') {
                            showAlert(r('FLTL_00747', '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('FLTL_01054', 'Edit Followers') : r('FLTL_00116', '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('FLTL_00667', 'Copied')),
                createElement('div', 'bar-list',
                    followers,
                    buttonEditFollower
                )
            )
        );
        return followers;
    }

    load(data, contacts, followers, func, hisFunc, keep) {
        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;
                }
            }
            const lastVisible = this._var.option.showMessageHidden;
            for (let comment of data) {
                const div = createElement('div', 'item-div');
                if (comment.Hidden) {
                    div.classList.add('hidden-content');
                    if (!lastVisible) {
                        div.style.display = 'none';
                    }
                }
                let name;
                if (comment.IsReply && contacts?.length > 0) {
                    const c = isEmail(comment.Sender) ?
                        contacts.find(c => c.Email === comment.Sender) :
                        contacts.find(c => c.MobilePhone === comment.Sender);
                    name = c?.Name;
                }
                name ??= comment.IsReply && String(comment.FormatSender) !== '' ? comment.FormatSender : comment.Sender;
                const sendto = getMessageSendTo(comment, contacts, followers, r)
                div.appendChild(createElement('div', div => {
                    div.className = 'item-poster';
                    div.innerText = name;
                    if (!comment.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(comment.Message)) {
                        span.innerHTML = formatUrl(escapeEmoji(comment.Message));
                    } else {
                        span.innerText = escapeEmoji(comment.Message);
                    }
                    span.appendChild(mmsParts);
                }));
                if (comment.MMSParts?.length > 0) {
                    mmsParts.style.display = '';
                    for (let kv of comment.MMSParts) {
                        appendMedia(mmsParts, kv.Key, kv.Value);
                    }
                }
                if (comment.IsReply) {
                    div.classList.add('item-other');
                } else {
                    div.classList.add('item-self');
                    const [status, text, color, tips] = getMessageStatus(comment, 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,
                    createHideMessageCommentTail(
                        this, 'showMessageHidden',
                        comment, 'TimeStr',
                        func, hisFunc)
                );
                children.push(div);
            }
            children[0].style.marginTop = '0';
        }
        if (this._var.message.children.length > 0) {
            this._var.lastTop = this._var.message.scrollTop;
        }
        this._var.message.replaceChildren(...children);
        requestAnimationFrame(() => this._var.message.scrollTop = keep ? this._var.lastTop : this._var.message.scrollHeight);
    }
}