package com.adealink.weparty.util

import net.sourceforge.pinyin4j.PinyinHelper
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination

object PinyinUtils {
    
    // 默认格式配置（使用懒加载）
    val defaultFormat by lazy {
        HanyuPinyinOutputFormat().apply {
            caseType = HanyuPinyinCaseType.LOWERCASE
            toneType = HanyuPinyinToneType.WITHOUT_TONE
            vCharType = HanyuPinyinVCharType.WITH_V
        }
    }
    
    /**
     * 创建自定义格式
     */
    fun createFormat(
        caseType: HanyuPinyinCaseType = HanyuPinyinCaseType.LOWERCASE,
        toneType: HanyuPinyinToneType = HanyuPinyinToneType.WITHOUT_TONE,
        vCharType: HanyuPinyinVCharType = HanyuPinyinVCharType.WITH_V
    ): HanyuPinyinOutputFormat {
        return HanyuPinyinOutputFormat().apply {
            this.caseType = caseType
            this.toneType = toneType
            this.vCharType = vCharType
        }
    }
    
    /**
     * 判断字符是否为汉字
     */
    fun Char.isChinese(): Boolean {
        return this.toString().matches(Regex("[\\u4E00-\\u9FA5]"))
    }
    
    /**
     * 判断字符串是否包含汉字
     */
    fun String.containsChinese(): Boolean {
        return any { it.isChinese() }
    }
    
    /**
     * 获取汉字全拼（带空格分隔）
     * @param chinese 中文字符串
     * @param format 拼音格式，默认使用 defaultFormat
     * @param withSpace 是否用空格分隔每个字的拼音
     */
    @Throws(BadHanyuPinyinOutputFormatCombination::class)
    fun getFullPinyin(
        chinese: String, 
        format: HanyuPinyinOutputFormat = defaultFormat,
        withSpace: Boolean = true
    ): String {
        return buildString {
            chinese.forEachIndexed { index, char ->
                when {
                    char.isChinese() -> {
                        val pinyinArray = PinyinHelper.toHanyuPinyinStringArray(char, format)
                        pinyinArray?.firstOrNull()?.let { pinyin ->
                            append(pinyin)
                            if (withSpace && index < chinese.length - 1) {
                                append(" ")
                            }
                        }
                    }
                    else -> append(char)
                }
            }
        }.trim()
    }
    
    /**
     * 获取汉字全拼（安全版，不抛出异常）
     */
    fun getFullPinyinSafely(
        chinese: String,
        format: HanyuPinyinOutputFormat = defaultFormat,
        withSpace: Boolean = true
    ): String {
        return runCatching {
            getFullPinyin(chinese, format, withSpace)
        }.getOrDefault(chinese)
    }
    
    /**
     * 获取汉字首字母
     */
    @Throws(BadHanyuPinyinOutputFormatCombination::class)
    fun getFirstLetter(
        chinese: String,
        format: HanyuPinyinOutputFormat = defaultFormat
    ): String {
        return buildString {
            chinese.forEach { char ->
                when {
                    char.isChinese() -> {
                        val pinyinArray = PinyinHelper.toHanyuPinyinStringArray(char, format)
                        pinyinArray?.firstOrNull()?.firstOrNull()?.let { firstChar ->
                            append(firstChar)
                        }
                    }
                    else -> append(char)
                }
            }
        }
    }
    
    /**
     * 获取大写首字母（如：北京 -> BJ）
     */
    fun getCapitalLetters(
        chinese: String,
        format: HanyuPinyinOutputFormat = defaultFormat
    ): String {
        return runCatching {
            getFirstLetter(chinese, format)
        }.getOrDefault("").uppercase()
    }
    
    /**
     * 转换为拼音，非汉字保留原字符
     * @param text 输入文本
     * @param keepOriginal 非汉字是否保持原样
     * @param separateWords 是否分词（每个词单独转换）
     */
    fun convertToPinyin(
        text: String,
        format: HanyuPinyinOutputFormat = defaultFormat,
        keepOriginal: Boolean = true,
        separateWords: Boolean = false
    ): String {
        return if (separateWords) {
            // 按词转换（简单分词：按非汉字字符分割）
            text.split(Regex("[^\\u4E00-\\u9FA5]+")).filter { it.isNotEmpty() }
                .joinToString(" ") { word ->
                    getFullPinyinSafely(word, format, withSpace = false)
                }
        } else {
            // 整体转换
            buildString {
                text.forEach { char ->
                    when {
                        char.isChinese() -> {
                            val pinyin = runCatching {
                                PinyinHelper.toHanyuPinyinStringArray(char, format)?.firstOrNull()
                            }.getOrDefault(char.toString())
                            append(pinyin)
                        }
                        keepOriginal -> append(char)
                        // 如果不保留原字符且不是汉字，跳过
                    }
                }
            }
        }
    }
    
    /**
     * 获取拼音首字母分组（用于通讯录）
     */
    fun getPinyinGroup(
        chinese: String,
        format: HanyuPinyinOutputFormat = defaultFormat
    ): Char {
        return runCatching {
            val firstChar = chinese.firstOrNull { it.isChinese() }
            firstChar?.let { 
                val pinyinArray = PinyinHelper.toHanyuPinyinStringArray(it, format)
                pinyinArray?.firstOrNull()?.firstOrNull()?.uppercaseChar()
            } ?: '#'
        }.getOrDefault('#')
    }
    
    /**
     * 带缓存的拼音转换（提高性能）
     */
    private val pinyinCache = mutableMapOf<String, String>()
    
    fun getCachedPinyin(
        chinese: String,
        format: HanyuPinyinOutputFormat = defaultFormat
    ): String {
        val cacheKey = "$chinese-${format.hashCode()}"
        return pinyinCache.getOrPut(cacheKey) {
            getFullPinyinSafely(chinese, format)
        }
    }
    
    /**
     * 清除缓存
     */
    fun clearCache() {
        pinyinCache.clear()
    }
}