import { CLConfigureUtil } from "@normalized:N&&&@wanshu/realauthsdk/src/main/ets/CLConfigureUtil&1.0.0";
import { CLGzipUtil, CLSecurityUtils, CLStringUtil } from "@normalized:N&&&@wanshu/realauthsdk/src/main/ets/utils/CLSecurityUtils&1.0.0";
import NetManager, { CLNetContanst } from "@normalized:N&&&@wanshu/realauthsdk/src/main/ets/utils/CLNetworkUtils&1.0.0";
import type { CLRequestOption } from "@normalized:N&&&@wanshu/realauthsdk/src/main/ets/utils/CLNetworkUtils&1.0.0";
import http from "@ohos:net.http";
import bundleManager from "@ohos:bundle.bundleManager";
import { compressedImage } from "@normalized:N&&&@wanshu/realauthsdk/src/main/ets/utils/CLImageCompressUtils&1.0.0";
import { CLCoreHttpResopnse } from "@normalized:N&&&@wanshu/realauthsdk/src/main/ets/clocr/CLCoreHttpResponse&1.0.0";
import type { CLOCRAuthOrderMessage, CLOCRCardMessage, CLOCRSideMessage, CLResult } from "@normalized:N&&&@wanshu/realauthsdk/src/main/ets/clocr/CLCoreHttpResponse&1.0.0";
import type { BusinessError as BusinessError } from "@ohos:base";
import JSON from "@ohos:util.json";
import CLLog from "@normalized:N&&&@wanshu/realauthsdk/src/main/ets/utils/CLLogUtils&1.0.0";
/**
 * @class CLOCRManager OCR识别
 **/
export class CLOCRManager {
    /**设置SDK token，作为后续操作凭证*/
    static setToken(token: string) {
        CLConfigureUtil.setToken(token);
    }
    /**
     * 身份证OCR接口    ⚠️ 先调用人像面（图片大小建议压缩为1M以内，超过会被SDK压缩）
     * @param image: 传入的身份证图片
     * @param isFront: true：人像面；false：国徽面
     * @returns Promise<Object> 返回结果：
     * @example
     * 国徽面数据 :{
                   "expire_date"       = "失效日期";
                   "issuing_authority" ="签发机关";
                   "issuing_date"      = "签发日期";
                 };
     *人像面数据：{
                    "address"    = "地址";
                    "brith_day"  = "出生日期";
                    "id_card_no" = "身份证号";
                    "name"       = "姓名";
                    "nation"     = "民族";
                    "sex"        = "性别";
                 };
     * */
    static async realPersonOCROfSignal(image: PixelMap, isFront: boolean): Promise<Object> {
        if (!image || typeof image === 'string') {
            return new Promise((race) => {
                const result: Record<string, string> = { 'code': '-999', 'message': ' 图片不正确' };
                race(result);
            });
        }
        const pksId = CLConfigureUtil.getPksId();
        const pks = CLConfigureUtil.getPks();
        const random = CLStringUtil.generateRandomString(32);
        const imageBuffer = await compressedImage(image, 1 * 1024);
        const imageData = await CLGzipUtil.gzipAndAES(imageBuffer, random);
        const imageBase64 = CLStringUtil.uint8ArrayToBase64(imageData);
        const bundleId: string = bundleManager.getBundleInfoForSelfSync(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_SIGNATURE_INFO).name;
        const rsaRandomUUID = await CLSecurityUtils.encryptRSA(random, pks);
        const rsaRandomHex = CLStringUtil.uint8ArrayToHexString(rsaRandomUUID);
        let params: Record<string, Object> = {
            'image': imageBase64,
            'image_type': 'BASE64',
            'platform_type': CLConfigureUtil.getPlatform(),
            'bundle_id': bundleId,
            'app_key': CLConfigureUtil.getAppId(),
            'auth_token': CLConfigureUtil.getToken(),
            'side': isFront ? 'front' : 'back',
        };
        let headers: Record<string, string> = {
            'Content-Encoding': 'gzip',
            'Content-Type': 'application/json',
            'Data-Key': (pksId + rsaRandomHex)
        };
        let option: CLRequestOption = {
            method: http.RequestMethod.POST,
            header: headers,
            data: params,
            path: CLNetContanst.getOCRIdcard()
        };
        console.log('请求参数：' + JSON.stringify(params));
        try {
            let r = await NetManager.post<CLResult<CLOCRCardMessage>>(CLNetContanst.getOCRIdcard(), params, headers);
            if (r.code === '000000' && isFront === true) {
                console.log('请求---' + JSON.stringify(r.data.id_card_no));
                if (r.data) {
                    if (r.data.id_card_no) {
                        const idCardNum = await CLSecurityUtils.decryptRSAString(r.data.id_card_no, pks);
                        r.data.id_card_no = idCardNum;
                    }
                    if (r.data.name) {
                        const name = await CLSecurityUtils.decryptRSAString(r.data.name, pks);
                        r.data.name = name;
                    }
                }
            }
            CLLog.log(`OCR识别-单面识别：${JSON.stringify(r)}`);
            return r;
        }
        catch (e) {
            CLLog.error(`OCR识别-单面识别：${JSON.stringify(e)}`);
            return e;
        }
    }
    /**
     * 身份证OCR接口    识别人像面和国徽面（单图片大小建议压缩为1M以内，超过会被SDK压缩）
     * @param frontImagePixMap 人像面照片
     * @param backImagePixMap  国徽面照片
     * @returns Promise<Object> 返回结果
     * @example {
                back = {
                         "expire_date"       = "失效日期";
                         "issuing_authority" = "签发机关";
                         "issuing_date"      = "签发日期";
                       };
               front =  {
                         "address"    = "地址";
                         "brith_day"  = "出生日期";
                         "id_card_no" = "身份证号";
                         "name"       = "姓名";
                         "nation"     = "民族";
                         "sex"        = "性别";
                        };
     * */
    static async realPersonOCR(frontImagePixMap: PixelMap, backImagePixMap: PixelMap): Promise<Object> {
        if (!frontImagePixMap || !backImagePixMap || typeof frontImagePixMap === 'string' || typeof backImagePixMap === 'string') {
            console.log('进入判断啦啦啦啦啦啦啦啦');
            return new Promise((race) => {
                const result: Record<string, string> = { 'code': '-999', 'message': ' 图片不正确' };
                race(result);
            });
        }
        frontImagePixMap.getImageInfo();
        const pksId = CLConfigureUtil.getPksId();
        const pks = CLConfigureUtil.getPks();
        const random = CLStringUtil.generateRandomString(32).replace('-', '');
        const fontImageBuffer = await compressedImage(frontImagePixMap, 2 * 1024);
        const frontImageData = await CLGzipUtil.gzipAndAES(fontImageBuffer, random);
        const frontImageBase64 = CLStringUtil.uint8ArrayToBase64(frontImageData);
        const backImageBuffer = await compressedImage(backImagePixMap, 2 * 1024);
        const backImageData = await CLGzipUtil.gzipAndAES(backImageBuffer, random);
        const backImageBase64 = CLStringUtil.uint8ArrayToBase64(backImageData);
        const bundleId: string = bundleManager.getBundleInfoForSelfSync(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_SIGNATURE_INFO).name;
        const rsaRandomUUID = await CLSecurityUtils.encryptRSA(random, pks);
        const rsaRandomHex = CLStringUtil.uint8ArrayToHexString(rsaRandomUUID);
        let params: Record<string, string> = {
            'front_image': frontImageBase64,
            'back_image': backImageBase64,
            'image_type': 'BASE64',
            'platform_type': CLConfigureUtil.getPlatform(),
            'bundle_id': bundleId,
            'app_key': CLConfigureUtil.getAppId(),
            'auth_token': CLConfigureUtil.getToken(),
        };
        let headers: Record<string, string> = {
            'Content-Type': 'application/json',
            'Content-Encoding': 'gzip',
            'Data-Key': (pksId + rsaRandomHex),
        };
        CLLog.log('OCR识别 双面开始...');
        try {
            let r = await NetManager.post<CLResult<CLOCRSideMessage>>(CLNetContanst.getOCRIdcardDouble(), params, headers);
            if (r.code === '000000') {
                CLLog.log('OCR识别22222' + JSON.stringify(r));
                CLLog.log('OCR识别' + JSON.stringify(r.data.front.id_card_no));
                if (r.data && r.data.front) {
                    if (r.data.front.id_card_no) {
                        const idCardNum = await CLSecurityUtils.decryptRSAString(r.data.front.id_card_no, pks);
                        r.data.front.id_card_no = idCardNum;
                    }
                    if (r.data.front.name) {
                        const name = await CLSecurityUtils.decryptRSAString(r.data.front.name, pks);
                        r.data.front.name = name;
                    }
                }
            }
            CLLog.info(`OCR识别-双面识别：${JSON.stringify(r)}`);
            return r;
        }
        catch (e) {
            CLLog.error(`OCR识别-双面识别：${JSON.stringify(e)}`);
            return e;
        }
        return Promise.race('');
    }
    /**
     * 身份证认证
     * @param name：姓名
     * @param idNumber：身份证号码
     * @returns Promise<Object> 返回结果：
     * @example {
                  "order_no"  : "业务唯一流水号",
                  "city"      : "城市",
                  "country"   : "县区",
                  "gender"    : "性别：1：男、2：女",
                  "age"       : "年龄",
                  "remark"    : "备注，例：一致",
                  "birthday"  : "生日，格式是yyyyMMdd",
                  "result"    : "返回结果： 01-认证一致(收费) 02-认证不一致(收费) 03-认证不确定（收费）   04-认证失败(不收费)",
                  "handle_time" : "查询时间 例：2018-04-09 15:05:01",
                  "province"  : "省份"
                }
     * */
    static async realPersonDetect(name: string, idNumber: string): Promise<Object> {
        if (name.length <= 0 || idNumber.length <= 0) {
            return Promise.resolve(new CLCoreHttpResopnse('-1', 'name或者idNumber不能为空'));
        }
        const bundleId: string = bundleManager.getBundleInfoForSelfSync(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_SIGNATURE_INFO).name;
        const pks = CLConfigureUtil.getPks();
        const nameString = CLStringUtil.uint8ArrayToBase64(await CLSecurityUtils.encryptRSA(name, pks));
        const idNumberString = CLStringUtil.uint8ArrayToBase64(await CLSecurityUtils.encryptRSA(idNumber, pks));
        let params: Record<string, string> = {
            'platform_type': CLConfigureUtil.getPlatform(),
            'bundle_id': bundleId,
            'app_key': CLConfigureUtil.getAppId(),
            'auth_token': CLConfigureUtil.getToken(),
            'id_num': idNumberString,
            'name': nameString,
        };
        let headers: Record<string, string> = {
            'Content-Type': 'application/json',
        };
        try {
            let result = await NetManager.post<CLResult<CLOCRAuthOrderMessage>>(CLNetContanst.getOCRIdcardAuth(), params, headers);
            CLLog.log(`OCR识别-身份证校验：${JSON.stringify(result)}`);
            return result;
        }
        catch (e) {
            let error = e as BusinessError;
            let re: CLResult<any> = {
                code: error.code.toString(),
                message: error.message,
                data: undefined
            };
            CLLog.error(`OCR识别-身份证校验：${JSON.stringify(re)}`);
            return re;
        }
    }
}
