import m from 'http://talk.kospo.co.kr:3000/static/bundle/mithril-2.2.2/mithril.js'
import {global} from "http://talk.kospo.co.kr:3000/static/js/module/variable.js";
import {talkEvent} from "http://talk.kospo.co.kr:3000/static/js/module/talkEvent.js";
import {talkMapping, messageMapping} from "http://talk.kospo.co.kr:3000/static/js/module/render.js"
import {Tab} from "http://talk.kospo.co.kr:3000/static/bundle/bootstrap-5.1.3/js/bootstrap.esm.js";
import Common from "http://talk.kospo.co.kr:3000/static/js/utils.js";
import {HubEvent} from "http://talk.kospo.co.kr:3000/static/js/module/hubEvent.js";
import {showNotification} from "http://talk.kospo.co.kr:3000/static/js/notification.js";
import receiver from "http://talk.kospo.co.kr:3000/static/js/module/receiver.js";

// api 관리
let isQuestion = true;

const talkInit = () => {
    work().then(() => {
        manual().then(() => {
            question()
        })
        docManual()
        videoManual()
    })

}
// 현재 사용자 정보
const getUser = async () => {
    global.user = await global.request({
        url: `/api/user/info/client`,
        method: 'get',
        withCredentials: true
    })
}

// itsm 만족도 조사 저장
const setITSMSatis = (talkId, reqId, rating, content) => {
    global.request({
        url: `/api/ict/satis`,
        method: 'post',
        body: {talk_id : talkId, req_id : reqId, h_point: rating, opinion: content},
        withCredentials: true
    })
}
// scm 만족도 조사 저장
const setSCMSatis = (talkId, reqId, rating, content) => {
    global.request({
        url: `/api/scm/satis`,
        method: 'post',
        body: {talk_id : talkId, req_id : reqId, h_point: rating, opinion: content},
        withCredentials: true
    })
}

// 접속 중인 시스템 정보
const work = async () => {
    global.work = await global.request({
        url: `/api/work`,
        method: 'get',
        params: {workId: global.currentWorkId},
        withCredentials: true
    })

    global.shadowRoot.querySelector('#intro-work').innerText = global.work.workNm;
    global.shadowRoot.querySelector('#intro-online').classList.add(global.work.onlineYn ? 'online' : 'offline');
    global.shadowRoot.querySelector('#intro-user').innerText = global.user.name;

    receiver.changeLoginInfo(global.work)
}

// 접속 중인 시스템의 매뉴얼
const manual = () => {
    // 현재 업무의 메뉴얼 & 비디오 메뉴얼 호출
    return new Promise((resolve, reject) => {
        global.request({
            method: 'get',
            url: `/api/manual/intro`,
            params: {workId: global.work.workId},
            withCredentials: true
        }).then((images) => {
            const manualSlide = global.shadowRoot.querySelector('#manual-play');
            const vNode = []
            if(images.length === 0) {
                const parent = Common.findParentElement(manualSlide, 'mt-4')
                parent.remove()
                isQuestion = false;
            } else {
                images.forEach((i, idx) => {
                    if (i.onm.includes("mp4")) {
                        vNode.push(
                            m('div', {class: `carousel-item ${idx === 0 ? 'active' : ''}`}, [
                                m('video', {
                                    controls: false,
                                    class: 'd-block w-100 intro-video',
                                    muted: true,
                                    preload: 'auto',
                                    autoplay: false
                                }, [
                                    m('source', {
                                        src: `${global.apiUrl}/api/manual/view/video?id=${i.id}&type=S`,
                                        type: "video/mp4"
                                    })
                                ]),
                                m('div', {class: 'video-control'}, [
                                    m('div', {class:'video-fullscreen cus-hide',  'data-ori-src': `${global.apiUrl}/api/manual/view/video?id=${i.id}&type=O`}, [
                                        m('i', {class: 'bi-fullscreen bi-color-white'})
                                    ])
                                ])
                            ])
                        )
                    } else {
                        vNode.push(
                            m('div', {class: `carousel-item ${idx === 0 ? 'active' : ''}`}, [
                                m('img', {
                                    src: `${global.apiUrl}/api/manual/view/image?workId=${global.work.workId}&vnm=${i.vnm}&sabun=${global.user.sabun}`,
                                    class: 'd-block w-100',
                                    alt: 'img1'
                                })
                            ])
                        )
                    }
                })

                m.render(manualSlide.querySelector('.carousel-inner'), vNode);
                /* 숏츠 비디오 이벤트 정의 */
                global.shadowRoot.querySelectorAll('.video-control').forEach((target) => {
                    target.addEventListener('mouseenter', () => {
                        target.querySelector('.video-fullscreen').classList.remove('cus-hide')
                        target.querySelector('.video-fullscreen').classList.add('cus-show')
                    })

                    target.addEventListener('mouseleave', () => {
                        target.querySelector('.video-fullscreen').classList.remove('cus-show')
                        target.querySelector('.video-fullscreen').classList.add('cus-hide')
                    })
                })

                global.shadowRoot.querySelectorAll('.video-fullscreen').forEach((target) => {
                    target.addEventListener('click', () => {
                        const oriSrc = target.dataset.oriSrc
                        console.log(oriSrc)
                        const fullvideo = global.shadowRoot.querySelector('#fullscreen-container');
                        fullvideo.classList.remove('cus-hide')
                        fullvideo.classList.add('cus-show');
                        const video = m('video', {preload: 'none', controls: 'controls', id: 'fullvideo', style: 'width:100%; height:100%;'}, [
                            m('source', {src: oriSrc, type: 'video/mp4'})
                        ])
                        m.render(fullvideo, video);
                        const playVideo = global.shadowRoot.querySelector('#fullvideo');
                        playVideo.requestFullscreen();
                        playVideo.play();

                        window.onresize = () => {
                            if(window.matchMedia('(display-mode: fullscreen)').matches || window.document.fullscreenElement) {
                                console.log(true)
                            } else {
                                closeFullscreen();
                                console.log(false);
                            }
                        }
                    })
                })
            }
            resolve();
        })
    })
}

const closeFullscreen = () => {
    const playVideo = global.shadowRoot.querySelector('#fullvideo');
    if(playVideo) {
        const fullvideo = global.shadowRoot.querySelector('#fullscreen-container');
        m.render(fullvideo, []);
        fullvideo.classList.remove('cus-show')
        fullvideo.classList.add('cus-hide')
    }
}

// 접속 중인 시스템의 자주 하는 질문
const question = () => {
    const questionCnt = isQuestion ? 5 : 6;
    /*현재 업무의 자주하는 질문 설정 */
    global.request({
        method: 'get',
        url: `/api/question/${global.work.workId}`,
        withCredentials: true
    }).then((question) => {
        const questionContent = global.shadowRoot.querySelector('#question');
        const question_page = Math.ceil(question.length / questionCnt)

        let question_div = null
        let paging = 0;
        question.forEach((a, idx) => {
            if(idx % questionCnt === 0) {
                paging++;
                question_div = document.createElement('div')
                question_div.setAttribute("id", `question-pg-${paging}`)
                question_div.classList.add('question-pg-container')
                if(paging !== 1) {
                    question_div.classList.add('cus-hide')
                } else {
                    question_div.classList.add('cus-show')
                }
            }

            const questionP = document.createElement("p");
            questionP.classList.add('cursor-pointer', 'question')
            const questionText = document.createTextNode(`${a.content}`)
            questionP.appendChild(questionText)
            question_div.append(questionP);
            questionP.addEventListener('click', () => {
                const talkId = talkEvent.generateUUID();
                // 키보드 숨김 해제
                global.element.chatEditorArea.classList.remove('cus-hide');
                // 채팅 구독 메시지 보내기
                localStorage.setItem(global.tabId, talkId)
                // 발 생성자 주입
                global.chatCreator = global.tabId;
                talkEvent.join(global.talkParams({
                    type: 'JOIN',
                    message: a.content,
                    talkId: talkId,
                    workId: global.work.workId,
                    introOwner: 'mine'
                }))

                talkEvent.messageShow()
            })
            if(idx % questionCnt === questionCnt-1 || idx === question.length-1) {
                questionContent.append(question_div)
            }
        })
        const pagination = document.createElement('div');
        pagination.classList.add('fx', 'fx-gap')
        pagination.setAttribute("id", 'question_pg')
        for(var i=0; i< question_page; i++) {
            const pagination_btn = document.createElement('div')
            if(i === 0) {
                pagination_btn.classList.add('btn', 'active')
                pagination_btn.dataset.pg = i
            } else {
                pagination_btn.classList.add('btn')
                pagination_btn.dataset.pg = i
            }
            pagination.append(pagination_btn)
        }
        questionContent.append(pagination)

        let current_page = 0

        function switchToNext(evt) {
            const {target} =evt;
            if(!target.classList.contains('btn')) {
                return;
            }
            const clickedBtn = target;
            if(clickedBtn.classList.contains('active')) {
                return;
            }

            const activeBtn = pagination.getElementsByClassName('active')[0]
            activeBtn?.classList.remove("active")
            clickedBtn.classList.add('active')
            global.shadowRoot.querySelectorAll(".question-pg-container").forEach((el) => {
                el.classList.add('cus-hide')
                el.classList.remove('cus-show')
            });
            const active = global.shadowRoot.querySelector(`#question-pg-${Number(clickedBtn.dataset.pg) + 1}`)
            active.classList.remove('cus-hide')
            active.classList.add('cus-show')
            current_page = Number(clickedBtn.dataset.pg) + 1;
        }

        pagination.addEventListener('click', switchToNext)

        /*자주찾는 질문이 2페이지 이상일때만 실행*/
        if(question_page > 1) {
            setInterval(autoNext, 10000)
            function autoNext() {
                let movePage = Number(current_page) + 1
                if(question_page < movePage) movePage = 1;
                global.shadowRoot.querySelectorAll(".question-pg-container").forEach((el) => {
                    el.classList.add('cus-hide')
                    el.classList.remove('cus-show')
                });
                const active = global.shadowRoot.querySelector(`#question-pg-${movePage}`);
                active.classList.remove('cus-hide')
                active.classList.add('cus-show')
                current_page = movePage;
            }
        }

        if(!isQuestion) {
            const question = global.shadowRoot.querySelector('#question');
            const questionPg = global.shadowRoot.querySelector('.question-pg-container');
            question.style.minHeight = '286px';
            questionPg.style.minHeight = '230px';
        }
    })
}

// 접속 중인 시스템의 문서 매뉴얼

const docManual = () => {
    /*본인 메뉴얼*/
    global.request({
        method: 'get',
        url: `/api/manual`,
        params: {workId: global.work.workId, type: '0000'},
        withCredentials: true
    }).then((manuals) => {
        const manualVNode = [];

        manuals.map((ma) => {
            manualVNode.push(
                m('div', {class: "d-flex justify-content-start manual-content"}, [
                    m('div', {class: "p-2 text-ellipsis", style: "width:60%;cursor: help;", title:ma.onm}, `${ma.onm}`),
                    m('div', {class: "p-2", style: "width:20%;"}, `${ma.version}`),
                    m('a', {
                        href: `${global.apiUrl}/api/manual/download/doc?workId=${ma.workId}&vnm=${ma.vnm}`,
                        target: '_download_',
                        rel: 'noopener',
                        style: 'padding-top:6px;'
                    }, [
                        m('i', {
                            class: "bi bi-download text-black",
                            style: "padding-right:10px; font-size:1.0rem; cursor:pointer;"
                        })
                    ])
                ])
            )
        })
        const manualBody = global.shadowRoot.querySelector('#manual-doc-body');
        const content = manualBody.querySelector('.simplebar-content');
        if(manualVNode.length > 0)  m.render(content, manualVNode)
    })
}

// 접속 중인 시스템의 동영상 매뉴얼
const videoManual = () => {
    global.request({
        method: 'get',
        url: `/api/manual/video`,
        params: {workId: global.work.workId},
        withCredentials: true
    }).then((manuals) => {
        const manualVNode = [];
        manuals.map((ma) => {
            manualVNode.push(
                m('div', {class: "d-flex justify-content-evenly manual-content"}, [
                    m('div', {class: "p-2 text-ellipsis", style: "width:70%;"}, `${ma.onm}`),
                    // m('div', {class: "p-2", style: "font-size:13px; width:20%;"}, `${ma.version}`),
                    m('button', {
                        class: 'btn btn-sm btn-play manual-play-btn p-0',
                        'data-id': ma.id,
                    }, '재생')
                ])
            )
        })
        const manualBody = global.shadowRoot.querySelector('#manual-video-body');
        const content = manualBody.querySelector('.simplebar-content');
        if(manualVNode.length > 0)  m.render(content, manualVNode)
        // videoManualPlayEvent();
    })

    console.log('work init end')
}

// 생성된 톡방 목록 추가
const setChatList = function (chat) {
    console.log('setChatList before', global.talkData, chat)
    global.talkData.unshift(chat)
    console.log('setChatList after', global.talkData)
    // 채팅 목록 생성
    talkMapping(global.talkData);
    // 채팅 목록 구독
    if (Common.isMaster()) {
        chatConnect([chat]);
    }
    // 채팅 부트스트랩 이벤트 수동 연결
    chatBootstrapEvent();


    talkEvent.badgeChange()

}


// 현사용자의 톡방 목록
const getTalkList = function (reset) {
    return new Promise((resolve, reject) => {
        global.request({
            url: `/api/talk`,
            method: 'get',
            withCredentials: true
        }).then((lists) => {
            if (reset) {
                global.talkData = lists;
                getTalkListEvent()
                resolve(global.talkData.length === 0 ? true : false)
            } else {
                lists.forEach(list => {
                    if (!global.talkData.map(talk => talk.talkId).join(',').includes(list.talkId)) {
                        global.talkData.push(list)
                    }
                })
                getTalkListEvent()
                resolve(global.talkData.length === 0 ? true : false)
            }
        }).catch(function (error) {
            console.log(error)
            reject()
        })
    })

}

// 톡방 이벤트 정의 소켓 연결 및 동적으로 생성된 DOM 이벤트 재설정
const getTalkListEvent = () => {
    // 채팅 목록 생성
    talkMapping(global.talkData);
    //  마스터만 채팅 목록 구독
    if (Common.isMaster()) {
        chatConnect(global.talkData);
    }
    // 채팅 부트스트랩 이벤트 수동 연결
    chatBootstrapEvent();

    talkEvent.badgeChange()
}

const getApInfo = () => {
    return new Promise((resolve, reject) => {
        global.request({
            url: `/api/getApInfo`,
            method: 'get',
            withCredentials: true
        }).then(data => {
            console.log(data)
            resolve(data);
        }).catch(() => {
            reject();
        })
    })

}

// 소켓 구독
const chatConnect = function (chats) {
    for (const ch of chats) {
        if (!ch.closeYn) {
            if (!Object.keys(global.subscribeList).includes(ch.talkId)) {
                global.subscribeList[ch.talkId] = talkEvent.subscribe(ch.talkId)
            }
        }
    }
}

// 톡방 이벤트 정의
const chatBootstrapEvent = () => {
    /*bootstrap 수동 이벤트 설정*/

    global.shadowRoot.querySelectorAll('div[data-bs-toggle="tab"]').forEach((el) => {
        if (!el.dataset.tabListener) {
            const tabTrigger = new Tab(el);
            el.addEventListener('click', function (e) {
                e.preventDefault();
                tabTrigger.show();
            })
        }

        el.dataset.tabListener = true;
    })
}

// 톡방 클릭시 해당 메시지
const getMessage = function (messageParams) {
    global.request({
        url: `/api/message/line`,
        method: 'get',
        params: messageParams,
        withCredentials: true
    }).then((dto) => {
        const cacheTalk = global.talkData.filter((talk) => talk.talkId === messageParams.talkId)[0];
        cacheTalk.messageParams = messageParams;
        cacheTalk.talkMessages = dto;
    });
}
/*
* 비동기 톡방 메시지 호출
* parameter
* reset : 초기 설정 일시 true 재연결시 false
* */
const getMessageAll = async function (reset) {
    const dto = await global.request({
        url: `/api/message/all`,
        method: 'get',
        withCredentials: true
    });

    if (reset) {
        global.talkData.forEach((talk) => {
            const cacheTalk = dto.filter((talkData) => talkData.talkId === talk.talkId)[0];
            talk.talkMessages = cacheTalk.talkMessages;
        })
    } else {
        let queue = []
        global.talkData.forEach((talk) => {
            try {
                const lastMsg = talk.talkMessages.talks[talk.talkMessages.talks.length - 1]
                const cacheTalk = dto.filter((talkData) => talkData.talkId === talk.talkId)[0];
                const newMsg = cacheTalk.talkMessages.talks.filter((ct) => {
                    return Common.dateDifference(new Date(ct.insDate), new Date(lastMsg.insDate))
                })

                if (newMsg.length > 0) {
                    newMsg.forEach((msg) => {
                        msg.workNm = talk.work.workNm
                    })
                    talk.lastMessage = newMsg[newMsg.length - 1].message;
                    talk.lastMessageDate = newMsg[newMsg.length - 1].insDate;
                    // 톡방 접속중인 경우 메시지 맵핑
                    if (localStorage.getItem(global.tabId) === talk.talkId) {
                        messageMapping(talk.talkId, {talks: newMsg}, 'after', false)
                        // 브라우저 상태가 hidden 인 경우 알림에 추가
                        if (!document.hasFocus()) queue = [...queue, ...newMsg]
                        // 그외 메시지 재정의
                    } else {
                        talk.talkMessages.talks = [...newMsg, ...talk.talkMessages.talks]
                        talk.unReadCnt = talk.unReadCnt + newMsg.length;
                        queue = [...queue, ...newMsg]
                    }
                }
            } catch (e) {
                console.log(`talk.talkId is null messages`)
            }
        })

        console.log(queue)
        // 추가된 큐가 존재 할시 톡방 저체 갱신
        // 큐에 정의된 메시지를 알림
        if (queue.length > 0) {
            talkMapping(global.talkData);
            talkEvent.badgeChange();
            queue.forEach((que) => {
                showNotification(que)
            })
        }
    }
}

const getMoreMessageAll = async function () {
    let insDate = '1999-01-01';
    global.talkData.forEach(talk => {
        if(insDate < talk.lastMessageDate) {
            insDate = talk.lastMessageDate
        }
    })

    const dtos = await global.request({
        url: `/api/message/more/all`,
        method: 'get',
        params: {'insDate': insDate},
        withCredentials: true
    });

    let queue = []
    dtos.forEach((dto) => {
        try {
            const cacheTalk = global.talkData.filter((talk) => talk.talkId === dto.talkId)[0];

            const newMsg = dto.talkMessages.talks;
            console.log(newMsg)
            if (newMsg.length > 0) {
                newMsg.forEach((msg) => {
                    msg.workNm = cacheTalk.work.workNm
                })
                cacheTalk.lastMessage = newMsg[newMsg.length - 1].message;
                cacheTalk.lastMessageDate = newMsg[newMsg.length - 1].insDate;
                // 톡방 접속중인 경우 메시지 맵핑
                if (localStorage.getItem(global.tabId) === cacheTalk.talkId) {
                    messageMapping(cacheTalk.talkId, {talks: newMsg}, 'after', false)
                    // 브라우저 상태가 hidden 인 경우 알림에 추가
                    if (!document.hasFocus()) queue = [...queue, ...newMsg]
                    // 그외 메시지 재정의
                } else {
                    cacheTalk.talkMessages.talks = [...newMsg, ...cacheTalk.talkMessages.talks]
                    cacheTalk.unReadCnt = cacheTalk.unReadCnt + newMsg.length;
                    queue = [...queue, ...newMsg]
                }
            }
        } catch (e) {
            console.log(`talk.talkId is null messages`)
        }
    })

    // 추가된 큐가 존재 할시 톡방 저체 갱신
    // 큐에 정의된 메시지를 알림
    if (queue.length > 0) {
        talkMapping(global.talkData);
        talkEvent.badgeChange();
        queue.forEach((que) => {
            showNotification(que)
        })
    }
}

// 톡방 내용 가져오기
const getMoreMessageLine = (talkId) => {
    const cacheTalk = global.talkData.filter((talk) => talk.talkId === talkId)[0];
    cacheTalk.messageParams['insDate'] = cacheTalk.talkMessages.talks[cacheTalk.talkMessages.talks.length - 1].insDate;
    return new Promise((resolve, reject) => {
        global.request({
            url: `/api/message/line`,
            method: 'get',
            params: cacheTalk.messageParams,
            withCredentials: true
        }).then((dto) => {
            if (dto.talks.length > 0) {
                messageMapping(talkId, dto, 'before', false);
                talkEvent.messageScrollOriginalPositionMove();
                let result = '';
                if (cacheTalk.talkMessages.talks.length >= dto.total) {
                    result = 'last';
                } else {
                    result = 'success';
                }

                HubEvent.send(global.talkParams({
                    type: 'MORE_MESSAGE_LINE',
                    talkId: talkId,
                    tabId: global.tabId,
                    result: result,
                    talkMessages: dto
                }))
                resolve(result)
            } else {
                resolve('last');
            }

        }).catch(function (error) {
            reject(error)
        })
    })
}

// 톡방내 메시지 검색
const getMessageSearch = (params) => {
    global.request({
        url: `/api/message/search`,
        method: 'get',
        params: {talkId: params.talkId, search: params.search},
        withCredentials: true
    }).then((lists) => {
        params.callback(lists)
    })
}


// 메시지 통합 검색
const getAllContentSearch = (params) => {
    global.request({
        url: `/api/message/search/all`,
        method: 'get',
        params: {search: params.search},
        withCredentials: true,
    }).then((lists) => {
        params.callback(lists)
    })
}

//매뉴얼 조회
const getManual = (params) => {
    const sendParam = {type: params.type}
    if(params.search !== '') sendParam['search'] = params.search
    if(params.workId !== '') sendParam['workId'] = params.workId
    global.request({
        url: `/api/manual`,
        method: 'get',
        params: sendParam,
        withCredentials: true
    }).then((manuals) => {
        params.callback(manuals)
    })
}


//매뉴얼 조회
const getVideoManual = (params) => {
    const sendParam = {type: params.type}
    if(params.search !== '') sendParam['search'] = params.search
    if(params.workId !== '') sendParam['workId'] = params.workId
    global.request({
        url: `/api/manual/video`,
        method: 'get',
        params: sendParam,
        withCredentials: true
    }).then((manuals) => {
        params.callback(manuals)
    })
}

// 톡방 삭제 (실제 삭제 여부만 갱신)
const deleteTalk = (params) => {
    global.request({
        url: `/api/talk/delete/${params.talkId}`,
        method: 'put',
        withCredentials: true
    }).then((data) => {
        params.callback(data)
    })
}

// 톡방 읽음 표시
const setChatRead = (talkId) => {
    console.log('read', talkId)
    return new Promise((resolve, reject) => {
        global.request({
            url: `/api/message/read`,
            method: 'post',
            body: {talkId: talkId},
            withCredentials: true
        }).then((result) => {
            resolve(result);

        }).catch((err) => {
            reject(err);
        })
    })

}

// 톡방 보관
const setTalkMark = (obj) => {
    global.request({
        url: `/api/talk/mark/${obj.talkId}`,
        method: 'put',
        withCredentials: true
    }).then(() => {
        obj.callback()
    })
}


export {
    talkInit,
    getUser,
    getApInfo,
    getTalkList,
    getTalkListEvent,
    setChatList,
    getMessage,
    getMoreMessageLine,
    getMessageSearch,
    getAllContentSearch,
    getManual,
    getVideoManual,
    setChatRead,
    setTalkMark,
    setITSMSatis,
    setSCMSatis,
    deleteTalk,
    getMessageAll,
    getMoreMessageAll
}