package com.heyu.api.controller.traffic;


import com.heyu.api.baidu.handle.traffic.BWaybillHandle;
import com.heyu.api.baidu.request.traffic.BWaybillRequest;
import com.heyu.api.baidu.response.traffic.BWaybillResp;
import com.heyu.api.controller.BaseController;
import com.heyu.api.data.annotation.CacheResult;
import com.heyu.api.data.annotation.CustomPath;
import com.heyu.api.data.utils.ApiR;
import com.heyu.api.data.utils.R;
import com.heyu.api.resp.traffic.WaybillResp;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.ArrayList;
import java.util.List;


/**
 * 快递面单识别控制器
 * <p>
 * 基于百度 OCR API，对常见快递面单进行结构化识别。
 * 支持主流快递公司的面单版式，提取运单号、收寄件人信息、地址等关键字段。
 * </p>
 * <p>
 * 支持的快递公司：
 * <ul>
 *   <li>主流快递：顺丰、京东、邮政、中通、圆通、申通、韵达、百世汇通、极兔、天天等</li>
 *   <li>其他快递：持续更新支持更多快递公司版式</li>
 * </ul>
 * </p>
 * <p>
 * 识别字段包括：
 * <ul>
 *   <li>运单信息：运单号、条形码、三段码</li>
 *   <li>收件人信息：姓名、电话、地址</li>
 *   <li>寄件人信息：姓名、电话、地址</li>
 *   <li>隐私面单：虚拟面单号、转接号、隐私面单标识</li>
 *   <li>图像信息：面单方向</li>
 * </ul>
 * </p>
 * <p>
 * 注意事项：
 * <ul>
 *   <li>支持隐私面单识别，需在请求中设置 is_identify_virtual_waybill=true</li>
 *   <li>需保证面单清晰、完整、无遮挡</li>
 *   <li>支持图片 URL 或 Base64 编码输入</li>
 *   <li>启用结果缓存以提升响应速度</li>
 * </ul>
 * </p>
 * <p>
 * 适用场景：
 * <ul>
 *   <li>物流管理：快递收发自动化录入</li>
 *   <li>仓库管理：出入库信息自动提取</li>
 *   <li>电商系统：订单物流信息对接</li>
 *   <li>快递驿站：批量处理快递面单</li>
 * </ul>
 * </p>
 * <p>
 * 接口路径：/waybill/recognize
 * </p>
 *
 * @author heyu
 * @since 1.0.0
 */
@Component
@Slf4j
@CustomPath("waybill")
public class WaybillController extends BaseController {


    @Autowired
    private BWaybillHandle bWaybillHandle;


    @RequestMapping("/recognize")
    @CacheResult
    public R recognize(BWaybillRequest request) {

        List<WaybillResp> respList = new ArrayList<>();


        ApiR<BWaybillResp> bR = bWaybillHandle.handle(request);
        if (bR.isSuccess()) {

            BWaybillResp bWaybillResp = bR.getData();
            if (CollectionUtils.isNotEmpty(bWaybillResp.getWordsResult())) {
                for (BWaybillResp.WordsResultDTO wordsResultDTO : bWaybillResp.getWordsResult()) {
                    WaybillResp resp = new WaybillResp();

                    resp.setImageInfo(wordsResultDTO.getImageInfo().getDirection());                 //	图像四方向

                    List<String> barCode = new ArrayList<>();               //条形码


                    if (CollectionUtils.isNotEmpty(wordsResultDTO.getBarCode())) {
                        for (BWaybillResp.WordsResultDTO.BarCodeDTO barCodeDTO : wordsResultDTO.getBarCode()) {

                            barCode.add(barCodeDTO.getWord());
                        }
                    }
                    resp.setBarCode(barCode);

                    List<String> waybillNumber = new ArrayList<>();           //快递运单号

                    if (CollectionUtils.isNotEmpty(wordsResultDTO.getWaybillNumber())) {
                        for (BWaybillResp.WordsResultDTO.WaybillNumberDTO waybillNumberDTO : wordsResultDTO.getWaybillNumber()) {
                            waybillNumber.add(waybillNumberDTO.getWord());
                        }
                    }
                    resp.setWaybillNumber(waybillNumber);

                    List<String> threeSegmentCode = new ArrayList<>();         //三段码
                    if (CollectionUtils.isNotEmpty(wordsResultDTO.getThreeSegmentCode())) {
                        for (BWaybillResp.WordsResultDTO.ThreeSegmentCodeDTO threeSegmentCodeDTO : wordsResultDTO.getThreeSegmentCode()) {
                            threeSegmentCode.add(threeSegmentCodeDTO.getWord());

                        }
                    }
                    resp.setThreeSegmentCode(threeSegmentCode);

                    List<String> recipientName = new ArrayList<>();   //收件人姓名
                    if (CollectionUtils.isNotEmpty(wordsResultDTO.getRecipientName())) {
                        for (BWaybillResp.WordsResultDTO.RecipientNameDTO recipientNameDTO : wordsResultDTO.getRecipientName()) {
                            recipientName.add(recipientNameDTO.getWord());

                        }
                    }
                    resp.setRecipientName(recipientName);

                    List<String> senderName = new ArrayList<>();         //寄件人姓名
                    if (CollectionUtils.isNotEmpty(wordsResultDTO.getSenderName())) {
                        for (BWaybillResp.WordsResultDTO.SenderNameDTO senderNameDTO : wordsResultDTO.getSenderName()) {
                            senderName.add(senderNameDTO.getWord());

                        }
                    }
                    resp.setSenderName(senderName);

                    List<String> recipientAddr = new ArrayList<>();           //收件人地址
                    if (CollectionUtils.isNotEmpty(wordsResultDTO.getRecipientAddr())) {
                        for (BWaybillResp.WordsResultDTO.RecipientAddrDTO recipientAddrDTO : wordsResultDTO.getRecipientAddr()) {
                            recipientAddr.add(recipientAddrDTO.getWord());

                        }
                    }
                    resp.setRecipientAddr(recipientAddr);

                    List<String> senderAddr = new ArrayList<>();             //寄件人地址
                    if (CollectionUtils.isNotEmpty(wordsResultDTO.getSenderAddr())) {
                        for (BWaybillResp.WordsResultDTO.SenderAddrDTO senderAddrDTO : wordsResultDTO.getSenderAddr()) {
                            senderAddr.add(senderAddrDTO.getWord());

                        }
                    }

                    resp.setSenderAddr(senderAddr);


                    List<String> recipientPhone = new ArrayList<>();         //收件人电话
                    if (CollectionUtils.isNotEmpty(wordsResultDTO.getRecipientPhone())) {
                        for (BWaybillResp.WordsResultDTO.RecipientPhoneDTO recipientPhoneDTO : wordsResultDTO.getRecipientPhone()) {
                            recipientPhone.add(recipientPhoneDTO.getWord());

                        }
                    }
                    resp.setRecipientPhone(recipientPhone);


                    List<String> senderPhone = new ArrayList<>(); // 寄件人电话String
                    if (CollectionUtils.isNotEmpty(wordsResultDTO.getSenderPhone())) {
                        for (BWaybillResp.WordsResultDTO.SenderPhoneDTO senderPhoneDTO : wordsResultDTO.getSenderPhone()) {
                            senderPhone.add(senderPhoneDTO.getWord());

                        }
                    }
                    resp.setSenderPhone(senderPhone);

                    List<String> virtualNumber = new ArrayList<>(); //虚拟面单号。当请求参数 is_identify_virtual_waybill = true 时返回该字段
                    if (CollectionUtils.isNotEmpty(wordsResultDTO.getVirtualNumber())) {
                        for (BWaybillResp.WordsResultDTO.SenderPhoneDTO senderPhoneDTO : wordsResultDTO.getVirtualNumber()) {
                            virtualNumber.add(senderPhoneDTO.getWord());
                        }
                    }

                    resp.setVirtualNumber(virtualNumber);

                    List<String> virtualNumberLast = new ArrayList<>(); //隐私面单的4位转接号。当请求参数 is_identify_virtual_waybill = true 时返回该字段
                    if (CollectionUtils.isNotEmpty(wordsResultDTO.getVirtualNumberLast())) {
                        for (BWaybillResp.WordsResultDTO.SenderPhoneDTO senderPhoneDTO : wordsResultDTO.getVirtualNumberLast()) {
                            virtualNumberLast.add(senderPhoneDTO.getWord());
                        }
                    }

                    resp.setVirtualNumberLast(virtualNumberLast);
                    List<String> isVirtualWaybill = new ArrayList<>(); // 此张快递面单是否为隐私面单，“true”代表“是”，“false”代表“否”。当请求参数 is_identify_virtual_waybill = true 时返回该字段
                    if (CollectionUtils.isNotEmpty(wordsResultDTO.getIsVirtualWaybill())) {
                        for (BWaybillResp.WordsResultDTO.SenderPhoneDTO senderPhoneDTO : wordsResultDTO.getIsVirtualWaybill()) {
                            isVirtualWaybill.add(senderPhoneDTO.getWord());
                        }
                    }
                    resp.setIsVirtualWaybill(isVirtualWaybill);

                    respList.add(resp);
                }
            }
            return R.ok().setData(respList);
        }
        return R.error();
    }


}
