import { message } from 'antd';
import { RcFile } from 'antd/lib/upload';
import { parse } from 'querystring';

/* eslint no-useless-escape:0 import/prefer-default-export:0 */
const reg = /(((^https?:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)$/;

export const isUrl = (path: string): boolean => reg.test(path);

export const isAntDesignPro = (): boolean => {
    if (ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION === 'site') {
        return true;
    }
    return window.location.hostname === 'preview.pro.ant.design';
};

// 给官方演示站点用，用于关闭真实开发环境不需要使用的特性
export const isAntDesignProOrDev = (): boolean => {
    const { NODE_ENV } = process.env;
    if (NODE_ENV === 'development') {
        return true;
    }
    return isAntDesignPro();
};

export const getPageQuery = () => {
    const { href } = window.location;
    const qsIndex = href.indexOf('?');
    const sharpIndex = href.indexOf('#');

    if (qsIndex !== -1) {
        if (qsIndex > sharpIndex) {
            return parse(href.split('?')[1]);
        }

        return parse(href.slice(qsIndex + 1, sharpIndex));
    }

    return {};
};

// 排序这是比较函数
export const compare = (field: string, order: 'descend' | 'ascend') => {
    // descend 降序 大到小  ascend 升序 小到大
    if (order === 'ascend') {
        return function (m: any, n: any) {
            var a = m[field];
            var b = n[field];
            return a - b; //升序
        }
    } else {
        return function (m: any, n: any) {
            var a = m[field];
            var b = n[field];
            return b - a; //降序
        }
    }
}

// 返回别名
export const getChannelName = (name: string) => {
    let newName = name
    let abridgeServer: string[] = ['知定', '巨网', '广联', '太古', '云广', '傲星', '弘捷', '开域']
    let asName = abridgeServer.find((item: string) => name?.indexOf(item) !== -1)
    if (asName) {
        newName = asName
    } else if (newName?.length > 5) {
        newName = newName?.slice(2, 5) + '...'
    }
    return newName
}


/**
 * 转正则
 * @param arr 
 * @returns 
 */
function arrayToRegex(arr: string[]) {
    // 转义正则表达式中的特殊字符
    function escapeRegExp(str: string) {
        return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
    }

    // 将数组中的每个元素用括号包裹，并用 | 连接
    const regexString = arr.map(item => `(${escapeRegExp(item)})`).join('|');

    // 创建正则表达式
    const regex = new RegExp(regexString, 'g');
    return regex;
}

const arr = ['[微笑]', '[撇嘴]', '[色]', '[发呆]', '[流泪]', '[害羞]', '[睡]', '[大哭]', '[尴尬]', '[发怒]', '[调皮]', '[呲牙]', '[惊讶]', '[难过]', '[冷汗]', '[抓狂]', '[偷笑]', '[愉快]', '[白眼]', '[傲慢]', '[惊恐]', '[流汗]', '[憨笑]', '[奋斗]', '[疑问]', '[晕]', '[衰]', '[敲打]', '[再见]', '[擦汗]', '[鼓掌]', '[坏笑]', '[左哼哼]', '[右哼哼]', '[哈欠]', '[委屈]', '[快哭了]', '[阴险]', '[亲亲]', '[可怜]', '[西瓜]', '[咖啡]', '[猪头]', '[玫瑰]', '[嘴唇]', '[爱心]', '[蛋糕]', '[月亮]', '[太阳]', '[拥抱]', '[强]', '[胜利]', '[握手]', '[抱拳]', '[勾引]', '[拳头]', '[OK]', '[跳跳]', '[发抖]', '[怄火]', '[转圈]', '[嘿哈]', '[捂脸]', '[奸笑]', '[机智]', '[皱眉]', '[耶]', '[加油]', '[汗]', '[天啊]', '[社会社会]', '[旺柴]', '[好的]', '[加油加油]', '[哇]', '[红包]', '[發]', '[福]'];
export function extractAndFilterBracketsContent(input: string): { extracted: string[], filteredString: string } {
    const regex = arrayToRegex(arr);
    const matches: string[] = [];
    let match;

    // 提取方括号内的内容
    while ((match = regex.exec(input)) !== null) {
        matches.push(match[1]);
    }

    // 过滤掉原字符串中方括号及其包裹的内容
    const filteredString = input.replace(regex, '');

    return { extracted: matches, filteredString: filteredString };
}

// 输入文案时判断
export const txtLength = (t?: string) => {
    if (t) {
        const result = extractAndFilterBracketsContent(t);
        let extracted = result.extracted;
        let value = result.filteredString;
        let length = value?.length
        let text = value?.replace(/[\x00-\xff]/g, '')
        return extracted.length + text?.length + Number(((length - text?.length) / 2).toFixed())
    } else {
        return 0
    }
}

// 返回图片宽高
export const getImgSize = (file: RcFile): Promise<{ width: number, height: number }> => {
    return new Promise((resolve: (value: any) => void, reject: (reason?: any) => void) => {
        if (file) {
            let img: any = new Image();
            let _URL = window.URL || window.webkitURL;
            img.onload = function (e: any) {
                resolve({ width: this.width, height: this.height })
            }
            img.src = _URL.createObjectURL(file);
        } else {
            reject()
        }
    })
}

// 返回落地页组件key
export const getTypeKey = (key: string): string => {
    switch (key) {
        case 'TOP_IMAGE':
            return 'topImageSpec'
        case 'TOP_SLIDER':
            return 'topSliderSpec'
        case 'TOP_VIDEO':
            return 'topVideoSpec'
        case 'IMAGE':
            return 'imageSpec'
        case 'TEXT':
            return 'textSpec'
        case 'GH':
            return 'ghSpec'
        case 'ENTERPRISE_WX':
            return 'enterpriseWxSpec'
        case 'IMAGE_TEXT':
            return 'imageTextSpec'
        case 'FLOAT_BUTTON':
            return 'floatButtonSpec'
    }
    return ''
}

// 点击复制
export const copy = (str: string) => {
    let element = document.createElement("textarea");
    element.id = 'myTextarea'
    element.textContent = str
    document.body.append(element);
    (document.getElementById('myTextarea') as any).select();
    document.execCommand("Copy")
    document.body.removeChild(element);
    message.success(`复制成功：${str}`)
}

// 数组分组
export const groupBy = (array: any[], f: (item: any) => any[], isObject?: boolean) => {
    const groups: any = {};
    array.forEach(function (o) { //注意这里必须是forEach 大写
        const group = JSON.stringify(f(o));
        groups[group] = groups[group] || [];
        groups[group].push(o);
    });
    if (isObject) {
        return groups
    }
    return Object.keys(groups).map(function (group) {
        return groups[group];
    });
}

export const replaceSpecialTxt = (text: string | number | null | undefined) => {
    if (text) {
        return text.toString().replace(/[<>]/ig, '')
    } else {
        return text
    }
}

/**
 * 随机生成字符串
 * @param flag 
 * @param min 
 * @param max 
 * @returns string
 */
export const randomString = (flag: boolean, min: number, max: number) => {
    let str = "", range = min
    let arr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
    if (flag) {
        range = Math.round(Math.random() * (max - min)) + min;
    }
    for (let i = 0; i < range; i++) {
        let pos = Math.round(Math.random() * (arr.length - 1));
        str += arr[pos];
    }
    return str;
}


/**
 * 找2个数组不同元素
 * @param arr1 
 * @param arr2 
 * @returns 
 */
export const getArrDifference = (arr1: any[], arr2: any[]) => {
    return arr1.concat(arr2).filter((v, i, arr) => {
        return arr.indexOf(v) === arr.lastIndexOf(v);
    });
}

/**
 * 拼接oss参数获取视频首针图
 * @param videoUrl t_0 0秒的视频截图 t_10000 10秒的视频截图帧
 */
export const getVideoImgUrl = (videoUrl: string) => {
    if (['.mp4', '.swf', '.flv', '.rm', '.ram', '.mov', '.mpg', '.mpeg', '.wmv', '.avi'].some(item => videoUrl.includes(item))) {
        return videoUrl + "?x-oss-process=video/snapshot,t_0,f_jpg,w_0,h_0,m_fast,ar_auto"
    }
    return videoUrl
}

// 设置值
export const setValueAtPath = (path: string, object: { [k: string]: any }, value: any): void => {
    if (path.startsWith('/')) {
        path = path.slice(1);
    }
    let parts = path.split('/');
    let current: { [k: string]: any } = object;
    for (let i = 0; i < parts.length; i++) {
        let part = parts[i];
        if (i === parts.length - 2) {
            let children = current?.['children'] || {}
            children[parts[parts.length - 1]] = value
            current['children'] = children;
            break
        } else {
            if (!(part in current)) {
                current[part] = {};
            }
            current = current[part];
        }
    }
}

/**
 * 处理创意数据
 * @param data 
 * @returns 
 */
export const processData = (data: string | any[]) => {
    let children = [], parentData: { [k: string]: any } = {};
    for (let i = 0; i < data.length; i += 1) {
        let node = data[i];
        if (!(node?.parentName) || node?.parentName === "") {
            parentData[node.name] = {
                ...data[i],
                children: {}
            }
        } else {
            children.push(data[i])
        }
    }
    // console.log('children--->', children)
    let jumpInfo = [], list: any[] = [], left_button: any = {}, right_button: any = {}
    for (let i = 0; i < children.length; i += 1) {
        let node = children[i];
        if (node.parentName) {
            if (node.parentName === "jump_info" && !['/jump_info/page_type', '/jump_info/backups', '/jump_info/page_spec'].includes(node.path)) {
                jumpInfo.push(node)
            } else if (node.parentName === "list") {
                list.push(node)
            } else if (node.parentName === "left_button") {
                left_button[node.name] = node
            } else if (node.parentName === "right_button") {
                right_button[node.name] = node
            } else {
                let c = parentData[node.parentName]
                if (c) {
                    c['children'][node.name] = node
                    parentData[node.parentName] = c
                } else {
                    console.log('空childen-->', node.parentName)
                }
            }
        } else {
            console.log('空node.parentName--->', node)
        }
    }
    if (jumpInfo.length > 0) {
        jumpInfo.forEach(item => {
            if (item.path) {
                setValueAtPath(item.path, parentData, item)
            } else {
                console.log('没有path---->', item)
            }
        })
    }
    if (Object.keys(left_button).length > 0) {
        let children = {
            text: left_button?.text
        }
        let newLeftButton = [{ ...left_button?.jump_info, children }]
        newLeftButton.forEach(item => {
            if (item.path) {
                setValueAtPath(item.path, parentData, item)
            } else {
                console.log('没有path---->', item)
            }
        })
    }
    if (Object.keys(right_button).length > 0) {
        let children = {
            text: right_button?.text
        }
        let newRightButton = [{ ...right_button?.jump_info, children }]
        newRightButton.forEach(item => {
            if (item.path) {
                setValueAtPath(item.path, parentData, item)
            } else {
                console.log('没有path---->', item)
            }
        })
    }
    if (list?.length > 0 && Object.keys(parentData).includes('label')) {
        let l = parentData?.label?.children?.list
        if (l) {
            let lChildren: any = {}
            list.forEach(item => {
                lChildren[item.name] = item
            })
            l = { ...l, children: lChildren }
            parentData.label.children.list = l
        }
    }
    if (list?.length > 0 && Object.keys(parentData).includes('element_story')) {
        let l = parentData?.element_story?.children?.list
        if (l) {
            let lChildren: any = {}
            list.forEach(item => {
                lChildren[item.name] = item
            })
            l = { ...l, children: lChildren }
            parentData.element_story.children.list = l
        }
    }

    if (list?.length > 0 && Object.keys(parentData).includes('image_list')) {
        let l = parentData?.image_list?.children?.list
        if (l) {
            let lChildren: any = {}
            list.forEach(item => {
                lChildren[item.name] = item
            })
            l = { ...l, children: lChildren }
            parentData.image_list.children.list = l
        }
    }

    return parentData;
}

/**
 * 数组叉乘
 * @param arr1 
 * @param arr2 
 * @returns 
 */
export function cartesianProduct<T, U>(arr1: T[], arr2: U[]): [T, U, string][] {
    return arr1.flatMap((d1, index1) => arr2.map((d2, index2) => [d1, d2, `${index1 + 1}_${index2 + 1}`] as [T, U, string]));
}

/**
 * 对比2个数组是否相同，不考虑下表
 * @param arr1 
 * @param arr2 
 * @returns 
 */
export const arraysHaveSameValues = (arr1: any[], arr2: any[]): boolean => {
    // 首先检查数组的长度是否相同
    if (arr1.length !== arr2.length) {
        return false;
    }

    // 使用数组的 sort 方法对两个数组进行排序，然后逐个比较
    const sortedArr1 = [...arr1].sort();
    const sortedArr2 = [...arr2].sort();

    for (let i = 0; i < sortedArr1.length; i++) {
        if (sortedArr1[i] !== sortedArr2[i]) {
            return false;
        }
    }

    return true;
}


/**
 * 定义一个函数，用于将数组平均分配给多个数组
 * @param originalArray 
 * @param numGroups 
 * @returns 
 */
export const distributeArray = (originalArray: any[], numGroups: number): any[][] => {
    // 初始化结果数组，每个子数组为空
    const result: any[][] = Array.from({ length: numGroups }, () => []);
    console.log('result==============>', result)
    // 分配原始数组中的元素到结果数组
    originalArray.forEach((element, index) => {
        result[index % numGroups].push(element);
    });

    return result;
};

/**
 * 数组分组
 * @param arr 
 * @param adLength 
 * @param infoLength 
 * @returns 
 * arr = [1,2,3,4,5,6]
 * groupArr(arr, 2, 2) [[[1,2],[3,4]],[[5,6]]]
 * groupArr(arr, 2, 3) [[[1,2,3],[4,5,6]]]
 * groupArr(arr, 3, 2) [[[1,2],[3,4],[5,6]]]
 */
export function groupArr<T>(arr: T[], adLength: number, infoLength: number): T[][][] {
  // 1. 先按 infoLength 切分
  const infoGroups: T[][] = []
  for (let i = 0; i < arr.length; i += infoLength) {
    infoGroups.push(arr.slice(i, i + infoLength))
  }

  // 2. 如果数量小于等于 adLength，每个单独一组
  if (infoGroups.length <= adLength) {
    return infoGroups.map(g => [g])
  }

  // 3. 轮询分配
  const result: T[][][] = Array.from({ length: adLength }, () => [])

  infoGroups.forEach((group, index) => {
    const target = index % adLength
    result[target].push(group)
  })

  return result
}

/**
 * 随机取几个值
 * @param arr 
 * @param n 
 * @returns 
 */
export function getRandomElements<T>(arr: T[], n: number): T[] {
    if (n > arr.length) {
        throw new RangeError("getRandomElements: more elements taken than available");
    }

    const result: T[] = new Array(n);
    let len: number = arr.length;
    const taken: number[] = new Array(len);

    while (n--) {
        const x: number = Math.floor(Math.random() * len);
        result[n] = arr[x in taken ? taken[x] : x];
        taken[x] = --len in taken ? taken[len] : len;
    }

    return result;
}


/**
 * 打乱数组
 * @param array 
 * @returns 
 */
export function shuffleArray<T>(array: T[]): T[] {
    const shuffled = array.slice();
    for (let i = shuffled.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
    }
    return shuffled;
}

export function chunkArray<T>(array: T[], numChunks: number): T[][] {
    const chunks: T[][] = Array.from({ length: numChunks }, () => []);
    array.forEach((item, index) => {
        chunks[index % numChunks].push(item);
    });
    return chunks;
}
/**
 * 按多少个一组分组
 * @param array 
 * @param chunkSize 
 * @returns 
 */
export function chunkArray1<T>(array: T[], chunkSize: number): T[][] {
    const result: T[][] = [];
    for (let i = 0; i < array.length; i += chunkSize) {
        result.push(array.slice(i, i + chunkSize));
    }
    return result;
}
/**
 * 打乱随机分配数组
 * @param array 
 * @param numChunks 
 * @returns 
 */
export function splitArrayIntoRandomChunks<T>(array: T[], numChunks: number): T[][] {
    const shuffledArray = shuffleArray(array);
    return chunkArray(shuffledArray, numChunks);
}

/**
 * 秒数格式化
 * @param seconds 秒
 * @returns 
 */
export function formatSecondsToTime(seconds: number): string {
    const hours = Math.floor(seconds / 3600);
    const minutes = Math.floor((seconds % 3600) / 60);
    const secs = seconds % 60;

    // 使用 padStart 确保每个部分都是两位数  
    return `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}:${String(secs).padStart(2, '0')}`;
}

/**
 * 文件大小转换
 * @param bytes 
 * @returns 
 */
export function formatBytes(bytes: number) {
    if (bytes < 1048576) { // 1024 * 1024  
        return (bytes / 1024).toFixed(2) + ' KB';
    } else if (bytes < 1073741824) { // 1024 * 1024 * 1024  
        return (bytes / 1048576).toFixed(2) + ' MB';
    } else {
        return (bytes / 1073741824).toFixed(2) + ' GB';
    }
}

/**
 * 下划线转驼峰
 * @param s 
 * @returns 
 */
export const toCamelCase = (s: string): string => {
    return s.replace(/_([a-zA-Z])/g, (_, g1) => g1.toUpperCase());
}