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

const TEMPLATE_COLLECTION = 'tbl_scheme_template'
const SCHEME_COLLECTION = 'tbl_scheme'
const USER_COLLECTION = 'tbl_auth_users'
const PRODUCT_COLLECTION = 'tbl_product_list'

function tryFindCollection(collectionName) {
    try {
        return $app.findCollectionByNameOrId(collectionName)
    } catch (_error) {
        return null
    }
}

function ensureCollectionReady(collectionName) {
    const collection = tryFindCollection(collectionName)
    if (!collection) {
        throw createAppError(400, '集合未初始化：' + collectionName + '，请先执行方案建表脚本')
    }

    return collection
}

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

function normalizeText(value) {
    return String(value || '').replace(/^\s+|\s+$/g, '')
}

function normalizeDateValue(value) {
    const text = normalizeText(value)
    if (!text) return null

    if (/^\d{4}-\d{2}-\d{2}$/.test(text)) {
        return text + ' 00:00:00.000Z'
    }

    if (/^\d{4}-\d{2}-\d{2}\s/.test(text) || text.indexOf('T') !== -1) {
        return text
    }

    throw createAppError(400, '日期字段格式错误')
}

function parseJsonInput(value, fieldName) {
    if (value === null || typeof value === 'undefined' || value === '') {
        return []
    }

    if (Array.isArray(value)) {
        try {
            return JSON.parse(JSON.stringify(value))
        } catch (_error) {
            throw createAppError(400, fieldName + ' 必须是可序列化的 JSON 数组')
        }
    }

    if (typeof value === 'object') {
        try {
            return JSON.parse(JSON.stringify(value))
        } catch (_error) {
            throw createAppError(400, fieldName + ' 必须是可序列化的 JSON 对象或数组')
        }
    }

    if (typeof value === 'string') {
        try {
            return JSON.parse(value)
        } catch (_error) {
            throw createAppError(400, fieldName + ' 必须为合法 JSON')
        }
    }

    throw createAppError(400, fieldName + ' 必须为 JSON')
}

function parseJsonForOutput(value, fallback) {
    if (value === null || typeof value === 'undefined' || value === '') {
        return typeof fallback === 'undefined' ? [] : fallback
    }

    if (Array.isArray(value)) {
        try {
            return JSON.parse(JSON.stringify(value))
        } catch (_error) {
            return typeof fallback === 'undefined' ? [] : fallback
        }
    }

    if (typeof value === 'object') {
        try {
            return JSON.parse(JSON.stringify(value))
        } catch (_error) {
            return typeof fallback === 'undefined' ? [] : fallback
        }
    }

    if (typeof value === 'string') {
        try {
            return JSON.parse(value)
        } catch (_error) {
            return typeof fallback === 'undefined' ? [] : fallback
        }
    }

    return typeof fallback === 'undefined' ? [] : fallback
}

function getUserRecordByOpenid(openid) {
    const value = normalizeText(openid)
    if (!value) return null
    if (!tryFindCollection(USER_COLLECTION)) return null

    const records = $app.findRecordsByFilter(USER_COLLECTION, 'openid = {:openid}', '', 1, 0, {
        openid: value,
    })

    if (!records.length) return null
    if (Number(records[0].get('is_delete') || 0) === 1) return null
    return records[0]
}

function ensureUserExists(openid, fieldName) {
    const value = normalizeText(openid)
    if (!value) {
        throw createAppError(400, fieldName + ' 为必填项')
    }

    const record = getUserRecordByOpenid(value)
    if (!record) {
        throw createAppError(400, fieldName + ' 对应用户不存在：' + value)
    }

    return record
}

function ensureAttachmentExists(attachmentId, fieldName) {
    const value = normalizeText(attachmentId)
    if (!value) {
        return ''
    }

    try {
        documentService.getAttachmentDetail(value)
    } catch (_error) {
        throw createAppError(400, fieldName + ' 对应附件不存在：' + value)
    }

    return value
}

function getProductRecordById(productId) {
    const value = normalizeText(productId)
    if (!value) return null
    if (!tryFindCollection(PRODUCT_COLLECTION)) return null

    const records = $app.findRecordsByFilter(PRODUCT_COLLECTION, 'prod_list_id = {:productId}', '', 1, 0, {
        productId: value,
    })

    if (!records.length) return null
    if (Number(records[0].get('is_delete') || 0) === 1) return null
    return records[0]
}

function ensureProductExists(productId, fieldName) {
    const value = normalizeText(productId)
    if (!value) {
        throw createAppError(400, fieldName + ' 不能为空')
    }

    const record = getProductRecordById(value)
    if (!record) {
        throw createAppError(400, fieldName + ' 对应产品不存在：' + value)
    }

    return record
}

function findTemplateRecordByTemplateId(templateId) {
    const value = normalizeText(templateId)
    if (!value) return null
    if (!tryFindCollection(TEMPLATE_COLLECTION)) return null

    const records = $app.findRecordsByFilter(TEMPLATE_COLLECTION, 'scheme_template_id = {:templateId}', '', 1, 0, {
        templateId: value,
    })

    if (!records.length) return null
    if (Number(records[0].get('is_delete') || 0) === 1) return null
    return records[0]
}

function ensureTemplateExists(templateId, fieldName) {
    const value = normalizeText(templateId)
    if (!value) {
        return null
    }

    const record = findTemplateRecordByTemplateId(value)
    if (!record) {
        throw createAppError(400, fieldName + ' 对应模板不存在：' + value)
    }

    return record
}

function findSchemeRecordBySchemeId(schemeId) {
    const value = normalizeText(schemeId)
    if (!value) return null
    if (!tryFindCollection(SCHEME_COLLECTION)) return null

    const records = $app.findRecordsByFilter(SCHEME_COLLECTION, 'scheme_id = {:schemeId}', '', 1, 0, {
        schemeId: value,
    })

    if (!records.length) return null
    if (Number(records[0].get('is_delete') || 0) === 1) return null
    return records[0]
}

function normalizeTemplateProductList(value) {
    const parsed = parseJsonInput(value, 'scheme_template_product_list')
    if (!Array.isArray(parsed)) {
        throw createAppError(400, 'scheme_template_product_list 必须为 JSON 数组')
    }

    const result = []
    for (let i = 0; i < parsed.length; i += 1) {
        const item = parsed[i] && typeof parsed[i] === 'object' ? parsed[i] : null
        if (!item) {
            continue
        }

        const productId = normalizeText(item.prod_list_id || item.product_id)
        if (!productId) {
            throw createAppError(400, 'scheme_template_product_list 第 ' + (i + 1) + ' 项必须包含 product_id 或 prod_list_id')
        }
        ensureProductExists(productId, 'scheme_template_product_list.product_id')

        const hasProductSnapshot = Object.keys(item).some(function (key) {
            return key.indexOf('prod_list_') === 0 || key === 'pb_id'
        })

        if (hasProductSnapshot) {
            let snapshot = null
            try {
                snapshot = JSON.parse(JSON.stringify(item))
            } catch (_error) {
                throw createAppError(400, 'scheme_template_product_list 第 ' + (i + 1) + ' 项必须为可序列化的产品对象')
            }

            snapshot.prod_list_id = productId
            result.push(snapshot)
            continue
        }

        const qty = Number(item.qty)
        if (!Number.isFinite(qty) || qty <= 0) {
            throw createAppError(400, 'scheme_template_product_list 第 ' + (i + 1) + ' 项 qty 必须为正数')
        }

        result.push({
            product_id: productId,
            qty: qty,
            note: normalizeText(item.note),
        })
    }

    return result
}

function normalizeSchemeRoomType(value) {
    const parsed = parseJsonInput(value, 'scheme_room_type')
    if (!Array.isArray(parsed)) {
        throw createAppError(400, 'scheme_room_type 必须为 JSON 数组')
    }

    const result = []
    for (let i = 0; i < parsed.length; i += 1) {
        const item = parsed[i] && typeof parsed[i] === 'object' ? parsed[i] : null
        if (!item) {
            continue
        }

        const roomType = normalizeText(item.room_type || item.name)
        if (!roomType) {
            throw createAppError(400, 'scheme_room_type 第 ' + (i + 1) + ' 项 room_type 为必填项')
        }

        const qty = Number(item.qty)
        if (!Number.isFinite(qty) || qty <= 0) {
            throw createAppError(400, 'scheme_room_type 第 ' + (i + 1) + ' 项 qty 必须为正数')
        }

        result.push({
            room_type: roomType,
            qty: qty,
        })
    }

    return result
}

function resolveAttachment(attachmentId) {
    const value = normalizeText(attachmentId)
    if (!value) {
        return {
            id: '',
            url: '',
            attachment: null,
        }
    }

    try {
        const attachment = documentService.getAttachmentDetail(value)
        return {
            id: value,
            url: attachment ? attachment.attachments_url : '',
            attachment: attachment,
        }
    } catch (_error) {
        return {
            id: value,
            url: '',
            attachment: null,
        }
    }
}

function buildTemplateSummaryMap() {
    if (!tryFindCollection(TEMPLATE_COLLECTION)) {
        logger.warn('方案模板集合未初始化，方案模板摘要映射将返回空结果', {
            collection: TEMPLATE_COLLECTION,
        })
        return {}
    }

    const records = $app.findRecordsByFilter(TEMPLATE_COLLECTION, 'is_delete = 0', '-updated', 1000, 0)
    const map = {}

    for (let i = 0; i < records.length; i += 1) {
        const templateId = normalizeText(records[i].getString('scheme_template_id'))
        if (!templateId) {
            continue
        }

        map[templateId] = {
            scheme_template_id: templateId,
            scheme_template_name: records[i].getString('scheme_template_name'),
            scheme_template_owner: records[i].getString('scheme_template_owner'),
            scheme_template_status: records[i].getString('scheme_template_status'),
        }
    }

    return map
}

function exportTemplateRecord(record) {
    const icon = resolveAttachment(record.getString('scheme_template_icon'))

    return {
        pb_id: record.id,
        scheme_template_id: record.getString('scheme_template_id'),
        scheme_template_icon: icon.id,
        scheme_template_icon_url: icon.url,
        scheme_template_icon_attachment: icon.attachment,
        scheme_template_label: record.getString('scheme_template_label'),
        scheme_template_name: record.getString('scheme_template_name'),
        scheme_template_owner: record.getString('scheme_template_owner'),
        scheme_template_status: record.getString('scheme_template_status'),
        scheme_template_solution_type: record.getString('scheme_template_solution_type'),
        scheme_template_solution_feature: record.getString('scheme_template_solution_feature'),
        scheme_template_product_list: parseJsonForOutput(record.get('scheme_template_product_list'), []),
        scheme_template_description: record.getString('scheme_template_description'),
        scheme_template_remark: record.getString('scheme_template_remark'),
        is_delete: Number(record.get('is_delete') || 0),
        created: String(record.created || ''),
        updated: String(record.updated || ''),
    }
}

function exportSchemeRecord(record, templateMap) {
    const highendId = record.getString('scheme_template_highend')
    const midendId = record.getString('scheme_template_midend')
    const lowendId = record.getString('scheme_template_lowend')
    const templates = templateMap || {}

    return {
        pb_id: record.id,
        scheme_id: record.getString('scheme_id'),
        scheme_name: record.getString('scheme_name'),
        scheme_owner: record.getString('scheme_owner'),
        scheme_share_status: record.getString('scheme_share_status'),
        scheme_expires_at: String(record.get('scheme_expires_at') || ''),
        scheme_hotel_type: record.getString('scheme_hotel_type'),
        scheme_solution_type: record.getString('scheme_solution_type'),
        scheme_solution_feature: record.getString('scheme_solution_feature'),
        scheme_room_type: parseJsonForOutput(record.get('scheme_room_type'), []),
        scheme_curtains: record.getString('scheme_curtains'),
        scheme_voice_device: record.getString('scheme_voice_device'),
        scheme_ac_type: record.getString('scheme_ac_type'),
        scheme_template_highend: highendId,
        scheme_template_highend_name: templates[highendId] ? templates[highendId].scheme_template_name : '',
        scheme_template_midend: midendId,
        scheme_template_midend_name: templates[midendId] ? templates[midendId].scheme_template_name : '',
        scheme_template_lowend: lowendId,
        scheme_template_lowend_name: templates[lowendId] ? templates[lowendId].scheme_template_name : '',
        scheme_status: record.getString('scheme_status'),
        scheme_remark: record.getString('scheme_remark'),
        is_delete: Number(record.get('is_delete') || 0),
        created: String(record.created || ''),
        updated: String(record.updated || ''),
    }
}

function applyTemplatePayload(record, payload) {
    ensureUserExists(payload.scheme_template_owner, 'scheme_template_owner')

    record.set('scheme_template_name', normalizeText(payload.scheme_template_name))
    record.set('scheme_template_owner', normalizeText(payload.scheme_template_owner))
    record.set('scheme_template_icon', ensureAttachmentExists(payload.scheme_template_icon, 'scheme_template_icon'))
    record.set('scheme_template_label', normalizeText(payload.scheme_template_label))
    record.set('scheme_template_status', normalizeText(payload.scheme_template_status))
    record.set('scheme_template_solution_type', normalizeText(payload.scheme_template_solution_type))
    record.set('scheme_template_solution_feature', normalizeText(payload.scheme_template_solution_feature))
    record.set('scheme_template_product_list', normalizeTemplateProductList(payload.scheme_template_product_list))
    record.set('scheme_template_description', normalizeText(payload.scheme_template_description))
    record.set('scheme_template_remark', normalizeText(payload.scheme_template_remark))
}

function applySchemePayload(record, payload) {
    ensureUserExists(payload.scheme_owner, 'scheme_owner')
    ensureTemplateExists(payload.scheme_template_highend, 'scheme_template_highend')
    ensureTemplateExists(payload.scheme_template_midend, 'scheme_template_midend')
    ensureTemplateExists(payload.scheme_template_lowend, 'scheme_template_lowend')

    record.set('scheme_name', normalizeText(payload.scheme_name))
    record.set('scheme_owner', normalizeText(payload.scheme_owner))
    record.set('scheme_share_status', normalizeText(payload.scheme_share_status))
    record.set('scheme_expires_at', normalizeDateValue(payload.scheme_expires_at))
    record.set('scheme_hotel_type', normalizeText(payload.scheme_hotel_type))
    record.set('scheme_solution_type', normalizeText(payload.scheme_solution_type))
    record.set('scheme_solution_feature', normalizeText(payload.scheme_solution_feature))
    record.set('scheme_room_type', normalizeSchemeRoomType(payload.scheme_room_type))
    record.set('scheme_curtains', normalizeText(payload.scheme_curtains))
    record.set('scheme_voice_device', normalizeText(payload.scheme_voice_device))
    record.set('scheme_ac_type', normalizeText(payload.scheme_ac_type))
    record.set('scheme_template_highend', normalizeText(payload.scheme_template_highend))
    record.set('scheme_template_midend', normalizeText(payload.scheme_template_midend))
    record.set('scheme_template_lowend', normalizeText(payload.scheme_template_lowend))
    record.set('scheme_status', normalizeText(payload.scheme_status))
    record.set('scheme_remark', normalizeText(payload.scheme_remark))
}

function listSchemeTemplates(payload) {
    if (!tryFindCollection(TEMPLATE_COLLECTION)) {
        logger.warn('方案模板集合未初始化，模板列表返回空结果', {
            collection: TEMPLATE_COLLECTION,
        })
        return []
    }

    const records = $app.findRecordsByFilter(TEMPLATE_COLLECTION, 'is_delete = 0', '-updated', 1000, 0)
    const keyword = normalizeText(payload.keyword).toLowerCase()
    const owner = normalizeText(payload.scheme_template_owner)
    const status = normalizeText(payload.scheme_template_status)
    const solutionType = normalizeText(payload.scheme_template_solution_type)
    const solutionFeature = normalizeText(payload.scheme_template_solution_feature)
    const result = []

    for (let i = 0; i < records.length; i += 1) {
        const item = exportTemplateRecord(records[i])
        const matchedKeyword = !keyword
            || normalizeText(item.scheme_template_id).toLowerCase().indexOf(keyword) !== -1
            || normalizeText(item.scheme_template_name).toLowerCase().indexOf(keyword) !== -1
            || normalizeText(item.scheme_template_label).toLowerCase().indexOf(keyword) !== -1
            || normalizeText(item.scheme_template_owner).toLowerCase().indexOf(keyword) !== -1
        const matchedOwner = !owner || item.scheme_template_owner === owner
        const matchedStatus = !status || item.scheme_template_status === status
        const matchedSolutionType = !solutionType || item.scheme_template_solution_type === solutionType
        const matchedSolutionFeature = !solutionFeature || item.scheme_template_solution_feature === solutionFeature

        if (matchedKeyword && matchedOwner && matchedStatus && matchedSolutionType && matchedSolutionFeature) {
            result.push(item)
        }
    }

    return result
}

function getSchemeTemplateDetail(templateId) {
    ensureCollectionReady(TEMPLATE_COLLECTION)

    const record = findTemplateRecordByTemplateId(templateId)
    if (!record) {
        throw createAppError(404, '未找到对应方案模板')
    }

    return exportTemplateRecord(record)
}

function createSchemeTemplate(userOpenid, payload) {
    const collection = ensureCollectionReady(TEMPLATE_COLLECTION)
    const templateId = normalizeText(payload.scheme_template_id) || buildBusinessId('SCHTPL')
    if (findTemplateRecordByTemplateId(templateId)) {
        throw createAppError(400, 'scheme_template_id 已存在')
    }

    const record = new Record(collection)

    record.set('scheme_template_id', templateId)
    record.set('is_delete', 0)
    applyTemplatePayload(record, payload)

    try {
        $app.save(record)
    } catch (err) {
        throw createAppError(400, '新增方案模板失败', {
            originalMessage: (err && err.message) || '未知错误',
            originalData: (err && err.data) || {},
        })
    }

    logger.info('方案模板创建成功', {
        scheme_template_id: templateId,
        operator_openid: userOpenid || '',
    })

    return exportTemplateRecord(record)
}

function updateSchemeTemplate(userOpenid, payload) {
    ensureCollectionReady(TEMPLATE_COLLECTION)

    const templateId = normalizeText(payload.scheme_template_id)
    if (!templateId) {
        throw createAppError(400, 'scheme_template_id 为必填项')
    }

    const record = findTemplateRecordByTemplateId(templateId)
    if (!record) {
        throw createAppError(404, '未找到待修改的方案模板')
    }

    applyTemplatePayload(record, payload)

    try {
        $app.save(record)
    } catch (err) {
        throw createAppError(400, '更新方案模板失败', {
            originalMessage: (err && err.message) || '未知错误',
            originalData: (err && err.data) || {},
        })
    }

    logger.info('方案模板更新成功', {
        scheme_template_id: templateId,
        operator_openid: userOpenid || '',
    })

    return exportTemplateRecord(record)
}

function deleteSchemeTemplate(userOpenid, templateId) {
    ensureCollectionReady(TEMPLATE_COLLECTION)
    ensureCollectionReady(SCHEME_COLLECTION)

    const value = normalizeText(templateId)
    if (!value) {
        throw createAppError(400, 'scheme_template_id 为必填项')
    }

    const record = findTemplateRecordByTemplateId(value)
    if (!record) {
        throw createAppError(404, '未找到待删除的方案模板')
    }

    const usedSchemes = $app.findRecordsByFilter(
        SCHEME_COLLECTION,
        'is_delete = 0 && (scheme_template_highend = {:templateId} || scheme_template_midend = {:templateId} || scheme_template_lowend = {:templateId})',
        '',
        1,
        0,
        { templateId: value }
    )

    if (usedSchemes.length) {
        throw createAppError(400, '方案模板已被方案引用，无法删除')
    }

    record.set('is_delete', 1)

    try {
        $app.save(record)
    } catch (err) {
        throw createAppError(400, '删除方案模板失败', {
            originalMessage: (err && err.message) || '未知错误',
            originalData: (err && err.data) || {},
        })
    }

    logger.info('方案模板删除成功', {
        scheme_template_id: value,
        operator_openid: userOpenid || '',
    })

    return {
        scheme_template_id: value,
    }
}

function listSchemes(payload) {
    if (!tryFindCollection(SCHEME_COLLECTION)) {
        logger.warn('方案集合未初始化，方案列表返回空结果', {
            collection: SCHEME_COLLECTION,
        })
        return []
    }

    const templateMap = buildTemplateSummaryMap()
    const records = $app.findRecordsByFilter(SCHEME_COLLECTION, 'is_delete = 0', '-updated', 1000, 0)
    const keyword = normalizeText(payload.keyword).toLowerCase()
    const owner = normalizeText(payload.scheme_owner)
    const status = normalizeText(payload.scheme_status)
    const shareStatus = normalizeText(payload.scheme_share_status)
    const hotelType = normalizeText(payload.scheme_hotel_type)
    const result = []

    for (let i = 0; i < records.length; i += 1) {
        const item = exportSchemeRecord(records[i], templateMap)
        const matchedKeyword = !keyword
            || normalizeText(item.scheme_id).toLowerCase().indexOf(keyword) !== -1
            || normalizeText(item.scheme_name).toLowerCase().indexOf(keyword) !== -1
            || normalizeText(item.scheme_owner).toLowerCase().indexOf(keyword) !== -1
        const matchedOwner = !owner || item.scheme_owner === owner
        const matchedStatus = !status || item.scheme_status === status
        const matchedShareStatus = !shareStatus || item.scheme_share_status === shareStatus
        const matchedHotelType = !hotelType || item.scheme_hotel_type === hotelType

        if (matchedKeyword && matchedOwner && matchedStatus && matchedShareStatus && matchedHotelType) {
            result.push(item)
        }
    }

    return result
}

function getSchemeDetail(schemeId) {
    ensureCollectionReady(SCHEME_COLLECTION)

    const record = findSchemeRecordBySchemeId(schemeId)
    if (!record) {
        throw createAppError(404, '未找到对应方案')
    }

    return exportSchemeRecord(record, buildTemplateSummaryMap())
}

function createScheme(userOpenid, payload) {
    const collection = ensureCollectionReady(SCHEME_COLLECTION)
    const schemeId = normalizeText(payload.scheme_id) || buildBusinessId('SCHEME')
    if (findSchemeRecordBySchemeId(schemeId)) {
        throw createAppError(400, 'scheme_id 已存在')
    }

    const record = new Record(collection)

    record.set('scheme_id', schemeId)
    record.set('is_delete', 0)
    applySchemePayload(record, payload)

    try {
        $app.save(record)
    } catch (err) {
        throw createAppError(400, '新增方案失败', {
            originalMessage: (err && err.message) || '未知错误',
            originalData: (err && err.data) || {},
        })
    }

    logger.info('方案创建成功', {
        scheme_id: schemeId,
        operator_openid: userOpenid || '',
    })

    return exportSchemeRecord(record, buildTemplateSummaryMap())
}

function updateScheme(userOpenid, payload) {
    ensureCollectionReady(SCHEME_COLLECTION)

    const schemeId = normalizeText(payload.scheme_id)
    if (!schemeId) {
        throw createAppError(400, 'scheme_id 为必填项')
    }

    const record = findSchemeRecordBySchemeId(schemeId)
    if (!record) {
        throw createAppError(404, '未找到待修改的方案')
    }

    applySchemePayload(record, payload)

    try {
        $app.save(record)
    } catch (err) {
        throw createAppError(400, '更新方案失败', {
            originalMessage: (err && err.message) || '未知错误',
            originalData: (err && err.data) || {},
        })
    }

    logger.info('方案更新成功', {
        scheme_id: schemeId,
        operator_openid: userOpenid || '',
    })

    return exportSchemeRecord(record, buildTemplateSummaryMap())
}

function deleteScheme(userOpenid, schemeId) {
    ensureCollectionReady(SCHEME_COLLECTION)

    const value = normalizeText(schemeId)
    if (!value) {
        throw createAppError(400, 'scheme_id 为必填项')
    }

    const record = findSchemeRecordBySchemeId(value)
    if (!record) {
        throw createAppError(404, '未找到待删除的方案')
    }

    record.set('is_delete', 1)

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

    logger.info('方案删除成功', {
        scheme_id: value,
        operator_openid: userOpenid || '',
    })

    return {
        scheme_id: value,
    }
}

module.exports = {
    listSchemeTemplates,
    getSchemeTemplateDetail,
    createSchemeTemplate,
    updateSchemeTemplate,
    deleteSchemeTemplate,
    listSchemes,
    getSchemeDetail,
    createScheme,
    updateScheme,
    deleteScheme,
}
