import PinYin from "./pinyin";

export const html2Text = (html) => {
	if (!html) {
		return "";
	}
	return html
		.replace(/<\/p><p>/g, "\n")
		.replace(/\&nbsp;/g, " ")
		.replace(/<p>/g, "")
		.replace(/<\/p>/g, "")
		.replace(/<br>/g, "")
		.trim();
};

export const parseBr = (content) => {
	if (!content) {
		return "";
	}
	return content.replace(/\n/g, "\\n").trim();
};

export const getEl = (el) => {
	return new Promise((resolve) => {
		const query = uni.createSelectorQuery().in(this);
		query
			.select(el)
			.boundingClientRect((data) => {
				// 存在data，且存在宽和高，视为渲染完毕
				resolve(data);
			})
			.exec();
	});
};

export const getDbDir = () => {
	const userID = uni.getStorageSync("IMUserID");
	return new Promise((resolve, reject) => {
		plus.io.requestFileSystem(plus.io.PRIVATE_DOC, (fs) => {
			fs.root.getDirectory(
				userID ? userID : "user", {
					create: true,
				},
				(entry) => {
					resolve(entry.fullPath);
				},
				(error) => {
					reject(error);
				},
			);
		});
	});
};
export const formatIndexListData = (list, key = "nickname") => {
	// 兼容：list 为数组，数组元素可以是字符串或对象；key 为要分组的字段名（若元素为字符串则忽略 key）
	if (!Array.isArray(list) || list.length === 0) return [];

	const ucfirst = (l1) => {
		if (!l1) return "";
		if (l1.length > 0) {
			var first = l1.substr(0, 1).toUpperCase();
			var spare = l1.substr(1, l1.length);
			return first + spare;
		}
		return l1;
	};

	const arraySearch = (l1) => {
		for (var name in PinYin) {
			if (PinYin[name].indexOf(l1) != -1) {
				return ucfirst(name);
			}
		}
		return false;
	};

	// 将字符串转为可排序的拼音/字母表示
	const codefans = (l1) => {
		l1 = l1 ?? "";
		var l2 = l1.length;
		var I1 = "";
		var reg = new RegExp("[a-zA-Z0-9- ]");
		for (var i = 0; i < l2; i++) {
			var val = l1.substr(i, 1);
			var name = arraySearch(val);
			if (reg.test(val)) {
				I1 += val;
			} else if (name !== false) {
				I1 += name;
			}
		}
		I1 = I1.replace(/ /g, "-");
		while (I1.indexOf("--") > 0) {
			I1 = I1.replace("--", "-");
		}
		return I1;
	};

	// 构建分组 map
	const groups = {};
	for (let i = 0; i < list.length; i++) {
		const item = list[i];
		const val = (typeof item === "string") ? item : (item && item[key]) ? item[key] : "";
		const coded = codefans(String(val));
		let initial = (coded && coded.length > 0) ? coded.substr(0, 1).toUpperCase() : "#";
		if (!/^[A-Z]$/.test(initial)) initial = "#";
		if (!groups[initial]) groups[initial] = [];
		groups[initial].push({
			raw: item,
			sortKey: coded || String(val)
		});
	}

	// 按字母顺序构建结果，A-Z 然后 #
	const letters = Object.keys(groups).filter((l) => l !== "#").sort();
	const result = [];
	for (const L of letters) {
		// 组内按照 sortKey 排序
		groups[L].sort((a, b) => {
			if (a.sortKey < b.sortKey) return -1;
			if (a.sortKey > b.sortKey) return 1;
			return 0;
		});
		result.push({
			letter: L,
			data: groups[L].map((x) => x.raw)
		});
	}
	// 特殊字符组放最后
	if (groups["#"] && groups["#"].length > 0) {
		groups["#"].sort((a, b) => {
			if (a.sortKey < b.sortKey) return -1;
			if (a.sortKey > b.sortKey) return 1;
			return 0;
		});
		result.push({
			letter: "#",
			data: groups["#"].map((x) => x.raw)
		});
	}

	return result;
}

export const formatChooseData = (data, key = "nickname") => {
	const ucfirst = (l1) => {
		if (l1.length > 0) {
			var first = l1.substr(0, 1).toUpperCase();
			var spare = l1.substr(1, l1.length);
			return first + spare;
		}
	};

	const arraySearch = (l1, l2) => {
		for (var name in PinYin) {
			if (PinYin[name].indexOf(l1) != -1) {
				return ucfirst(name);
				break;
			}
		}
		return false;
	};

	const codefans = (l1) => {
		l1 = l1 ?? "unkown";
		var l2 = l1.length;
		var I1 = "";
		var reg = new RegExp("[a-zA-Z0-9- ]");
		for (var i = 0; i < l2; i++) {
			var val = l1.substr(i, 1);
			var name = arraySearch(val, PinYin);
			if (reg.test(val)) {
				I1 += val;
			} else if (name !== false) {
				I1 += name;
			}
		}
		I1 = I1.replace(/ /g, "-");
		while (I1.indexOf("--") > 0) {
			I1 = I1.replace("--", "-");
		}
		return I1;
	};

	var arr = [],
		firstName;

	for (var i = 0; i < data.length; i++) {
		firstName = data[i].initial = codefans(data[i][key]).substr(0, 1);
		arr.push(firstName.toUpperCase());
	}

	var arrlist = [];
	for (i = 0; i < arr.length; i++) {
		if (arrlist.indexOf(arr[i]) == -1) {
			arrlist.push(arr[i]);
		}
	}

	var dataSort = [];
	for (var i = 0; i < arrlist.length; i++) {
		dataSort[i] = {
			initial: arrlist[i],
		};
		dataSort[i].data = [];
		for (var j = 0; j < data.length; j++) {
			if (data[j].initial.toUpperCase() == dataSort[i].initial) {
				dataSort[i].data.push(data[j]);
			}
		}
	}
	for (var i = 0; i < dataSort.length - 1; i++) {
		for (var j = 1; j < dataSort.length - i; j++) {
			if (dataSort[j - 1].initial > dataSort[j].initial) {
				var a = dataSort[j];
				dataSort[j] = dataSort[j - 1];
				dataSort[j - 1] = a;
			}
		}
	}
	const NomalInitial = "QWERTYUIOPLKJHGFDSAZXCVBNM".split("");
	const special = {
		initial: "#",
		data: [],
	};
	const newFilterData = dataSort.filter((d) => {
		if (!NomalInitial.includes(d.initial)) {
			special.data = [...special.data, ...d.data];
		} else {
			return d;
		}
	});
	if (special.data.length > 0) {
		newFilterData.push(special);
	}
	const indexList = newFilterData.map((item) => item.initial);
	const dataList = newFilterData.map((item) => item.data);
	return {
		indexList,
		dataList,
	};
};

export const getPurePath = (path) => {
    if(!path)return "";
	const prefix = "file://";
	const relativeRrefix = "_doc/";
	if (path.includes(prefix)) {
		path = path.replace(prefix, "");
	}
	if (path.includes(relativeRrefix)) {
		path = plus.io.convertLocalFileSystemURL(path);
	}
	return path;
};

export const filterEmptyValue = (obj) => {
	for (let key in obj) {
		if (obj[key] === "") {
			delete obj[key];
		}
	}
};

export const toastWithCallback = (message, callBack, duration = 1000) => {
	uni.$u.toast(message);
	setTimeout(callBack, duration);
};

export const checkLoginError = (error) => {
	if (error?.msg) {
		return error.msg
	}
	if (!error?.errCode) {
		return "操作失败";
	}
	switch (error.errCode) {
		case 20001:
			return "密码错误";
		case 20002:
			return "账号不存在";
		case 20003:
			return "手机号已经注册";
		case 20004:
			return "账号已注册";
		case 20005:
			return "操作过于频繁，请稍后再试";
		case 20006:
			return "验证码错误";
		case 20007:
			return "验证码过期";
		case 20008:
			return "验证码错误次数超过限制，请稍后再试";
		case 20009:
			return "验证码已被使用";
		case 20010:
			return "邀请码已被使用";
		case 20011:
			return "邀请码不存在";
		case 20012:
			return "操作限制";
		case 20014:
			return "账号已注册";
		default:
			return "操作失败";
	}
};


// 删除本地文件，适配 plus 环境
export const deleteLocalFile = (path) => {
	return new Promise((resolve) => {
		if (!path) return resolve();
		if (typeof plus === 'undefined') return resolve();

		// 尝试直接用 resolveLocalFileSystemURL，如果失败再尝试加 file:// 前缀
		const tryRemove = (p) => {
			plus.io.resolveLocalFileSystemURL(p, function(entry) {
				entry.remove(function() {
					resolve();
				}, function(err) {
					console.log('deleteLocalFile remove error:', err);
					resolve();
				});
			}, function(err) {
				resolve(err);
			});
		};

		tryRemove(path);
	});
};
export const getVideoCover = (videoPath, frameIndex, callback) => {
    // 兼容性：如果传入 callback，则函数立即返回空串，并在回调中返回路径；
    // 如果不传 callback，则返回 Promise<string>（兼容旧用法）。

    // 简单字符串哈希，用于生成固定缩略图文件名
    const _hash = (s) => {
        let h = 2166136261;
        for (let i = 0; i < s.length; i++) {
            h ^= s.charCodeAt(i);
            h = Math.imul(h, 16777619);
        }
        return (h >>> 0).toString(16);
    };

    const run = async () => {
        if (!videoPath) return "";

        // 生成固定的缩略图路径（基于 videoPath 哈希）
        let coverRel = null;
        try {
            const key = _hash(String(videoPath));
            coverRel = `_doc/video_cover_${key}.jpg`;
            const coverAbs = typeof plus !== 'undefined' && plus.io ? plus.io.convertLocalFileSystemURL(coverRel) : null;

            // 如果已存在，直接返回
            if (typeof plus !== 'undefined' && plus.io) {
                try {
                    const exists = await new Promise((res) => {
                        plus.io.resolveLocalFileSystemURL(coverRel, function(entry) { res(true); }, function() { res(false); });
                    });
                    if (exists) return coverAbs;
                } catch (e) {
                    // ignore and continue
                }
            }
        } catch (e) {
            // ignore and continue
            coverRel = null;
        }

        // 1. Native plus 方式尝试
        if (typeof plus !== "undefined" && plus.io) {
            try {
                // 规范路径（若有可用转换函数）
                if (typeof getUniversalVideoPath === 'function') {
                    try { videoPath = await getUniversalVideoPath(videoPath); } catch (e) {}
                }

                // 尝试 Android 原生 MediaMetadataRetriever 提取帧
                if (plus.android) {
                    try {
                        var MediaMetadataRetriever = plus.android.importClass('android.media.MediaMetadataRetriever');
                        var retriever = new MediaMetadataRetriever();
                        var setDataSourcePath = videoPath;
                        if (typeof setDataSourcePath === 'string' && setDataSourcePath.indexOf('file://') === 0) {
                            setDataSourcePath = setDataSourcePath.replace('file://', '');
                        }
                        var _setOk = false;
                        try { retriever.setDataSource(setDataSourcePath); _setOk = true; } catch (sdErr) {
                            try {
                                var UriClass = plus.android.importClass('android.net.Uri');
                                var uriObj = UriClass.parse(videoPath);
                                var activity = plus.android.runtimeMainActivity();
                                retriever.setDataSource(activity, uriObj);
                                _setOk = true;
                            } catch (sd2Err) {}
                        }

                        var timeUs = (typeof frameIndex === 'number' && frameIndex >= 0) ? Math.floor(frameIndex * 1000000) : 0;
                        var bitmap = null;
                        try { bitmap = retriever.getFrameAtTime(timeUs); } catch (gfErr) {}
                        if (!bitmap) {
                            try { bitmap = retriever.getFrameAtTime(-1); } catch (e2) {}
                        }
                        if (!bitmap) {
                            try { bitmap = retriever.getFrameAtTime(1000000); } catch (e3) {}
                        }

                        if (bitmap) {
                            try {
                                var CompressFormat = plus.android.importClass('android.graphics.Bitmap$CompressFormat');
                                var ByteArrayOutputStream = plus.android.importClass('java.io.ByteArrayOutputStream');
                                var baos = new ByteArrayOutputStream();
                                plus.android.invoke(bitmap, 'compress', CompressFormat.JPEG, 80, baos);
                                var bytes = plus.android.invoke(baos, 'toByteArray');

                                // 写入到固定路径（如果 coverRel 可用）
                                var tempRel = coverRel || ('_doc/video_cover_' + Date.now() + '.jpg');
                                var tempAbs = plus.io.convertLocalFileSystemURL(tempRel);
                                var tempForJava = tempAbs;
                                if (typeof tempForJava === 'string' && tempForJava.indexOf('file://') === 0) tempForJava = tempForJava.replace('file://', '');
                                var FileOutputStream = plus.android.importClass('java.io.FileOutputStream');
                                var fos = new FileOutputStream(tempForJava);
                                plus.android.invoke(fos, 'write', bytes);
                                plus.android.invoke(fos, 'close');
                                try { retriever.release(); } catch (e) {}
                                return tempAbs;
                            } catch (writeErr) {
                                try { retriever.release(); } catch (e) {}
                            }
                        } else {
                            try { retriever.release(); } catch (e) {}
                        }
                    } catch (mmrErr) {}
                }

                // 兼容：尝试 plus.getVideoAttributes
                if (typeof plus.getVideoAttributes === "function") {
                    try {
                        const attr = await new Promise((res, rej) => {
                            plus.getVideoAttributes(videoPath, function(info) { res(info && info.path ? info.path : info); }, function(err) { rej(err); });
                        });
                        if (attr) return attr;
                    } catch (e) {}
                }
            } catch (e) {}
        }

        // 3. H5 capture via video+canvas（在 native 的 WebView 中也可以运行）
        if (typeof document !== "undefined") {
            try {
                const dataUrl = await new Promise((resolve) => {
                    const video = document.createElement('video');
                    video.crossOrigin = 'anonymous';
                    video.src = videoPath;
                    video.muted = true;
                    video.playsInline = true;

                    const onError = () => { cleanup(); resolve(''); };
                    const onLoaded = () => {
                        try {
                            const targetTime = (typeof frameIndex === 'number' && frameIndex >= 0) ? Math.min(video.duration, frameIndex) : Math.min(1, Math.max(0, video.duration / 2));
                            video.currentTime = targetTime;
                        } catch (err) {}
                        setTimeout(() => {
                            try {
                                const canvas = document.createElement('canvas');
                                canvas.width = video.videoWidth || 320;
                                canvas.height = video.videoHeight || 240;
                                const ctx = canvas.getContext('2d');
                                ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
                                const data = canvas.toDataURL('image/jpeg', 0.8);
                                cleanup();
                                resolve(data || '');
                            } catch (err) { cleanup(); resolve(''); }
                        }, 400);
                    };
                    const cleanup = () => { video.removeEventListener('loadeddata', onLoaded); video.removeEventListener('error', onError); };
                    video.addEventListener('loadeddata', onLoaded);
                    video.addEventListener('error', onError);
                });

                if (!dataUrl) return '';

                if (typeof plus !== 'undefined' && plus.io) {
                    try {
                        const base64Data = dataUrl.split(',')[1];
                        const bytes = atob(base64Data);
                        const buf = new ArrayBuffer(bytes.length);
                        const arr = new Uint8Array(buf);
                        for (let i = 0; i < bytes.length; i++) arr[i] = bytes.charCodeAt(i);
                        const tempRel = coverRel || ('_doc/video_cover_' + Date.now() + '.jpg');
                        const tempAbs = plus.io.convertLocalFileSystemURL(tempRel);
                        await new Promise((res, rej) => {
                            plus.io.resolveLocalFileSystemURL(tempRel, function(fentry) {
                                fentry.createWriter(function(writer) {
                                    writer.onwrite = function() { res(tempAbs); };
                                    writer.onerror = function(e) { rej(e); };
                                    writer.write(arr.buffer);
                                }, function(e) { rej(e); });
                            }, function() {
                                plus.io.requestFileSystem(plus.io.PRIVATE_DOC, function(fs) {
                                    fs.root.getFile(tempRel, {create: true}, function(fentry) {
                                        fentry.createWriter(function(writer) { writer.onwrite = function() { res(tempAbs); }; writer.onerror = function(e) { rej(e); }; writer.write(arr.buffer); }, rej);
                                    }, rej);
                                }, rej);
                            });
                        });
                        return tempAbs;
                    } catch (e) { return dataUrl; }
                }
                return dataUrl;
            } catch (e) {}
        }

        return '';
    };

    if (typeof callback === 'function') {
        run().then((p) => { try { callback(p); } catch (e) {} }).catch(() => { try { callback(''); } catch (e) {} });
        return "";
    }

    return run();
};

export const getVideoInfo = async (src)=>{
    return await new Promise((resolve,reject)=>{
        uni.getVideoInfo({
            src:src,
            success(res){
                resolve(res)
            },fail(error){
                reject(error)
            }
        })  
    });
}
