const { createAppError } = require(`${__hooks}/bai_api_pb_hooks/bai_api_shared/utils/appError.js`)
const { sanitizePayload } = require(`${__hooks}/bai_api_pb_hooks/bai_api_shared/utils/sanitize.js`)

const requestCache = {}
const WINDOW_MS = 5000

function parseBody(e) {
    return sanitizePayload(e.requestInfo().body || {})
}

function requireJson(e) {
    const contentType = e.request.header.get('Content-Type') || e.request.header.get('content-type') || ''
    if (contentType.toLowerCase().indexOf('application/json') === -1) {
        throw createAppError(415, '请求体必须为 application/json')
    }
}

function validateLoginBody(e) {
    const payload = parseBody(e)
    if (!payload.users_wx_code) {
        throw createAppError(400, 'users_wx_code 为必填项')
    }
    return payload
}

function validateProfileBody(e) {
    const payload = parseBody(e)
    if (!payload.users_name) throw createAppError(400, 'users_name 为必填项')
    if (!payload.users_phone_code) throw createAppError(400, 'users_phone_code 为必填项')
    if (!payload.users_picture) throw createAppError(400, 'users_picture 为必填项')
    return payload
}

function validatePlatformRegisterBody(e) {
    const payload = parseBody(e)

    if (!payload.users_name) throw createAppError(400, 'users_name 为必填项')
    if (!payload.users_phone) throw createAppError(400, 'users_phone 为必填项')
    if (!payload.password) throw createAppError(400, 'password 为必填项')
    if (!payload.passwordConfirm) throw createAppError(400, 'passwordConfirm 为必填项')
    if (!payload.users_picture) throw createAppError(400, 'users_picture 为必填项')

    if (payload.password !== payload.passwordConfirm) {
        throw createAppError(400, 'password 与 passwordConfirm 不一致')
    }

    return payload
}

function validatePlatformLoginBody(e) {
    const payload = parseBody(e)

    const loginAccount = payload.login_account || payload.users_phone || payload.email || ''

    if (!loginAccount) throw createAppError(400, 'login_account 为必填项，支持邮箱或手机号')
    if (!payload.password) throw createAppError(400, 'password 为必填项')

    return {
        login_account: loginAccount,
        password: payload.password,
    }
}

function validateSystemRefreshBody(e) {
    const payload = parseBody(e)

    if (typeof payload.users_wx_code === 'undefined' || payload.users_wx_code === null) {
        return {
            users_wx_code: '',
        }
    }

    if (typeof payload.users_wx_code !== 'string') {
        throw createAppError(400, 'users_wx_code 类型错误')
    }

    return {
        users_wx_code: payload.users_wx_code,
    }
}

function requireManagePlatformUser(e) {
    const authUser = requireAuthUser(e)
    const idType = authUser.authRecord.getString('users_idtype')

    if (idType !== 'ManagePlatform') {
        throw createAppError(403, '仅平台管理用户可访问')
    }

    return authUser
}

function validateDictionaryListBody(e) {
    const payload = parseBody(e)
    return {
        keyword: payload.keyword || '',
    }
}

function validateDictionaryDetailBody(e) {
    const payload = parseBody(e)
    if (!payload.dict_name) {
        throw createAppError(400, 'dict_name 为必填项')
    }

    return {
        dict_name: payload.dict_name,
    }
}

function normalizeDictionaryItem(item, index) {
    const current = sanitizePayload(item || {})
    if (!current.enum) {
        throw createAppError(400, '第 ' + (index + 1) + ' 项 enum 为必填项')
    }

    if (!current.description) {
        throw createAppError(400, '第 ' + (index + 1) + ' 项 description 为必填项')
    }

    const sortOrderNumber = Number(current.sortOrder)
    if (!Number.isFinite(sortOrderNumber)) {
        throw createAppError(400, '第 ' + (index + 1) + ' 项 sortOrder 必须为数字')
    }

    return {
        enum: String(current.enum),
        description: String(current.description),
        sortOrder: sortOrderNumber,
    }
}

function validateDictionaryMutationBody(e, isUpdate) {
    const payload = parseBody(e)

    if (!payload.dict_name) {
        throw createAppError(400, 'dict_name 为必填项')
    }

    const items = Array.isArray(payload.items) ? payload.items : []
    if (!items.length) {
        throw createAppError(400, 'items 至少需要一项')
    }

    const normalizedItems = items.map(function (item, index) {
        return normalizeDictionaryItem(item, index)
    })

    return {
        dict_name: payload.dict_name,
        dict_word_is_enabled: typeof payload.dict_word_is_enabled === 'boolean' ? payload.dict_word_is_enabled : true,
        dict_word_parent_id: payload.dict_word_parent_id || '',
        dict_word_remark: payload.dict_word_remark || '',
        items: normalizedItems,
        original_dict_name: isUpdate ? (payload.original_dict_name || payload.dict_name) : '',
    }
}

function validateDictionaryDeleteBody(e) {
    const payload = parseBody(e)
    if (!payload.dict_name) {
        throw createAppError(400, 'dict_name 为必填项')
    }

    return {
        dict_name: payload.dict_name,
    }
}

function validateAttachmentListBody(e) {
    const payload = parseBody(e)

    return {
        keyword: payload.keyword || '',
        status: payload.status || '',
    }
}

function validateAttachmentDetailBody(e) {
    const payload = parseBody(e)
    if (!payload.attachments_id) {
        throw createAppError(400, 'attachments_id 为必填项')
    }

    return {
        attachments_id: payload.attachments_id,
    }
}

function validateAttachmentDeleteBody(e) {
    return validateAttachmentDetailBody(e)
}

function validateAttachmentUploadBody(e) {
    const payload = sanitizePayload(e.requestInfo().body || {})

    return {
        attachments_filename: payload.attachments_filename || '',
        attachments_filetype: payload.attachments_filetype || '',
        attachments_size: payload.attachments_size || 0,
        attachments_md5: payload.attachments_md5 || '',
        attachments_ocr: payload.attachments_ocr || '',
        attachments_status: payload.attachments_status || 'active',
        attachments_remark: payload.attachments_remark || '',
    }
}

function validateDocumentListBody(e) {
    const payload = parseBody(e)

    return {
        keyword: payload.keyword || '',
        status: payload.status || '',
        document_type: payload.document_type || '',
    }
}

function validateDocumentDetailBody(e) {
    const payload = parseBody(e)
    if (!payload.document_id) {
        throw createAppError(400, 'document_id 为必填项')
    }

    return {
        document_id: payload.document_id,
    }
}

function validateDocumentMutationBody(e, isUpdate) {
    const payload = parseBody(e)

    if (!payload.document_id && isUpdate) {
        throw createAppError(400, 'document_id 为必填项')
    }

    return {
        document_id: payload.document_id || '',
        document_effect_date: payload.document_effect_date || '',
        document_expiry_date: payload.document_expiry_date || '',
        document_type: payload.document_type || '',
        document_title: payload.document_title || '',
        document_subtitle: payload.document_subtitle || '',
        document_summary: payload.document_summary || '',
        document_content: payload.document_content || '',
        document_image: payload.document_image || '',
        document_video: payload.document_video || '',
        document_relation_model: payload.document_relation_model || '',
        document_keywords: payload.document_keywords || '',
        document_share_count: payload.document_share_count || 0,
        document_download_count: payload.document_download_count || 0,
        document_favorite_count: payload.document_favorite_count || 0,
        document_status: payload.document_status || '',
        document_embedding_status: payload.document_embedding_status || '',
        document_embedding_error: payload.document_embedding_error || '',
        document_embedding_lasttime: payload.document_embedding_lasttime || '',
        document_vector_version: payload.document_vector_version || '',
        document_product_categories: payload.document_product_categories || '',
        document_application_scenarios: payload.document_application_scenarios || '',
        document_hotel_type: payload.document_hotel_type || '',
        document_remark: payload.document_remark || '',
    }
}

function validateDocumentDeleteBody(e) {
    return validateDocumentDetailBody(e)
}

function validateDocumentHistoryListBody(e) {
    const payload = parseBody(e)

    return {
        document_id: payload.document_id || '',
    }
}

function requireAuthOpenid(e) {
    if (!e.auth) {
        throw createAppError(401, '认证令牌无效或已过期')
    }

    if (e.auth.collection().name !== 'tbl_auth_users') {
        throw createAppError(401, '认证用户集合不正确')
    }

    const openid = e.auth.getString('openid')
    if (!openid) {
        throw createAppError(401, '当前认证用户缺少 openid')
    }

    return openid
}

function requireAuthUser(e) {
    const authHeader = e.request.header.get('Authorization') || ''
    const parts = authHeader.split(' ')

    if (parts.length !== 2 || parts[0] !== 'Bearer' || !parts[1]) {
        throw createAppError(401, '请求头缺少 Authorization')
    }

    if (!e.auth) {
        throw createAppError(401, '认证令牌无效或已过期')
    }

    if (e.auth.collection().name !== 'tbl_auth_users') {
        throw createAppError(401, '认证用户集合不正确')
    }

    const authOpenid = e.auth.getString('openid')
    if (!authOpenid) {
        throw createAppError(401, '当前认证用户缺少 openid')
    }

    return {
        openid: authOpenid,
        authRecord: e.auth,
    }
}

function duplicateGuard(e) {
    const key = String(e.realIP()) + ':' + String(e.request.url.pathname) + ':' + JSON.stringify(e.requestInfo().body || {})
    const now = Date.now()
    const lastTime = requestCache[key]

    if (lastTime && now - lastTime < WINDOW_MS) {
        throw createAppError(429, '请求过于频繁，请稍后重试')
    }

    requestCache[key] = now
}

module.exports = {
    parseBody,
    requireJson,
    validateLoginBody,
    validateProfileBody,
    validatePlatformRegisterBody,
    validatePlatformLoginBody,
    validateSystemRefreshBody,
    requireManagePlatformUser,
    validateDictionaryListBody,
    validateDictionaryDetailBody,
    validateDictionaryMutationBody,
    validateDictionaryDeleteBody,
    validateAttachmentListBody,
    validateAttachmentDetailBody,
    validateAttachmentDeleteBody,
    validateAttachmentUploadBody,
    validateDocumentListBody,
    validateDocumentDetailBody,
    validateDocumentMutationBody,
    validateDocumentDeleteBody,
    validateDocumentHistoryListBody,
    requireAuthOpenid,
    requireAuthUser,
    duplicateGuard,
}
