import { Grid, createElement, setTooltip, createIcon, createCheckbox, createRadiobox, createPopup, showAlert, showConfirm } from "../../ui";
import { r, nullOrEmpty, formatUrl, isEmail, isPhone } from "../../utility";
import { createBox } from "./lib";
import Contact from "./contact";
import Follower from "./follower";

class NoteCol extends Grid.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);
        }
        element.querySelector('.contact-note').innerText = item.Notes;
    }
}

class CustomerCommunication {
    #container;
    #option;
    #contacts;
    #followers;
    #buttonFollower;
    #enter;
    #message;
    #data = {};
    #gridContact;
    #gridWo;
    #gridFollower;

    constructor(opt) {
        this.#option = opt ?? {};
    }

    get #autoUpdates() { return this.#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.#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.#container == null) {
            return;
        }
        this.#enter.disabled = flag;
        this.#container.querySelector('.customer-name>.ui-input').disabled = flag;
        this.#container.querySelector('.button-send-message').disabled = flag;
        this.#container.querySelector('.button-edit-contacts').disabled = flag;
        this.#container.querySelector('.button-edit-followers').disabled = flag;
    }

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

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

    get contacts() {
        return [...this.#contacts.children].map(el => {
            const span = el.querySelector('span');
            return { 'Key': span.dataset.to, 'Value': span.dataset.name };
        });
    }
    set contacts(contacts) {
        this.#contacts.replaceChildren();
        if (contacts?.length > 0) {
            for (let c of contacts) {
                if (c.OptOut || c.OptOut_BC || c.selected === false) {
                    continue;
                }
                const mp = String(c.MobilePhone).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;
                switch (pref) {
                    case '0':
                        icon = 'comment-lines';
                        method = r('textsToColon', 'Texts to:');
                        break;
                    case '2':
                        icon = 'mobile';
                        method = r('callsToColon', 'Calls to:');
                        break;
                    default:
                        icon = 'envelope';
                        method = r('emailsToColon', 'Emails to:');
                        break;
                }
                const span = createElement('span', span => {
                    span.dataset.to = to;
                    span.dataset.name = c.Name;
                    span.innerText = c.Name;
                });
                const item = createElement('div', 'contact-item',
                    createIcon('fa-light', icon),
                    span
                );
                this.#contacts.appendChild(item);
                let tip = `${method} ${to}`;
                if (span.scrollWidth > span.offsetWidth) {
                    tip = r('nameColon', 'Name:') + ` ${c.Name}\n${tip}`;
                }
                setTooltip(span, tip);
            }
            this.#message.scrollTop = this.#message.scrollHeight
        }
    }

    /**
     * @param {boolean} flag
     */
    set readonly(flag) {
        this.#option.readonly = flag;
        if (this.#container == null) {
            return;
        }
        const link = this.#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.#container.querySelector('.button-edit-contacts').style.display = display;
        this.#container.querySelector('.button-edit-followers').style.display = display;
        // this.#enter.disabled = flag === true;
        this.#container.querySelector('.message-bar').style.display = display;
        // this.#container.querySelector('.button-send-message').style.display = display;
    }

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

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

    get followers() {
        return [...this.#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.#data.followers = followers;
        this.#followers.replaceChildren();
        if (followers?.length > 0) {
            this.#container.querySelector('.follower-bar').style.display = '';
            this.#container.querySelector('.follower-bar>.bar-list').appendChild(this.#buttonFollower);
            for (let f of followers) {
                if (f.OptOut) {
                    continue;
                }
                const mp = String(f.MobilePhone).trim();
                const email = String(f.Email).trim();
                const tips = [];
                if (f.SendEmail) {
                    tips.push(r('emailsToColon', 'Emails to:') + ` ${email}`);
                }
                if (f.SendText) {
                    tips.push(r('textsToColon', 'Texts to:' + ` ${mp}`));
                }
                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.#followers.appendChild(item);
                if (span.scrollWidth > span.offsetWidth) {
                    tips.splice(0, 0, r('nameColon', 'Name:') + ` ${c.Name}`);
                }
                setTooltip(span, tips.join('\n'));
            }
        } else {
            this.#container.querySelector('.follower-bar').style.display = 'none';
            this.#container.querySelector('.button-edit-contacts').insertAdjacentElement('beforebegin', this.#buttonFollower)
        }
        this.#message.scrollTop = this.#message.scrollHeight
    }

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

    create() {
        const option = this.#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('autoUpdateEnabled', 'Auto Updates Enabled') :
                    r('autoUpdateDisabled', 'Auto Updates Disabled'));
            }
        });
        if (option.autoUpdatesVisible === false) {
            checkAutoUpdate.style.display = 'none';
        }
        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('statusLinkIncluded', 'Status Link Included') :
                    r('statusLinkExcluded', 'Status Link Excluded'));
            }
        });
        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('messages', 'Customer Communication');
                }),
                createElement('div', div => {
                    div.className = 'title-company';
                    if (nullOrEmpty(option.companyName)) {
                        div.style.display = 'none';
                    } else {
                        div.innerText = option.companyName;
                    }
                })
            ),
            [
                setTooltip(checkAutoUpdate, r('autoUpdateEnabled', 'Auto Updates Enabled')),
                setTooltip(checkLink, r('statusLinkExcluded', 'Status Link Excluded'))
            ]
        );
        // contacts
        this.#contacts = this.#createContacts(container, option);
        // followers
        this.#followers = this.#createFollowers(container, option);
        // enter box
        const enter = createElement('textarea', 'ui-text');
        enter.placeholder = r('typeMessage', 'Enter Message Here');
        option.maxLength ??= 3000;
        enter.maxLength = option.maxLength;
        // if (readonly === true) {
        //     enter.disabled = true;
        // }
        enter.addEventListener('input', () => {
            const val = this.#enter.value;
            const s = String(nullOrEmpty(val) ? 0 : val.length) + '/' + String(option.maxLength);
            this.#container.querySelector('.message-bar .prompt-count').innerText = s;
        });
        this.#enter = enter;
        container.appendChild(
            createElement('div', div => {
                div.className = 'message-bar';
                if (readonly === true) {
                    div.style.display = 'none';
                }
            },
                enter,
                createElement('div', div => div.style.textAlign = 'right',
                    createElement('div', div => {
                        div.className = 'customer-name';
                        if (option.customerNameVisible !== true) {
                            div.style.display = 'none';
                        }
                    },
                        createElement('span', span => span.innerText = r('nameColon', 'Name:')),
                        createElement('input', 'ui-input')
                    ),
                    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('sendMessage', 'Send Message'));
                        button.addEventListener('click', () => {
                            const val = this.#enter.value;
                            if (nullOrEmpty(val?.trim())) {
                                showAlert(r('error', 'Error'), r('messageRequired', 'Please input the message.'), 'warn');
                                return;
                            }
                            if (typeof this.#option.onAddMessage === 'function') {
                                this.#option.onAddMessage(this.#enter.value);
                            }
                        })
                    })
                )
            )
        );

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

    #createContacts(container, option) {
        const readonly = option.readonly;
        const recordReadonly = option.recordReadonly;
        const contacts = createElement('div');
        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('editContacts', 'Edit Contacts'));
                        button.addEventListener('click', () => {
                            const pop = createPopup(
                                createElement('div', div => {
                                    div.style.display = 'flex';
                                    div.style.alignItems = 'center';
                                    div.append(
                                        createElement('div', div => {
                                            div.className = 'popup-move';
                                            div.style.flex = '1 1 auto';
                                        },
                                            createElement('div', div => div.innerText = r('editContacts', 'Edit Contacts')),
                                            createElement('div', div => {
                                                div.className = 'title-company';
                                                if (nullOrEmpty(option.companyName)) {
                                                    div.style.display = 'none';
                                                } else {
                                                    div.innerText = option.companyName;
                                                }
                                            })
                                        ),
                                        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({
                                                    company: !nullOrEmpty(this.#data.companyCode),
                                                    onSave: item => {
                                                        const exists = this.#gridContact.source.some(s => s.Name === item.Name && s.MobilePhone === item.MobilePhone);
                                                        if (exists) {
                                                            showAlert(r('addContact', 'Add Contact'), r('contactUniqueRequired', '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.#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.#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('addContact', 'Add Contact'))
                                        })
                                    )
                                }),
                                createElement('div', null,
                                    createElement('div', div => {
                                        if (nullOrEmpty(this.#data.companyCode)) {
                                            div.style.display = 'none';
                                        }
                                        div.style.fontWeight = 'bold';
                                        div.innerText = r('contactFromRecord', 'Contacts from Customer Record');
                                    }),
                                    createElement('div', div => {
                                        if (nullOrEmpty(this.#data.companyCode)) {
                                            div.style.display = 'none';
                                        }
                                        div.className = 'contacts-record';
                                        div.style.maxHeight = '400px';
                                        div.style.width = '660px';
                                    }),
                                    createElement('div', div => {
                                        div.style.fontWeight = 'bold';
                                        div.innerText = r('contactFromWorkOrder', 'Contacts not on Customer Record');
                                    }),
                                    createElement('div', div => {
                                        div.className = 'contacts-wo';
                                        div.style.maxHeight = '200px';
                                        div.style.width = '660px';
                                    })
                                )
                            );
                            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.#gridContact.source, ...This.#gridWo.source]);
                                            }
                                        }
                                    }
                                };
                                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('edit', 'Edit'),
                                        events: {
                                            onclick: function () {
                                                const edit = new Contact({
                                                    contact: this,
                                                    company: !nullOrEmpty(This.#data.companyCode),
                                                    onSave: (item, _op) => {
                                                        const exists =
                                                            This.#gridContact.source.some(s => s !== this && s.Name === item.Name && s.MobilePhone === item.MobilePhone) ||
                                                            This.#gridWo.source.some(s => s !== this && s.Name === item.Name && s.MobilePhone === item.MobilePhone);
                                                        if (exists) {
                                                            showAlert(r('editContact', 'Edit Contact'), r('contactUniqueRequired', '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.#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.#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: 'MobilePhone', width: 130 },
                                    createEditCol(this),
                                    {
                                        key: 'delete',
                                        ...buttonCol,
                                        text: 'times',
                                        tooltip: r('delete', 'Delete'),
                                        events: {
                                            onclick: function () {
                                                showConfirm(
                                                    r('remoteContact', 'Remove Contact'),
                                                    createElement('div', null,
                                                        createElement('div', div => {
                                                            div.style.paddingLeft = '16px';
                                                            div.innerText = r('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('customerRecord', 'Customer Record'),
                                                                checked: true,
                                                                className: 'radio-customer-record'
                                                            }),
                                                            createRadiobox({
                                                                name: 'remove-type',
                                                                label: r('workOrder', 'Work Order')
                                                            })
                                                        )
                                                    ),
                                                    [
                                                        { key: 'ok', text: r('ok', 'OK') },
                                                        { key: 'cancel', text: r('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.#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.#gridWo.selectedIndexes?.length > 0) {
                                        this.#gridWo.selectedIndexes = [];
                                    }
                                };
                                this.#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: 'MobilePhone', width: 130 },
                                    createEditCol(this),
                                    {
                                        key: 'delete',
                                        ...buttonCol,
                                        text: 'times',
                                        tooltip: r('delete', 'Delete'),
                                        events: {
                                            onclick: function () {
                                                showConfirm(r('remoteContact', 'Remove Contact'), r('removeFromWorkorder', 'You are removing {name} from work order.\n\nDo you want to Continue?').replace('{name}', this.Name), [
                                                    { key: 'continue', text: r('continue', 'Continue') },
                                                    { key: 'cancel', text: r('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.#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.#gridContact.selectedIndexes?.length > 0) {
                                        this.#gridContact.selectedIndexes = [];
                                    }
                                };
                                this.#gridWo = gridWo;
                            });
                        });
                    })
                )
            )
        );
        return contacts;
    }

    #createFollowers(container, option) {
        const readonly = option.readonly;
        const recordReadonly = option.recordReadonly;
        const followers = createElement('div');
        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('editFollower', 'Edit Followers'));
            button.addEventListener('click', () => {
                const pop = createPopup(
                    createElement('div', div => {
                        div.style.display = 'flex';
                        div.style.alignItems = 'center';
                        div.append(
                            createElement('div', div => {
                                div.className = 'popup-move';
                                div.style.flex = '1 1 auto';
                                div.innerText = r('editContacts', 'Edit Contacts') + '\n' + r('followers', 'Followers');
                            }),
                            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-follower';
                                button.appendChild(createIcon('fa-solid', 'user-plus', {
                                    width: '16px',
                                    height: '16px'
                                }));
                                button.addEventListener('click', () => {
                                    if (typeof this.#option.onInitFollower === 'function') {
                                        this.#option.onInitFollower().then(data => {
                                            if (typeof data === 'string') {
                                                showAlert(r('customerRecord', 'Customer Record'), data, 'warn');
                                                return;
                                            }
                                            const add = new Follower({
                                                followers: data,
                                                onOk: list => {
                                                    if (typeof this.#option.onAddFollower === 'function') {
                                                        const result = this.#option.onAddFollower(list);
                                                        if (typeof result?.then === 'function') {
                                                            return result.then(r => {
                                                                this.#gridFollower.source = r;
                                                                return r;
                                                            });
                                                        }
                                                        return false;
                                                    }
                                                }
                                            });
                                            add.show(container);
                                        });
                                    }
                                });
                                setTooltip(button, r('addFollower', 'Add Follower'))
                            })
                        )
                    }),
                    createElement('div', null,
                        createElement('div', div => {
                            div.style.fontWeight = 'bold';
                            div.innerText = r('contactFromRecord', 'Contacts from Customer Record');
                        }),
                        createElement('div', div => {
                            div.className = 'followers-record';
                            div.style.maxHeight = '400px';
                            div.style.width = '660px';
                        })
                    )
                );
                pop.show(container).then(() => {
                    const buttonCol = {
                        type: Grid.ColumnTypes.Icon,
                        width: 40,
                        align: 'center',
                        iconType: 'fa-light'
                    };
                    const grid = new Grid();
                    grid.height = 0;
                    grid.allowHtml = true;
                    grid.headerVisible = false;
                    grid.columns = [
                        {
                            key: 'type',
                            type: Grid.ColumnTypes.Icon,
                            width: 50,
                            filter: c => c.SendText && c.SendEmail ? 'at' : (c.SendText ? 'comment-lines' : 'envelope'),
                            className: 'icon-contact-type',
                            iconType: 'fa-light'
                        },
                        { key: 'Name', width: 160 },
                        { key: 'Email', width: 180 },
                        { key: 'MobilePhone', width: 130 },
                        {
                            key: 'edit',
                            ...buttonCol,
                            text: 'edit',
                            tooltip: r('edit', 'Edit'),
                            events: {
                                onclick: function () {
                                    if (typeof option.onInitFollower === 'function') {
                                        option.onInitFollower().then(data => {
                                            if (typeof data === 'string') {
                                                showAlert(r('customerRecord', 'Customer Record'), data, 'warn');
                                                return;
                                            }
                                            const contact = data.find(d => d.IID === this.UserIID);
                                            showConfirm(
                                                r('editContactMethod', 'Edit Contact Method'),
                                                createElement('div', 'wrapper-edit-method',
                                                    createElement('div', div => {
                                                        div.style.display = 'flex';
                                                        div.style.justifyContent = 'center';
                                                        div.style.marginTop = '20px';
                                                    },
                                                        createCheckbox({
                                                            label: r('text', 'Text'),
                                                            checked: this.SendText && !nullOrEmpty(contact?.Mobile),
                                                            enabled: !nullOrEmpty(contact?.Mobile),
                                                            className: 'check-method-text'
                                                        }),
                                                        createCheckbox({
                                                            label: r('email', 'Email'),
                                                            checked: this.SendEmail,
                                                            className: 'check-method-email'
                                                        })
                                                    )
                                                ),
                                                [
                                                    {
                                                        key: 'ok',
                                                        text: r('ok', 'OK'),
                                                        trigger: (popup, button) => {
                                                            const text = popup.container.querySelector('.check-method-text>input').checked;
                                                            const email = popup.container.querySelector('.check-method-email>input').checked;

                                                            if (!text && !email) {
                                                                return showConfirm(r('editContactMethod', 'Edit Contact Method'), r('promptRemoveFollower', 'Contact method is required. If you continue, user will be removed as a follower.'), [
                                                                    { key: 'update', text: r('updateContactMethod', 'Update Contact Method') },
                                                                    { key: 'remove', text: r('removeFollower', 'Remove Follower') }
                                                                ], 'question').then(result => {
                                                                    if (result?.key === 'remove') {
                                                                        return {
                                                                            key: result.key,
                                                                            popup
                                                                        };
                                                                    }
                                                                    return false;
                                                                });
                                                            }
                                                            return {
                                                                key: button.key,
                                                                popup
                                                            };
                                                        }
                                                    },
                                                    { key: 'cancel', text: r('cancel', 'Cancel') }
                                                ],
                                                null
                                            ).then(result => {
                                                const key = result?.key;
                                                if (key === 'remove') {
                                                    if (typeof option.onDeleteFollower === 'function') {
                                                        option.onDeleteFollower(result.key, this);
                                                    }
                                                    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;
                                                    }
                                                } else if (key === 'ok') {
                                                    const text = result.popup.container.querySelector('.check-method-text>input').checked;
                                                    const email = result.popup.container.querySelector('.check-method-email>input').checked;
                                                    if (typeof option.onChangeFollower === 'function') {
                                                        option.onChangeFollower(result.key, this, text, email);
                                                    }
                                                    this.SendText = text;
                                                    this.SendEmail = email;
                                                    grid.refresh();
                                                }
                                            });
                                        });
                                    }
                                }
                            }
                        },
                        {
                            key: 'delete',
                            ...buttonCol,
                            text: 'times',
                            tooltip: r('delete', 'Delete'),
                            events: {
                                onclick: function () {
                                    showConfirm(
                                        r('deleteFollower', 'Delete Follower'),
                                        r('promptDeleteFollower', 'Do you want to delete this follower?')
                                    ).then(result => {
                                        if (result?.key === 'yes') {
                                            if (typeof option.onDeleteFollower === 'function') {
                                                option.onDeleteFollower(result.key, this);
                                            }
                                            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('.followers-record'));
                    grid.source = this.#data.followers;
                    this.#gridFollower = grid;
                });
            });
        });
        this.#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('copied', 'Copied')),
                createElement('div', 'bar-list',
                    followers,
                    buttonEditFollower
                )
            )
        );
        return followers;
    }

    load(data, contacts, followers) {
        const children = [];
        if (data?.length > 0) {
            contacts ??= this.#data.contacts;
            followers ??= this.#data.allfollowers;
            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;
                let sendto = '';
                if (!comm.IsReply && comm.OriPhoneNumbers?.length > 0) {
                    for (let oriph of comm.OriPhoneNumbers) {
                        let cname;
                        const email = isEmail(oriph);
                        if (contacts?.length > 0) {
                            let c = email ?
                                contacts.find(c => c.Email === oriph) :
                                contacts.find(c => c.MobilePhone === oriph);
                            if (c != null) {
                                cname = `${email ? c.Email : c.MobilePhone} - ${c.Name}`;
                            } else if (followers?.length > 0) {
                                c = email ?
                                    followers.find(f => f.Email === oriph) :
                                    followers.find(f => f.MobilePhone === oriph);
                                if (c != null) {
                                    cname = `${email ? c.Email : c.MobilePhone} - ${c.Name}`;
                                }
                            }
                        }
                        sendto += (cname ?? oriph) + '\n';
                    }
                }
                if (sendto !== '') {
                    sendto = r('sendToColon', 'Send To :') + `\n${sendto}`;
                }
                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');
                content.appendChild(createElement('span', span => {
                    if (/https?:\/\//i.test(comm.Message)) {
                        span.innerHTML = formatUrl(comm.Message);
                    } else {
                        span.innerText = comm.Message;
                    }
                }));
                if (comm.IsReply) {
                    div.classList.add('item-other');
                } else {
                    div.classList.add('item-self');
                    const [status, statusmsg] = this.#getMessageStatus(comm);
                    if (status !== -100) {
                        let statustext;
                        switch (status) {
                            case 0:
                                statustext = r('pending', 'Pending');
                                content.style.backgroundColor = '#ffc107';
                                break;
                            case 1:
                                statustext = r('sent', 'Sent');
                                break;
                            case 9:
                                statustext = r('failed', 'Failed');
                                content.style.backgroundColor = '#ffc107';
                                break;
                            case 10:
                                statustext = r('optOut', 'Opt-Out');
                                content.style.backgroundColor = '#ffc107';
                                break;
                            case 412:
                                statustext = r('landline', 'Landline');
                                content.style.backgroundColor = '#ffc107';
                                break;
                            default:
                                statustext = r('undelivered', 'Undelivered');
                                content.style.backgroundColor = '#ffc107';
                                break;
                        }
                        const divstatus = createElement('div', div => {
                            div.className = 'item-status';
                            div.innerText = statustext;
                            if (status == -10) {
                                setTooltip(div, statusmsg);
                            }
                        });
                        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.#message.replaceChildren(...children);
        this.#message.scrollTop = this.#message.scrollHeight
        // setTimeout(() => this.#message.scrollTop = this.#message.scrollHeight, 0);
    }

    #getMessageStatus(comm) {
        let status = -100;  // 没有状态,页面上不显示
        const ls = [];
        let statusmsg = '';
        if (!comm.StatusIncorrect && comm.Participator?.length > 0) {
            for (let p of comm.Participator) {
                if (!isEmail(p.CustomerNumber)) {
                    if (ls.indexOf(p.Status) < 0) {
                        ls.push(p.Status);
                    }
                    if (statusmsg.length > 0) {
                        statusmsg += '\n';
                    }
                    statusmsg += `${p.CustomerNumber}: `;
                    const st = ({
                        0: r('undelivered', 'Undelivered'),
                        1: r('sent', 'Sent'),
                        9: r('failed', 'Failed')
                    })[p.Status];
                    if (st != null) {
                        statusmsg += st;
                    }
                }
            }
        }
        if (ls.length === 1) {
            status = ls[0];
        } else if (ls.length > 1) {
            status = -10; // 多种状态
        }
        return [status, statusmsg];
    }
}

export default CustomerCommunication;