import m from 'http://devtalk.kospo.co.kr:3000/static/bundle/mithril-2.2.2/mithril.js'
import {global} from "http://devtalk.kospo.co.kr:3000/static/js/module/variable.js";
import {talkMapping} from "http://devtalk.kospo.co.kr:3000/static/js/module/render.js";
import SockJS from "http://devtalk.kospo.co.kr:3000/static/bundle/sockjs-client-1.6.1/sockjs.js";
import {getTalkList, getMessageAll, getMoreMessageAll} from "http://devtalk.kospo.co.kr:3000/static/js/module/apis.js";
import {HubEvent} from "http://devtalk.kospo.co.kr:3000/static/js/module/hubEvent.js";
import {getApInfo} from "http://devtalk.kospo.co.kr:3000/static/js/module/apis.js";
import Common from "http://devtalk.kospo.co.kr:3000/static/js/utils.js";
import Hub from "http://devtalk.kospo.co.kr:3000/static/js/module/hub.js";

// 톡방 기능
let reConnectAttempts = 0;
let reConnectCnt = 0;
let errCnt = 0;
const talkEvent = {
    // 소켓 연결
    connect() {
        const _this_ = this;
        /*현재 서버 정보 호출*/
        getApInfo().then((data) => {
            global.currentServer = data.server
        })

        return new Promise((resolve, reject) => {
            /*소켓연결*/
            global.sockJS = new SockJS(
                `${global.apiUrl}/stomp/talk`, {
                    Authentication: global.option.encSabun
                }, {
                    transports: ['websocket'],
                    reconnectInterval: 500,
                    reconnectDelay: 500,
                }
            );

            global.stomp = window.Stomp.over(global.sockJS);
            global.stomp.heartbeat.outgoing = 20000;
            global.stomp.heartbeat.incoming = 20000;
            global.stomp.debug = (e) => {
                if (e.includes('ERROR') || e.includes('Exception') || e.includes('failed')) {
                    // console.log(new Date().toString())
                    // console.error('STOMP error:', e);
                }
            };

            /*stomp 연결*/
            global.stomp.connect({Authentication: global.option.encSabun, location: 'TALK'}, function (frame) {
                resolve();
            })

            global.stomp.onerror = (e) => {
                console.log('err', e)
            }

            global.stomp.onclose = (e) => {
                console.log('close', e)
            }

            const maxReconnectAttempts = 3;
            const baseDelay = 10;
            global.sockJS.onclose = (e) => {
                if (e.wasClean) {
                    console.log('[Chat] WS Closed', new Date())
                } else {
                    console.log('[Chat] WS Connecting...', new Date())
                }

                console.log(e)
                /* 구독 해제 (남아 있는데이터 삭제) */
                talkEvent.allUnsubscribe()
                const delay = Math.min(baseDelay * Math.pow(100, reConnectAttempts), 2000)
                const reConnectTimeout = setTimeout(() => {
                    if (reConnectAttempts < maxReconnectAttempts) {
                        reConnectAttempts++;
                        this.reConnect();
                    } else {
                        console.log('[Chat] Max Reconnect attempts reached.')
                        clearTimeout(reConnectTimeout)
                        /*서비스워커 종료*/
                        HubEvent.kill(global.talkParams({
                            type: 'KILL',
                            channelSabun: global.user.sabun
                        }))
                        global.forceKill = true;
                        global.shadowRoot.querySelector('.server-error').classList.remove('cus-hide')
                    }
                }, delay)
            }
        })

    },
    reConnect: async () => {
        console.log('reconnect')
        // 소켓 설정 초기화
        global.subscribeList = [];

        /*현재 서버 정보 호출*/
        let data = {};
        try {
            data = await getApInfo();
        } catch (e) {
            data['server'] = '';
        }

        /*ap 다른곳으로 이동시 서비스워커 재설치*/
        if (global.currentServer !== data.server) {
            HubEvent.close({
                type: 'TAB_CLOSE',
                tabId: global.tabId,
                url: global.apiUrl,
                sabun: global.user.sabun,
                channelSabun: global.user.sabun,
                site: global.currentUrl
            })

            global.hub.install().then(() => {
                // 허브설정
                HubEvent.start(global.talkParams({
                    type: 'START',
                    tabId: global.tabId
                }))
            });
        }

        talkEvent.connect().then(async () => {
            global.hub.start();
            // 톡방 재갱신
            getTalkList(false).then(async () => {
                // 톡방 메시지 재갱신
                // getMessageAll(false)
                getMoreMessageAll()
                reConnectAttempts = 0;
                console.log('global.init = true')
            });
            // 현재 탭 외 모든 탭 구독 해지
            HubEvent.send(global.talkParams({
                type: 'UNSUBSCRIBE',
                tabId: global.tabId
            }))
            // 개인 사번 소켓 연결
            try{global.subscribeList[global.user.sabun] = talkEvent.userSubscribe();}catch(e){}
            // 업무별 소켓 연결
            try{global.subscribeList[global.work.workId] = talkEvent.workSubscribe();}catch(e){}

            global.init = true;
        });

        global.currentServer = data.server;
        console.log('reConnectAttempts', reConnectAttempts)
    },
    // 오류 보수
    // (추후 사용자 장애시 해당 기능 추가)
    // 서비스워커 제거, 소켓 제거 후 재시작
    repair: () => {
        talkEvent.allUnsubscribe();
        window.location.href = window.location.href;
    },
    // 개인 사번 구독
    userSubscribe: () => {
        return global.stomp.subscribe(`/exchange/user.exchange/user.${global.user.sabun}`, async function (content) {
            const payload = JSON.parse(content.body);
            if(payload.type === 'DEAD_MESSAGE') {
                global.shadowRoot.querySelector('.socket-error').classList.remove('cus-hide')
            } else {
                console.log('userSubscribe', payload)
                let sendFlag = false;
                while (!sendFlag) {
                    if (global.serviceWorkerConnect) {
                        HubEvent.send(payload)
                        sendFlag = true;
                    } else {
                        global.registration.active.postMessage({"type": "WAKEUP"})
                    }
                    await Common.sleep(100)
                }
                global.serviceWorkerConnect = false;
            }

        });
    },
    // 업무 구독
    workSubscribe: () => {
        return global.stomp.subscribe(`/exchange/work.exchange/work.${global.work.workId}`, async function (content) {
            const payload = JSON.parse(content.body);
            console.log('workSubscribe', payload)
            let sendFlag = false;
            while (!sendFlag) {
                if (global.serviceWorkerConnect) {
                    HubEvent.work(payload)
                    sendFlag = true;
                } else {
                    global.registration.active.postMessage({"type": "WAKEUP"})
                }
                await Common.sleep(100)
            }
            global.serviceWorkerConnect = false;
        });
    },
    // 파일 구독
    fileSubscribe: (payload) => {
        global.fileSubscribeList[payload.talkId] = global.stomp.subscribe(`/exchange/file.exchange/file.${payload.talkId}`, async function (content) {
            const payload = JSON.parse(content.body);
            console.log('file subscribe', payload)
            let sendFlag = false;
            while (!sendFlag) {
                if (global.serviceWorkerConnect) {
                    HubEvent.fileSend(payload)
                    sendFlag = true;
                } else {
                    global.registration.active.postMessage({"type": "WAKEUP"})
                }
                await Common.sleep(100)
            }
            global.serviceWorkerConnect = false;
        })
    },
    //톡방 구독
    subscribe: (talkId) => {
        return global.stomp.subscribe(`/exchange/talk.exchange/room.${talkId}`, async function (content) {
            const payload = JSON.parse(content.body);
            let sendFlag = false;
            while (!sendFlag) {
                if (global.serviceWorkerConnect) {
                    HubEvent.send(payload)
                    sendFlag = true;
                } else {
                    global.registration.active.postMessage({"type": "WAKEUP"})
                }
                await Common.sleep(100)
            }
            global.serviceWorkerConnect = false;
        });
    },
    // 구독 해지
    unsubscribe: (talkId) => {
        try {
            global.subscribeList[talkId].unsubscribe()
        } catch (e) {
        }
        delete global.subscribeList[talkId];
        // global.subscribeList[talkId] = null;
    },
    // 전체 구독 해지 (구독과 관련된 모든 데이터 초기화)
    allUnsubscribe: () => {
        Object.keys(global.subscribeList).forEach((key) => {
            try {
                global.subscribeList[key].unsubscribe();
            } catch (e) {
            }
        })
        try {
            global.subscribeList = [];
            if(global.stomp && global.stomp.connected) {
                global.stomp.disconnect(function() {
                    try {global.sockJS.close();} catch(e) {}
                    console.log('stomp 연결 해지 완료', global.stomp , global.sockJS)
                    global.stomp = null;
                    global.sockJS = null;
                })
            } else if(global.sockJS && global.sockJS.readyState === 1) {
                try {global.sockJS.close();} catch(e) {}
                console.log('sockjs 연결 해지 완료', global.stomp , global.sockJS)
                global.sockJS = null;
            }

        } catch (e) {
            console.log('allUnsubscribe error ', e)
        }

    },
    // 톡 시작
    start: (msgObj) => {
        global.stomp.send(`/pub/talk.start.${msgObj.talkId}`, {}, JSON.stringify(msgObj))
    },
    // 톡 메시지 전송
    send: async (msgObj) => {
        if (Common.isMaster()) {
            global.stomp.send(`/pub/talk.message.${msgObj.talkId}`, {}, JSON.stringify(msgObj))
        } else {
            msgObj.type = `SEND_${msgObj.type}`
            let sendFlag = false;
            while (!sendFlag) {
                if (global.serviceWorkerConnect) {
                    HubEvent.send(msgObj)
                    sendFlag = true;
                } else {
                    global.registration.active.postMessage({"type": "WAKEUP"})
                }
                await Common.sleep(100)
            }
            global.serviceWorkerConnect = false;
        }
    },
    // 톡 종료
    close: (msgObj) => {
        global.stomp.send(`/pub/talk.close.${msgObj.talkId}`, {}, JSON.stringify(msgObj))
    },
    // 톡 첩부파일 전송
    attach: async (msgObj) => {
        if (Common.isMaster()) {
            global.stomp.send(`/pub/talk.attach.${msgObj.talkId}`, {}, JSON.stringify(msgObj))
        } else {
            let sendFlag = false;
            while (!sendFlag) {
                if (global.serviceWorkerConnect) {
                    HubEvent.fileSend(msgObj)
                    sendFlag = true;
                } else {
                    global.registration.active.postMessage({"type": "WAKEUP"})
                }
                await Common.sleep(100)
            }
            global.serviceWorkerConnect = false;
        }
    },
    // 톡 생성
    join: async (msgObj) => {
        if (Common.isMaster()) {
            global.stomp.send(`/pub/talk.enter.${msgObj.talkId}`, {}, JSON.stringify(msgObj))
        } else {
            let sendFlag = false;
            while (!sendFlag) {
                if (global.serviceWorkerConnect) {
                    HubEvent.send(msgObj)
                    sendFlag = true;
                } else {
                    global.registration.active.postMessage({"type": "WAKEUP"})
                }
                await Common.sleep(100)
            }
            global.serviceWorkerConnect = false;
        }
    },
    // 톡 떠나기
    leave: async (msgObj) => {
        if (Common.isMaster()) {
            global.stomp.send(`/pub/talk.leave.${msgObj.talkId}`, {}, JSON.stringify(msgObj))
        } else {
            let sendFlag = false;
            while (!sendFlag) {
                if (global.serviceWorkerConnect) {
                    HubEvent.send(msgObj)
                    sendFlag = true;
                } else {
                    global.registration.active.postMessage({"type": "WAKEUP"})
                }
                await Common.sleep(100)
            }
            global.serviceWorkerConnect = false;
        }
    },
    // 시스템 변경
    change: (msgObj) => {
        /*유지보수 여러탭 구현 필요없음*/
        global.stomp.send(`/pub/talk.change.${msgObj.talkId}`, {}, JSON.stringify(msgObj))
    },
    // 톡 아이디 생성
    generateUUID: () => {
        let d = new Date();
        if (typeof performance !== 'undefined' && typeof performance.now === 'function') {
            d + performance.now();
        }

        const uuid = 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxxxxxxyxxxxxxxxxy'.replace(/[xy]/g, function (c) {
            const r = (d + Math.random() * 16) % 16 | 0;
            d = Math.floor(d / 16);
            return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
        })
        return uuid;
    },
    // 탭 아이디 생성
    generateTabUUID: () => {
        let d = new Date();
        if (typeof performance !== 'undefined' && typeof performance.now === 'function') {
            d + performance.now();
        }

        const uuid = 'xxxxxxxxxxxx4xxxyxxxxxxxxxx'.replace(/[xy]/g, function (c) {
            const r = (d + Math.random() * 16) % 16 | 0;
            d = Math.floor(d / 16);
            return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
        })
        return uuid;
    },
    /* 톡방 안에 담당자 및 업무명 변경*/
    talkHeaderChange: (workNm, name) => {
        const chatHeader = global.shadowRoot.querySelector('.chat-content-header');
        if (workNm) {
            chatHeader.querySelector('#work-nm').innerText = workNm
        }
        if (name) {
            const names = name.split(',')
            if (names.length === 1) {
                chatHeader.querySelector('#work-sm-nm').classList.remove('cus-tooltip')
                chatHeader.querySelector('#work-sm-nm').classList.remove('chat-inner-tooltip')
                chatHeader.querySelector('#work-sm-nm').setAttribute("data-tooltip", '')
                chatHeader.querySelector('#work-sm-nm').innerText = name;
            } else {
                chatHeader.querySelector('#work-sm-nm').classList.add('cus-tooltip')
                chatHeader.querySelector('#work-sm-nm').classList.add('chat-inner-tooltip')
                chatHeader.querySelector('#work-sm-nm').setAttribute("data-tooltip", name)
                chatHeader.querySelector('#work-sm-nm').innerText = `${names[0]}외 ${names.length - 1}명`;
            }
        }
    },
    // 톡 내용 활성화
    messageShow: () => {
        talkEvent.messageClean();
        global.shadowRoot.querySelector('#chat-tab').click()
        global.shadowRoot.querySelector('#chat-0').classList.add('active')
        global.element.chatSidebar.style.left = '-100%'
    },
    // 톡방 삭제
    talkRemove: (talkId) => {
        //톡방 삭제후 배지 카운트 재정의
        global.talkData.forEach((talk, idx) => {
            if (talk.talkId === talkId) {
                console.log('talkRemove :', idx, talk)
                // delete global.talkData[talk];
                global.talkData.splice(idx, 1)
            }
        })

        console.log(global.talkData)
        talkMapping(global.talkData)

        talkEvent.badgeChange()
    },
    // 톡방 보관
    talkMark: (talkId) => {
        let isMarkYn = false;
        global.talkData.forEach((chat, idx) => {
            if (chat.talkId === talkId) {
                chat.markYn = !chat.markYn;
                isMarkYn = chat.markYn;
                if (chat.markYn) {
                    global.talkData.splice(idx, 1)
                    global.talkData = [chat, ...global.talkData]
                }
            }
        })

        if (!isMarkYn) {
            global.talkData.sort((a, b) => {
                if (!b.markYn) {
                    if (a.insDate > b.insDate) {
                        return -1
                    } else if (a.insDate < b.insDate) {
                        return 1
                    }
                }
            })
        }
        talkMapping(global.talkData)
    },
    // 톡방 정렬
    talkSort: () => {
        global.talkData.sort((a, b) => {
            if (a.markYn) {
                return -1;
            } else {
                if (a.lastMessageDate >= b.lastMessageDate) {
                    return -1;
                } else if (a.lastMessageDate < b.lastMessageDate) {
                    return 1;
                }
            }


        })
    },
    // 톡방 현재 스크롤 위치
    messageScrollOriginalPositionMove: () => {
        const contentBody = global.shadowRoot.querySelector('.chat-content-body');
        const _contentScroll = contentBody.querySelector('.simplebar-content-wrapper')
        _contentScroll.scrollTop = _contentScroll.scrollHeight - global.oldScrollPosition
    },
    // 스크롤 위치 가 변경 되었을시 메시지 미리보기
    preMessageShow: (text) => {
        const preMsg = global.shadowRoot.querySelector('.message-preview');
        const msg = preMsg.querySelector('.msg');
        msg.innerText = text;

        preMsg.classList.remove('cus-hide');
    },
    // 메시지 삭제
    messageClean: () => {
        // 초기화 해야할 데이터
        global.currDay = '0';
        global.yourOldDate = '';
        global.mineOldDate = '';

        const chatContent = global.shadowRoot.querySelector('#chat-content');
        const content = chatContent.querySelector('.simplebar-content');
        m.render(content, []);
        content.innerHTML = '';
        global.element.chatEditor.innerHTML = '';
    },
    // 메인 뱃지 카운트 초기화
    badgeChange: () => {
        const badgeUnCount = global.talkData.reduce((a, b) => {
            return Number(a) + Number(b.unReadCnt)
        }, 0);
        const chatBadge = global.shadowRoot.querySelector('.unread.badge');
        if (badgeUnCount !== parseInt(0)) {
            chatBadge.classList.remove('cus-hide');
        } else {
            chatBadge.classList.add('cus-hide');
        }
        chatBadge.innerText = badgeUnCount;
    },
    /*채팅룸 읾음 표시로 변경*/
    readMessage: (talkId) => {
        console.log('readmessage', talkId)
        global.shadowRoot.querySelector(`div[data-talk-id="${talkId}"]`).classList.remove('unread-message')
        const room = global.shadowRoot.querySelector(`div[data-talk-id="${talkId}"]`);
        const badge = room.querySelector('.chat-list-badge')
        const cacheTalk = global.talkData.filter((talk) => talk.talkId === talkId)[0];
        try {
            cacheTalk.unReadCnt = 0;
            talkEvent.badgeChange();
            badge.remove()
        } catch (e) {/*badge 텍스트가 없을시 예외 처리*/
        }
    },
    /*채팅방 타이핑에 따른 progress 호출*/
    messageTyped: (msg) => {

        let html = ''

        html = `
                <div class="d-flex p-1 your-dot-progress cus-show">
                    <div class="avatar avatar-l me-2">
                    <!--<img class="rounded-circle" src="../assets/img/team/5.jpg" alt="">-->
                        <div class="rounded-circle chat-avatar">
                            ${msg.insName}
                        </div>
                    </div>
                    <div class="flex-1">
                        <div class="w-100">
                            <div class="stage your">
                                <div class="dot-typing"/>
                            </div>
                        </div>
                    </div>
                </div>
            `
        const chatContent = global.shadowRoot.querySelector('#chat-content');
        const content = chatContent.querySelector('.simplebar-content');
        if(!content.querySelector('.your-dot-progress')) {
            content.insertAdjacentHTML('beforeend', html)
        }
    },

    /*채팅방 타이핑을 하지 않을시 progress 제거*/
    messageUnTyped: (msg) => {
        const chatContent = global.shadowRoot.querySelector('#chat-content');
        const content = chatContent.querySelector('.simplebar-content');

        const dotProgress = content.querySelector('.your-dot-progress')
        if (dotProgress !== null) dotProgress.remove();
    },
    /*채팅리스트 메인 글 변경 */
    talkTitleChange: (talkId, sabun) => {
        const cacheTalk = global.talkData.filter((talk) => talk.talkId === talkId)[0];
        cacheTalk.talkMembers = cacheTalk.talkMembers.filter((member) => (member.sabun === 'info' || member.sabun === global.user.sabun || member.sabun === sabun))
        talkMapping(global.talkData)
    }
}

export {talkEvent}