const { createAppError } = require(`${__hooks}/bai_api_pb_hooks/bai_api_shared/utils/appError.js`)
const logger = require(`${__hooks}/bai_api_pb_hooks/bai_api_shared/utils/logger.js`)
const documentService = require(`${__hooks}/bai_api_pb_hooks/bai_api_shared/services/documentService.js`)

function buildSystemDictId() {
    return 'DICT-' + new Date().getTime() + '-' + $security.randomString(6)
}

function safeJsonParse(text, fallback) {
    if (!text) return fallback

    try {
        return JSON.parse(text)
    } catch (err) {
        return fallback
    }
}

function parseAttachmentIdList(value) {
    if (Array.isArray(value)) {
        return value
            .map(function (item) {
                return String(item || '').trim()
            })
            .filter(function (item) {
                return !!item
            })
    }

    const text = String(value || '').trim()
    if (!text) return []

    return text
        .split('|')
        .map(function (item) {
            return String(item || '').trim()
        })
        .filter(function (item) {
            return !!item
        })
}

function normalizeItemsFromRecord(record) {
    const enums = safeJsonParse(record.getString('dict_word_enum'), [])
    const descriptions = safeJsonParse(record.getString('dict_word_description'), [])
    const images = safeJsonParse(record.getString('dict_word_image'), [])
    const sortOrders = safeJsonParse(record.getString('dict_word_sort_order'), [])
    const maxLength = Math.max(enums.length, descriptions.length, images.length, sortOrders.length)
    const items = []

    for (let i = 0; i < maxLength; i += 1) {
        if (typeof enums[i] === 'undefined' && typeof descriptions[i] === 'undefined' && typeof images[i] === 'undefined' && typeof sortOrders[i] === 'undefined') {
            continue
        }

        const rawImageValue = typeof images[i] === 'undefined' ? '' : String(images[i] || '')
        const imageAttachmentIds = parseAttachmentIdList(rawImageValue)
        const imageAttachments = []
        const imageUrls = []

        for (let imageIndex = 0; imageIndex < imageAttachmentIds.length; imageIndex += 1) {
            const attachmentId = imageAttachmentIds[imageIndex]
            try {
                const imageAttachment = documentService.getAttachmentDetail(attachmentId)
                imageAttachments.push(imageAttachment)
                imageUrls.push(imageAttachment ? imageAttachment.attachments_url : '')
            } catch (_error) {
                imageAttachments.push(null)
                imageUrls.push('')
            }
        }

        items.push({
            enum: typeof enums[i] === 'undefined' ? '' : String(enums[i]),
            description: typeof descriptions[i] === 'undefined' ? '' : String(descriptions[i]),
            image: imageAttachmentIds.join('|'),
            imageIds: imageAttachmentIds,
            imageUrls: imageUrls,
            imageAttachments: imageAttachments,
            imageUrl: imageUrls.length ? imageUrls[0] : '',
            sortOrder: Number(sortOrders[i] || 0),
        })
    }

    return items
}

function exportDictionaryRecord(record) {
    return {
        pb_id: record.id,
        system_dict_id: record.getString('system_dict_id'),
        dict_name: record.getString('dict_name'),
        dict_word_is_enabled: !!record.get('dict_word_is_enabled'),
        dict_word_parent_id: record.getString('dict_word_parent_id'),
        dict_word_remark: record.getString('dict_word_remark'),
        items: normalizeItemsFromRecord(record),
        created: String(record.created || ''),
        updated: String(record.updated || ''),
    }
}

function sortDictionaryItems(items) {
    return (Array.isArray(items) ? items.slice() : []).sort(function (a, b) {
        const sortDiff = Number(a.sortOrder || 0) - Number(b.sortOrder || 0)
        if (sortDiff !== 0) {
            return sortDiff
        }

        return String(a.enum || '').localeCompare(String(b.enum || ''))
    })
}

function findDictionaryByName(dictName) {
    const records = $app.findRecordsByFilter('tbl_system_dict', 'dict_name = {:dictName}', '', 1, 0, {
        dictName: dictName,
    })

    return records.length ? records[0] : null
}

function ensureDictionaryNameUnique(dictName, excludeId) {
    const existing = findDictionaryByName(dictName)
    if (existing && existing.id !== excludeId) {
        throw createAppError(400, 'dict_name 已存在')
    }
}

function fillDictionaryItems(record, items) {
    const enums = []
    const descriptions = []
    const images = []
    const sortOrders = []

    for (let i = 0; i < items.length; i += 1) {
        enums.push(items[i].enum)
        descriptions.push(items[i].description)
        images.push(parseAttachmentIdList(items[i].image).join('|'))
        sortOrders.push(items[i].sortOrder)
    }

    record.set('dict_word_enum', JSON.stringify(enums))
    record.set('dict_word_description', JSON.stringify(descriptions))
    record.set('dict_word_image', JSON.stringify(images))
    record.set('dict_word_sort_order', JSON.stringify(sortOrders))
}

function listDictionaries(keyword) {
    const allRecords = $app.findRecordsByFilter('tbl_system_dict', '', 'dict_name', 500, 0)
    const normalizedKeyword = String(keyword || '').toLowerCase()
    const result = []

    for (let i = 0; i < allRecords.length; i += 1) {
        const item = exportDictionaryRecord(allRecords[i])
        if (!normalizedKeyword || item.dict_name.toLowerCase().indexOf(normalizedKeyword) !== -1) {
            result.push(item)
        }
    }

    return result
}

function getDictionaryByName(dictName) {
    const record = findDictionaryByName(dictName)
    if (!record) {
        throw createAppError(404, '未找到对应字典')
    }

    return exportDictionaryRecord(record)
}

function getDictionaryItemsByName(dictName) {
    const dictionary = getDictionaryByName(dictName)
    if (!dictionary.dict_word_is_enabled) {
        return []
    }

    return sortDictionaryItems(dictionary.items)
}

function createDictionary(payload) {
    ensureDictionaryNameUnique(payload.dict_name)

    const collection = $app.findCollectionByNameOrId('tbl_system_dict')
    const record = new Record(collection)
    record.set('system_dict_id', buildSystemDictId())
    record.set('dict_name', payload.dict_name)
    record.set('dict_word_is_enabled', payload.dict_word_is_enabled)
    record.set('dict_word_parent_id', payload.dict_word_parent_id)
    record.set('dict_word_remark', payload.dict_word_remark)
    fillDictionaryItems(record, payload.items)

    try {
        $app.save(record)
    } catch (err) {
        throw createAppError(400, '创建字典失败', {
            originalMessage: (err && err.message) || '未知错误',
            originalData: (err && err.data) || {},
        })
    }

    logger.info('字典创建成功', {
        dict_name: payload.dict_name,
        system_dict_id: record.getString('system_dict_id'),
    })

    return exportDictionaryRecord(record)
}

function updateDictionary(payload) {
    const record = findDictionaryByName(payload.original_dict_name)
    if (!record) {
        throw createAppError(404, '未找到待修改的字典')
    }

    const immutableName = record.getString('dict_name')

    record.set('dict_name', immutableName)
    record.set('dict_word_is_enabled', payload.dict_word_is_enabled)
    record.set('dict_word_parent_id', payload.dict_word_parent_id)
    record.set('dict_word_remark', payload.dict_word_remark)
    fillDictionaryItems(record, payload.items)

    try {
        $app.save(record)
    } catch (err) {
        throw createAppError(400, '修改字典失败', {
            originalMessage: (err && err.message) || '未知错误',
            originalData: (err && err.data) || {},
        })
    }

    logger.info('字典修改成功', {
        dict_name: immutableName,
        original_dict_name: payload.original_dict_name,
    })

    return exportDictionaryRecord(record)
}

function deleteDictionary(dictName) {
    const record = findDictionaryByName(dictName)
    if (!record) {
        throw createAppError(404, '未找到待删除的字典')
    }

    try {
        $app.delete(record)
    } catch (err) {
        throw createAppError(400, '删除字典失败', {
            originalMessage: (err && err.message) || '未知错误',
            originalData: (err && err.data) || {},
        })
    }

    logger.info('字典删除成功', {
        dict_name: dictName,
        system_dict_id: record.getString('system_dict_id'),
    })

    return {
        dict_name: dictName,
    }
}

module.exports = {
    listDictionaries,
    getDictionaryByName,
    getDictionaryItemsByName,
    createDictionary,
    updateDictionary,
    deleteDictionary,
}
