package com.heyu.api.controller.car;

import com.heyu.api.baidu.request.traffic.BVehicleLicenseRequest;
import com.heyu.api.controller.BaseController;
import com.heyu.api.data.annotation.EbAuthentication;
import com.heyu.api.data.annotation.NotIntercept;
import com.heyu.api.data.constants.ApiConstants;
import com.heyu.api.data.utils.MapUtils;
import com.heyu.api.data.utils.R;
import com.heyu.api.data.utils.StringUtils;
import com.heyu.api.request.car.VehicleLicenseRequest;
import com.heyu.api.resp.car.RecognizeDrivingLicenseBackResp;
import com.heyu.api.resp.car.RecognizeDrivingLicenseFaceResp;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;


/**
 * 行驶证识别。
 * https://console.bce.baidu.com/support/?_=1740219852952&timestamp=1740323990690#/api?product=AI&project=%E6%96%87%E5%AD%97%E8%AF%86%E5%88%AB&parent=%E4%BA%A4%E9%80%9A%E5%9C%BA%E6%99%AFOCR&api=rest%2F2.0%2Focr%2Fv1%2Fvehicle_license&method=post
 */
@Slf4j
@RestController
@RequestMapping("/driving/license")
@SuppressWarnings("unchecked")
public class RecognizeDrivingLicenseController extends BaseController {

    // http://localhost:8888/driving/license/recognize
    // {"side":"front","imageUrl":"https://q1.itc.cn/q_70/images03/20241016/622799fe72cb49f49e16b7f253e75b29.jpeg"}
    // https://api.1024api.com/api-interface/driving/license/recognize
    @EbAuthentication(tencent = ApiConstants.TENCENT_AUTH)
    @PostMapping("/recognize")
    public R<Object> recognize(@RequestBody VehicleLicenseRequest request) {
        long start = System.currentTimeMillis();

        long t1 = System.currentTimeMillis();
        BVehicleLicenseRequest bVehicleLicenseRequest = toBaiduRequest(request);
        String checkMsg = checkRequest(bVehicleLicenseRequest);
        if (!isBlank(checkMsg)) {
            return R.error(checkMsg);
        }
        log.info("行驶证识别-参数校验及构建请求耗时:{}ms", System.currentTimeMillis() - t1);

        long t2 = System.currentTimeMillis();
        Map<String, Object> data = requestBaidu(getContent(bVehicleLicenseRequest));
        long baiduCost = System.currentTimeMillis() - t2;
        log.info("行驶证识别-调用百度OCR接口耗时:{}ms", baiduCost);

        if (data == null) {
            log.info("行驶证识别-识别失败, 耗时:{}ms", System.currentTimeMillis() - start);
            return R.error("行驶证识别失败");
        }

        long t3 = System.currentTimeMillis();
        R<Object> result = R.ok();
        result.setData(toRecognizeResp(bVehicleLicenseRequest.getVehicleLicenseSide(), data));
        log.info("行驶证识别-结果映射耗时:{}ms", System.currentTimeMillis() - t3);

        log.info("行驶证识别-总耗时:{}ms, 其中第三方(百度OCR):{}ms", System.currentTimeMillis() - start, baiduCost);
        return result;
    }

    private BVehicleLicenseRequest toBaiduRequest(VehicleLicenseRequest request) {
        BVehicleLicenseRequest bVehicleLicenseRequest = new BVehicleLicenseRequest();
        if (request == null) {
            return bVehicleLicenseRequest;
        }
        bVehicleLicenseRequest.setImageUrl(request.getImageUrl());
        bVehicleLicenseRequest.setImageBase64(request.getImageBase64());
        if (StringUtils.isNotBlank(request.getSide())) {
            bVehicleLicenseRequest.setVehicleLicenseSide(request.getSide());
        }
        return bVehicleLicenseRequest;
    }

    private String checkRequest(BVehicleLicenseRequest request) {
        if (!hasImage(request)) {
            return "imageUrl和imageBase64不能同时为空";
        }
        if (checkNotTrueFalse(request.getDetectDirection())) {
            return "detectDirection 必须传 " + ApiConstants.trueOrFalse + ",false：不进行图像方向自动矫正, true: 开启图像方向自动矫正功能，可对旋转 90/180/270 度的图片进行自动矫正并识别";
        }
        if (checkNotFrontBack(request.getVehicleLicenseSide())) {
            return "front 必须传 " + ApiConstants.frontOrback + ",front：正向， back反面";
        }
        if (checkNotTrueFalse(request.getUnified())) {
            return "unified必须为 " + ApiConstants.trueOrFalse + ", false 不进行归一化处理, rue：对输出字段进行归一化处理，将新/老版行驶证的“注册登记日期/注册日期”统一为”注册日期“进行输出";
        }
        if (checkNotTrueFalse(request.getQualityWarn())) {
            return "qualityWarn 必须为" + ApiConstants.trueOrFalse + ",false：不输出质量告警信息, true : 输出行驶证遮挡、不完整质量告警信息";
        }
        return null;
    }

    private boolean hasImage(BVehicleLicenseRequest request) {
        return request != null && (!isBlank(request.getImageUrl()) || !isBlank(request.getImageBase64()));
    }

    private String getContent(BVehicleLicenseRequest request) {
        StringBuffer sb = getImageContent(request);
        if (StringUtils.isNotBlank(request.getDetectDirection())) {
            sb.append("&detect_direction=").append(request.getDetectDirection());
        }
        if (StringUtils.isNotBlank(request.getVehicleLicenseSide())) {
            sb.append("&vehicle_license_side=").append(request.getVehicleLicenseSide());
        }
        if (StringUtils.isNotBlank(request.getUnified())) {
            sb.append("&unified=").append(request.getUnified());
        }
        if (StringUtils.isNotBlank(request.getQualityWarn())) {
            sb.append("&quality_warn=").append(request.getQualityWarn());
        }
        if (StringUtils.isNotBlank(request.getRiskWarn())) {
            sb.append("&risk_warn=").append(request.getRiskWarn());
        }
        return sb.toString();
    }

    private StringBuffer getImageContent(BVehicleLicenseRequest request) {
        StringBuffer sb = new StringBuffer();
        if (StringUtils.isNotBlank(request.getImageBase64())) {
            sb.append("&image=").append(request.getImageBase64());
        }

        if (StringUtils.isNotBlank(request.getImageUrl())) {
            sb.append("&url=").append(request.getImageUrl());
        }
        return sb;
    }

    private boolean checkNotTrueFalse(String value) {
        return !ApiConstants.trueOrFalse.contains(value);
    }

    private boolean checkNotFrontBack(String value) {
        return !ApiConstants.frontOrback.contains(value);
    }

    private Object toRecognizeResp(String side, Map<String, Object> data) {
        if (ApiConstants.front.equals(side)) {
            return toFaceResp(data);
        }
        return toBackResp(data);
    }

    private RecognizeDrivingLicenseFaceResp toFaceResp(Map<String, Object> data) {
        RecognizeDrivingLicenseFaceResp faceResp = new RecognizeDrivingLicenseFaceResp();
        faceResp.setIssueDate(MapUtils.getByExpr(data, "words_result.发证日期.words"));
        faceResp.setIssueAuthority(MapUtils.getByExpr(data, "words_result.发证单位.words"));
        faceResp.setModel(MapUtils.getByExpr(data, "words_result.品牌型号.words"));
        faceResp.setVehicleType(MapUtils.getByExpr(data, "words_result.车辆类型.words"));
        faceResp.setOwner(MapUtils.getByExpr(data, "words_result.所有人.words"));
        faceResp.setEngineNumber(MapUtils.getByExpr(data, "words_result.发动机号码.words"));
        faceResp.setPlateNumber(MapUtils.getByExpr(data, "words_result.号牌号码.words"));
        faceResp.setAddress(MapUtils.getByExpr(data, "words_result.住址.words"));
        faceResp.setUseCharacter(MapUtils.getByExpr(data, "words_result.使用性质.words"));
        faceResp.setVin(MapUtils.getByExpr(data, "words_result.车辆识别代号.words"));
        faceResp.setRegisterDate(MapUtils.getByExpr(data, "words_result.注册日期.words"));
        return faceResp;
    }

    private RecognizeDrivingLicenseBackResp toBackResp(Map<String, Object> data) {
        RecognizeDrivingLicenseBackResp backResp = new RecognizeDrivingLicenseBackResp();
        backResp.setOverallDimension(MapUtils.getByExpr(data, "words_result.外廓尺寸.words"));
        backResp.setInspectionRecord(MapUtils.getByExpr(data, "words_result.检验记录.words"));
        backResp.setUnladenMass(MapUtils.getByExpr(data, "words_result.整备质量.words"));
        backResp.setFileNumber(MapUtils.getByExpr(data, "words_result.档案编号.words"));
        backResp.setTractionMass(MapUtils.getByExpr(data, "words_result.准牵引总质量.words"));
        backResp.setGrossMass(MapUtils.getByExpr(data, "words_result.总质量.words"));
        backResp.setPlateNumber(MapUtils.getByExpr(data, "words_result.号牌号码.words"));
        backResp.setApprovedPassengerCapacity(MapUtils.getByExpr(data, "words_result.核定载人数.words"));
        backResp.setEnergyType(MapUtils.getByExpr(data, "words_result.燃油类型.words"));
        backResp.setApprovedLoad(MapUtils.getByExpr(data, "words_result.核定载质量.words"));
        backResp.setRemark(MapUtils.getByExpr(data, "words_result.备注.words"));
        backResp.setCertificateNumber(MapUtils.getByExpr(data, "words_result.证芯编号.words"));
        return backResp;
    }

}
