// 공통 유틸

import {global} from "http://devtalk.kospo.co.kr:3000/static/js/module/variable.js";

let masterVar = false;
const Common = {
    isMasterVar : () => {
        return masterVar;
    },
    sleep: (delay) => {
        return new Promise(resolve => setTimeout(resolve, delay));
    },
    nowDateDifference: (date1) => {
        // date1과 date2 문자열을 Date 객체로 변환합니다.
        const now = new Date();
        const midNow = new Date(`${now.getFullYear()}-${now.getMonth() + 1}-${now.getDate() + 1}`);
        // 두 날짜 간의 시간 차이를 밀리초 단위로 계산합니다.
        let diffTime = midNow.getTime() - date1.getTime();

        // 밀리초를 일 단위로 변환합니다.
        let diffDays = diffTime / (1000 * 60 * 60 * 24);

        // 일수 차이를 반환합니다.
        return diffDays;
    },
    dateDifference: (date1, date2) => {
        // date1과 date2 문자열을 Date 객체로 변환합니다.
        // 두 날짜 간의 시간 차이를 밀리초 단위로 계산합니다.
        let diffTime = date1.getTime() - date2.getTime();

        // 일수 차이를 반환합니다.
        return diffTime > 0;
    },
    dateWithNanos: (date) => {
        const year = date.getFullYear();
        const month = String(date.getMonth() + 1).padStart(2, '0');
        const day = String(date.getDate()).padStart(2, '0');
        const hour = String(date.getHours()).padStart(2, '0')
        const minutes = String(date.getMinutes()).padStart(2, '0')
        const seconds = String(date.getSeconds()).padStart(2, '0')

        const millisNanos = String(date.getMilliseconds()).padStart(3, '0')
        const additionalNanos = String(Math.floor(Math.random() * 999)).padStart(3, '0');

        return `${year}-${month}-${day} ${hour}:${minutes}:${seconds}.${millisNanos}${additionalNanos}`

    },
    getAttachVnm: (date, tabId) => {
        const year = date.getFullYear();
        const month = String(date.getMonth() + 1).padStart(2, '0');
        const day = String(date.getDate()).padStart(2, '0');
        const hour = String(date.getHours()).padStart(2, '0')
        const minutes = String(date.getMinutes()).padStart(2, '0')
        const seconds = String(date.getSeconds()).padStart(2, '0')

        const millisNanos = String(date.getMilliseconds()).padStart(3, '0')
        const nanoSecond = Math.round(Math.random() * 999).toString().padEnd(3, '0')


        return `${year}${month}${day}${hour}${minutes}${seconds}${millisNanos}${nanoSecond}_${tabId}`

    },
    nowDate: () => {
        // 날짜 포맷터 생성
        const dateFormatter = new Intl.DateTimeFormat('ko-KR', {
            year: 'numeric',
            month: '2-digit',
            day: '2-digit',
            hour: '2-digit',
            minute: '2-digit',
            second: '2-digit',
            hour12: false
        });


        // 날짜와 시간 포맷팅
        const parts = dateFormatter.formatToParts(now);

        // 원하는 형식으로 조합
        let formattedDate = '';
        let datePart = '';
        let timePart = '';

        parts.forEach(({type, value}) => {
            switch (type) {
                case 'year':
                case 'month':
                case 'day':
                    datePart += (type === 'year' ? value : '-' + value.padStart(2, '0'));
                    break;
                case 'hour':
                case 'minute':
                case 'second':
                    timePart += (timePart ? ':' : '') + value.padStart(2, '0');
                    break;
            }
        });

        formattedDate = `${datePart} ${timePart}`;

        return formattedDate;
    },
    //대화방 리스트에서 사용
    talkListDateFormat: (str) => {
        const convertDate = new Date(str);
        let formatOptions;
        let prefix = '';
        const diffDay = Common.nowDateDifference(convertDate);
        if (diffDay > 0 && diffDay <= 1) {
            formatOptions = {
                // year: 'numeric',
                // month: '2-digit',
                // day: '2-digit',
                hour: '2-digit',
                minute: '2-digit',
                // second: '2-digit',
                hour12: false
            }
            prefix = ''
        } else if (diffDay > 1 && diffDay <= 2) {
            formatOptions = {
                // year: 'numeric',
                // month: '2-digit',
                // day: '2-digit',
                hour: '2-digit',
                minute: '2-digit',
                // second: '2-digit',
                hour12: false
            }

            prefix = '어제 '
        } else {
            formatOptions = {
                year: 'numeric',
                month: '2-digit',
                day: '2-digit',
                // hour: '2-digit',
                // minute: '2-digit',
                // second: '2-digit',
                hour12: false
            }

        }

        // 날짜 포맷터 생성
        const dateFormatter = new Intl.DateTimeFormat('ko-KR', formatOptions);


        // 날짜와 시간 포맷팅
        const parts = dateFormatter.formatToParts(convertDate);

        // 원하는 형식으로 조합
        let formattedDate = '';
        let datePart = '';
        let timePart = '';

        parts.forEach(({type, value}) => {
            switch (type) {
                case 'year':
                case 'month':
                case 'day':
                    datePart += (type === 'year' ? value : '-' + value.padStart(2, '0'));
                    break;
                case 'hour':
                    timePart += (parseInt(value) > 12 ? '오후 ' : '오전 ') + (timePart ? ':' : '') + (parseInt(value) > 12 ? parseInt(value) % 12 : parseInt(value));
                    break;
                case 'minute':
                case 'second':
                    timePart += (timePart ? ':' : '') + value.padStart(2, '0');
                    break;
            }
        });

        formattedDate = `${prefix}${prefix !== '' ? '' : datePart} ${prefix !== '' ? '' : timePart}`;

        return formattedDate;
    },
    //대화방 글작성시 사용
    talkDateFormat: (str) => {
        // 문자열을 Date 객체로 변환
        const date = new Date(str);

        // 시간을 가져옴
        let hours = date.getHours();
        const minutes = date.getMinutes();

        // 오전/오후 결정
        const ampm = hours >= 12 ? '오후' : '오전';

        // 12시간 형식으로 변환
        hours = hours % 12;
        hours = hours ? hours : 12; // 0시를 12시로 표시

        // 분이 한 자리 수일 경우 앞에 0을 붙임
        const minutesStr = minutes < 10 ? '0' + minutes : minutes;

        // 최종 형식으로 조합
        return `${ampm} ${hours}:${minutesStr}`;
    },
    dayOfWeek: (yyyymmdd) => {
        const dow = new Date(yyyymmdd).getDay();
        const week = {
            '0': '일',
            '1': '월',
            '2': '화',
            '3': '수',
            '4': '목',
            '5': '금',
            '6': '토',
        }
        return `${yyyymmdd} (${week[dow]})`;
    },
    nullCheck: (value) => {
        let result = value;
        if (value === undefined || value === null) {
            result = ''
        }

        return result;
    },
    fileToBase64: async (file) => {
        const reader = new FileReader();
        let result;
        reader.readAsDataURL(file)
        reader.onload = async () => {
            result = await reader.result
        }

        return result
    },
    cropImage: (image, size) => {
        const widthRatio = size / image.width;
        const heightRatio = size / image.height;
        const ratio = Math.max(widthRatio, heightRatio);

        const newWidth = image.width * ratio;
        const newHeight = image.height * ratio;
        return new Promise((resolve, reject) => {
            // 썸네일 생성
            const canvas = document.createElement('canvas');
            canvas.width = newWidth;
            canvas.height = newHeight;
            const ctx = canvas.getContext('2d');

            // 이미지 크기 조정 및 그리기 (Bicubic과 같은 고품질 스케일링)
            ctx.imageSmoothingEnabled = true;
            ctx.imageSmoothingQuality = 'high';

            ctx.drawImage(image, 0, 0, newWidth, newHeight);

            resolve(canvas.toDataURL());
        });
    },
    mergeObject: (target, source) => {
        for(let key in source) {
            if(source[key] instanceof Object) {
                target[key] = Object.assign({}, Common.mergeObject(source[key], target[key]))
            }

            target = Object.assign({},  source, target);
        }
        return target;
    },
    addDelegatedEventListener: (parentElement, eventType, selector, handler) => {
        function elementMatches(el, selector) {
            const matches = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;

            if (matches) {
                return matches.call(el, selector);
            } else {
                // matches 메서드를 지원하지 않는 브라우저를 위한 폴백
                const allElements = el.parentNode.querySelectorAll(selector);
                return Array.prototype.indexOf.call(allElements, el) !== -1;
            }
        }

        parentElement.addEventListener(eventType, function (e) {
            const path = e.composedPath && e.composedPath() || e.path || (function (target) {
                const path = [];
                while (target.parentElement) {
                    path.push(target);
                    target = target.parentElement;
                }
                path.push(document, window);
                return path;
            })(e.target);


            for (let element of path) {
                if (element === parentElement) break;
                if (elementMatches(element, selector)) {
                    const wrappedEvent = new Proxy(e, {
                        get: function (target, prop) {
                            if (prop === 'target' || prop === 'currentTarget') {
                                return element;
                            }
                            if (prop === 'preventDefault') {
                                return () => e.preventDefault();
                            }
                            if (prop === 'stopPropagation') {
                                return () => {
                                    e.stopImmediatePropagation();
                                    e.stopPropagation();
                                };
                            }
                            if (typeof target[prop] === 'function') {
                                return target[prop].bind(target);
                            }
                            return target[prop];
                        }
                    });

                    const result = handler.call(element, wrappedEvent);

                    if (result === false) {
                        e.preventDefault();
                        e.stopImmediatePropagation();
                        e.stopPropagation();
                    }

                    if (wrappedEvent.defaultPrevented) {
                        e.preventDefault();
                    }

                    break;
                }
            }
        }, true);
    },
    findParentElement: (node, parentClass) => {
        let pa = node.parentElement;
        if(pa === null) {
            return null;
        } else {
            if (pa.classList.contains(parentClass)) {
                return pa;
            } else {
                return Common.findParentElement(pa, parentClass)
            }
        }

    },
    getListening: (talkId) => {
        const xhr = new XMLHttpRequest();
        xhr.open('GET', `${global.apiUrl}/api/user/listening?talkId=${talkId}`, false);
        xhr.withCredentials = true;
        xhr.send();

        if(xhr.status === 200) {
            console.log(xhr.responseText)
            return Number(xhr.responseText);
        }
    },
    setListening: (talkId, status) => {
        const xhr = new XMLHttpRequest();
        xhr.open('POST', `${global.apiUrl}/api/user/listening`, false);
        xhr.withCredentials = true;
        xhr.setRequestHeader("content-type", "application/json")
        xhr.send(JSON.stringify({"talkId":talkId, "status":status}));

        if(xhr.status === 200) {
            console.log(xhr.responseText)
        }
    },
    isMaster() {
        try {
            return global.stomp.connected;
        } catch(e) {
            return false;
        }
    },
    setCookie: (key, value) => {
        document.cookie = `${key}=${value};Path=/;domain=.kospo.co.kr`
    },
    getCookie: (key) => {
        const value = document.cookie.match('(^|;) ?' + key + '=([^;]*)(;|$)');
        return value ? value[2] : null;
    }

}


export default Common;