package com.cool.store.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.aliyun.dytnsapi20200217.Client;
import com.aliyun.dytnsapi20200217.models.DescribePhoneNumberOperatorAttributeRequest;
import com.aliyun.dytnsapi20200217.models.DescribePhoneNumberOperatorAttributeResponse;
import com.aliyun.ocr20191230.models.RecognizeIdentityCardResponse;
import com.aliyun.ocr20191230.models.RecognizeIdentityCardResponseBody;
import com.aliyun.teaopenapi.models.Config;
import com.cool.store.dto.partner.DescribePhoneNumberDTO;
import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.enums.IDCardSideEnum;
import com.cool.store.exception.ApiException;
import com.cool.store.exception.ServiceException;
import com.cool.store.service.AliyunService;
import com.cool.store.vo.cuser.IdentityCardInfoVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Objects;
import java.util.Optional;

/**
 * @author zhangchenbiao
 * @FileName: AliyunServiceImpl
 * @Description:
 * @date 2023-06-15 20:04
 */
@Slf4j
@Service
public class AliyunServiceImpl implements AliyunService {

    @Value("${aliyun.accessKeyId:null}")
    private String accessKeyId;

    @Value("${aliyun.accessKeySecret:null}")
    private String accessKeySecret;

    @Value("${aliyun.authCode:null}")
    private String authCode;

    @Override
    public DescribePhoneNumberDTO getPhoneNumberAttribute(String phoneNumber) {
        try {
            Config config = new Config();
            config.accessKeyId = accessKeyId;
            config.accessKeySecret = accessKeySecret;
            Client client = new Client(config);
            DescribePhoneNumberOperatorAttributeRequest request = new DescribePhoneNumberOperatorAttributeRequest();
            request.authCode = authCode;
            request.inputNumber = phoneNumber;
            request.mask = "NORMAL";
            DescribePhoneNumberOperatorAttributeResponse response = client.describePhoneNumberOperatorAttribute(request);
            String code = response.body.code;
            if (!com.aliyun.teautil.Common.equalString(code, "OK")) {
                log.error("错误信息:" , response.body.message + "");
                throw new ServiceException(ErrorCodeEnum.GET_PHONENUMBER_INFO_ERROR);
            }
            return JSONObject.parseObject(JSONObject.toJSONString(response.body.data), DescribePhoneNumberDTO.class);
        } catch (Exception e) {
            log.error("获取手机号异常：", e);
            throw new ServiceException(ErrorCodeEnum.GET_PHONENUMBER_INFO_ERROR);
        }
    }

    @Override
    public IdentityCardInfoVO getIdentityCardInfo(String faceImageUrl, IDCardSideEnum sideEnum) throws ApiException {
        //todo zcb ak sk替换
        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
                .setAccessKeyId(accessKeyId)
                .setAccessKeySecret(accessKeySecret);
        // 访问的域名
        config.endpoint = "ocr.cn-shanghai.aliyuncs.com";
        try {
            com.aliyun.ocr20191230.Client client = new com.aliyun.ocr20191230.Client(config);
            URL url = new URL(faceImageUrl);
            InputStream inputStream = url.openConnection().getInputStream();
            com.aliyun.ocr20191230.models.RecognizeIdentityCardAdvanceRequest recognizeIdentityCardAdvanceRequest = new com.aliyun.ocr20191230.models.RecognizeIdentityCardAdvanceRequest()
                    .setImageURLObject(inputStream)
                    .setSide(sideEnum.getCode());
            com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
            RecognizeIdentityCardResponse idCardResponse = client.recognizeIdentityCardAdvance(recognizeIdentityCardAdvanceRequest, runtime);
            log.info("身份证解析结果：{}", JSONObject.toJSONString(idCardResponse));
            RecognizeIdentityCardResponseBody.RecognizeIdentityCardResponseBodyDataFrontResult frontResult = Optional.ofNullable(idCardResponse).map(o -> o.getBody()).map(o -> o.data).map(o -> o.frontResult).orElse(null);
            if(Objects.nonNull(frontResult)){
                String username = frontResult.name;
                String liveAddress = frontResult.address;
                String birthdate = frontResult.birthDate;
                if(StringUtils.isNotBlank(birthdate)){
                    birthdate = convertDate(birthdate, "yyyyMMdd");
                }
                String sex = frontResult.gender;
                String idCard = frontResult.IDNumber;
                String nation = frontResult.nationality;
                IdentityCardInfoVO result = new IdentityCardInfoVO(username, liveAddress, birthdate, sex, idCard, nation);
                log.info("身份证解析：{}", JSONObject.toJSONString(result));
                return result;
            }
            return null;
        } catch (com.aliyun.tea.TeaException e) {
            log.error("身份证解析报错TeaException：{}", e);
            throw new ApiException(e.getMessage());
        } catch (MalformedURLException e) {
            log.error("身份证解析报错MalformedURLException：{}", e);
            throw new ApiException(e.getMessage());
        } catch (IOException e) {
            log.error("身份证解析报错IOException：{}", e);
            throw new ApiException(e.getMessage());
        } catch (Exception e) {
            log.error("身份证解析报错Exception：{}", e);
            throw new ApiException(e.getMessage());
        }
    }

    public static String convertDate(String date, String format) {
        try {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format);
            LocalDate localDate = LocalDate.parse(date, formatter);
            return localDate.toString();
        } catch (Exception e) {
            throw new ServiceException(ErrorCodeEnum.DATA_CONVERT_ERROR);
        }
    }


}
