package com.heyu.api.controller.car;

import com.heyu.api.baidu.handle.financial.BTaxiReceiptHandle;
import com.heyu.api.baidu.request.financial.BTaxiReceiptRequest;
import com.heyu.api.baidu.response.financial.BTaxiReceiptResp;
import com.heyu.api.controller.BaseController;
import com.heyu.api.data.annotation.NotIntercept;
import com.heyu.api.data.utils.ApiR;
import com.heyu.api.data.utils.R;
import com.heyu.api.request.car.TaxiInvoiceRecognizeRequest;
import com.heyu.api.resp.car.RecognizeTaxiInvoiceResp;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
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.io.UnsupportedEncodingException;
import java.net.URLEncoder;

/**
 * https://console.bce.baidu.com/support/#/api?product=AI&project=文字识别&parent=财务票据OCR&api=rest%2F2.0%2Focr%2Fv1%2Ftaxi_receipt&method=post
 *
 * 出租车发票识别（百度OCR）
 *
 * 支持识别全国各大城市的出租车票的全部字段，包括发票号码、发票代码、电话、日期、金额、
 * 上下车时间、里程等。
 */
@Slf4j
@RestController
@RequestMapping("/taxi/invoice")
@NotIntercept
public class RecognizeTaxiInvoiceController extends BaseController {

    @Autowired
    private BTaxiReceiptHandle bTaxiReceiptHandle;

    @PostMapping("/recognize")
    public R recognize(@RequestBody TaxiInvoiceRecognizeRequest request) {
        long start = System.currentTimeMillis();

        if (request == null) {
            return R.error("请求参数不能为空");
        }
        if (isBlank(request.getImageBase64()) && isBlank(request.getImageUrl())) {
            return R.error("imageBase64和imageUrl不能同时为空");
        }
        log.info("出租车发票识别-参数校验耗时:{}ms", System.currentTimeMillis() - start);

        long t1 = System.currentTimeMillis();
        BTaxiReceiptRequest bRequest = toBaiduRequest(request);
        log.info("出租车发票识别-构建百度请求耗时:{}ms", System.currentTimeMillis() - t1);

        long t2 = System.currentTimeMillis();
        ApiR<BTaxiReceiptResp> apiR = bTaxiReceiptHandle.handle(bRequest);
        long baiduCost = System.currentTimeMillis() - t2;
        log.info("出租车发票识别-调用百度OCR接口耗时:{}ms", baiduCost);

        if (apiR == null || !apiR.isSuccess() || apiR.getData() == null) {
            return R.error(thirdError(apiR));
        }

        long t3 = System.currentTimeMillis();
        BTaxiReceiptResp bResp = apiR.getData();
        BTaxiReceiptResp.WordsResultDTO wordsResult = bResp.getWordsResult();
        if (wordsResult == null) {
            log.info("出租车发票识别-未识别到发票信息, 耗时:{}ms", System.currentTimeMillis() - start);
            return R.error("未识别到出租车发票信息");
        }

        RecognizeTaxiInvoiceResp resp = toResp(wordsResult);
        log.info("出租车发票识别-结果映射耗时:{}ms", System.currentTimeMillis() - t3);

        log.info("出租车发票识别-总耗时:{}ms, 其中第三方(百度OCR):{}ms", System.currentTimeMillis() - start, baiduCost);
        return R.ok().setData(resp);
    }

    private BTaxiReceiptRequest toBaiduRequest(TaxiInvoiceRecognizeRequest request) {
        BTaxiReceiptRequest bRequest = new BTaxiReceiptRequest();
        if (isNotBlank(request.getImageBase64())) {
            bRequest.setImageBase64(encodeParam(request.getImageBase64()));
        }
        if (isNotBlank(request.getImageUrl())) {
            bRequest.setImageUrl(encodeParam(request.getImageUrl()));
        }
        return bRequest;
    }

    private RecognizeTaxiInvoiceResp toResp(BTaxiReceiptResp.WordsResultDTO wordsResult) {
        RecognizeTaxiInvoiceResp resp = new RecognizeTaxiInvoiceResp();
        resp.setDate(wordsResult.getDate());
        resp.setFare(wordsResult.getFare());
        resp.setLocation(wordsResult.getLocation());
        resp.setInvoiceCode(wordsResult.getInvoiceCode());
        resp.setInvoiceNum(wordsResult.getInvoiceNum());
        resp.setTaxiNum(wordsResult.getTaxiNum());
        resp.setTime(wordsResult.getTime());
        resp.setPickupTime(wordsResult.getPickupTime());
        resp.setDropoffTime(wordsResult.getDropoffTime());
        resp.setFuelOilSurcharge(wordsResult.getFuelOilSurcharge());
        resp.setCallServiceSurcharge(wordsResult.getCallServiceSurcharge());
        resp.setTotalFare(wordsResult.getTotalFare());
        resp.setProvince(wordsResult.getProvince());
        resp.setCity(wordsResult.getCity());
        resp.setPricePerkm(wordsResult.getPricePerkm());
        resp.setDistance(wordsResult.getDistance());
        return resp;
    }

    private String encodeParam(String value) {
        try {
            return URLEncoder.encode(value, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            log.error("URL编码失败:{}", value, e);
            return value;
        }
    }

    private boolean isNotBlank(String value) {
        return value != null && value.trim().length() > 0;
    }
}
