/**
 * 精确文本差异计算工具
 * 使用 diff-match-patch 算法实现字符级别的精确对比
 */

import DiffMatchPatch from 'diff-match-patch'

const dmp = new DiffMatchPatch()

/**
 * 计算两段文本的精确差异（字符级别）
 * @param {string} original - 原文
 * @param {string} rewritten - 修改后的文本
 * @returns {Array<{type: 'unchanged'|'modified'|'added'|'removed', original: string, rewritten: string}>}
 */
export const computePreciseDiff = (original, rewritten) => {
    if (!original && !rewritten) return []
    if (!original) {
        return [{ type: 'added', original: '', rewritten: rewritten }]
    }
    if (!rewritten) {
        return [{ type: 'removed', original: original, rewritten: '' }]
    }

    // 使用 diff-match-patch 计算差异
    const diffs = dmp.diff_main(original, rewritten)
    dmp.diff_cleanupSemantic(diffs) // 语义清理，让差异更可读

    const result = []

    for (const [op, text] of diffs) {
        if (op === 0) {
            // 相同部分
            result.push({
                type: 'unchanged',
                original: text,
                rewritten: text
            })
        } else if (op === -1) {
            // 删除
            result.push({
                type: 'removed',
                original: text,
                rewritten: ''
            })
        } else if (op === 1) {
            // 新增
            result.push({
                type: 'added',
                original: '',
                rewritten: text
            })
        }
    }

    // 合并相邻的删除和新增为修改
    return mergeAdjacentChanges(result)
}

/**
 * 合并相邻的删除和新增为修改
 * @param {Array} diffs - 差异数组
 * @returns {Array} - 合并后的差异数组
 */
const mergeAdjacentChanges = (diffs) => {
    const merged = []
    let i = 0

    while (i < diffs.length) {
        const current = diffs[i]
        const next = diffs[i + 1]

        // 如果当前是删除，下一个是新增，合并为修改
        if (current.type === 'removed' && next?.type === 'added') {
            merged.push({
                type: 'modified',
                original: current.original,
                rewritten: next.rewritten
            })
            i += 2
        }
        // 如果当前是新增，下一个是删除，也合并为修改
        else if (current.type === 'added' && next?.type === 'removed') {
            merged.push({
                type: 'modified',
                original: next.original,
                rewritten: current.rewritten
            })
            i += 2
        }
        else {
            merged.push(current)
            i++
        }
    }

    return merged
}

/**
 * 获取精确差异统计
 * @param {Array} diffSegments - 差异片段
 * @returns {{total: number, modified: number, added: number, removed: number, unchanged: number}}
 */
export const getPreciseDiffStats = (diffSegments) => {
    const nonUnchanged = diffSegments.filter(s => s.type !== 'unchanged')
    return {
        total: nonUnchanged.length,
        modified: diffSegments.filter(s => s.type === 'modified').length,
        added: diffSegments.filter(s => s.type === 'added').length,
        removed: diffSegments.filter(s => s.type === 'removed').length,
        unchanged: diffSegments.filter(s => s.type === 'unchanged').length
    }
}
