package com.bcxin.backend.domain.signature.service.impls.vos;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.IdcardUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bcxin.backend.core.exceptions.SaasRetryableException;
import com.bcxin.backend.domain.utils.StringUtils;
import com.bcxin.saas.core.utils.RetryUtil;
import com.github.rholder.retry.RetryException;
import lombok.Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Data
public class CertificateVo {
    public static final String ZHXINXI_HEAD_PHOTO_NOT_EXISTS_YET="图片检测不正确";
    private final static Logger logger = LoggerFactory.getLogger(CertificateVo.class);

    private String id;
    private String item_securityname;
    private String item_documentid;
    private String item_idaddress;
    private String item_certificateno;
    private String item_certificatefrom;
    private String item_certificatedate;
    private String item_headphoto;
    private String created;
    private String item_signatured_processed_status;
    private String author;

    /**
     * 多出来处理后的数据
     */
    private ProcessStatus processStatus;
    private String processResult;
    private String processJson;

    public void assignProcessJson(String processJson) {
        this.setProcessJson(processJson);
    }

    public String getCertificatedate() {
        String certificatedate = this.getItem_certificatedate();
        if (org.apache.commons.lang3.StringUtils.isEmpty(certificatedate)) {
            certificatedate = DateUtil.today();
        } else {
            certificatedate = DateUtil.format(DateUtil.parseDate(certificatedate), "yyyy-MM-dd");
        }

        return certificatedate;
    }

    public Short getYearFromIdCard() {
        return IdcardUtil.getYearByIdCard(this.getItem_documentid());
    }

    public Short getMonthFromIdCard() {
        return IdcardUtil.getMonthByIdCard(this.getItem_documentid());
    }

    public Short getDayFromIdCard() {
        return IdcardUtil.getDayByIdCard(this.getItem_documentid());
    }

    private String _headerPhoto;

    public String getHeadPhoto() {
        if (StringUtils.isEmpty(_headerPhoto)) {
            String hPhoto = this.getItem_headphoto();
            if (StringUtils.isEmpty(hPhoto)) {
                return "";
            }

            try {
                JSONArray array = JSONArray.parseArray(hPhoto);
                _headerPhoto = array.stream().map(ii -> ((JSONObject) ii).getString("path"))
                        .filter(ii -> !StringUtils.isEmpty(ii))
                        .findFirst().orElse("");
            } catch (Exception ex) {
                logger.error("无效的头像数据:id={}, photo={}", this.getId(), this.getItem_headphoto());
                return hPhoto;
            }
        }

        return _headerPhoto;
    }

    public void doCheckIdAddress() {
        String idAddress = this.getItem_idaddress();
        if (StringUtils.isEmpty(idAddress)) {
            this.setProcessStatus(ProcessStatus.ZHXINXI_ADDERSS);
            this.setProcessResult(ProcessStatus.ZHXINXI_ADDERSS.getText());
        } else {
            idAddress = idAddress.replace("，", "");
            if (idAddress.length() < 5) {
                this.setProcessStatus(ProcessStatus.ZHXINXI_ADDERSS);
                this.setProcessResult(String.format("%s-身份证地址无效", ProcessStatus.ZHXINXI_ADDERSS.getText()));
            }
        }
    }

    public void doCheckPhoto() {
        String headPhoto = this.getItem_headphoto();
        if (StringUtils.isEmpty(headPhoto)) {
            this.setProcessStatus(ProcessStatus.ZHXINXI_HEAD_PHOTO);
            this.setProcessResult(String.format("%s-%s.", ProcessStatus.ZHXINXI_HEAD_PHOTO.getText(), headPhoto));
        }
    }

    public boolean doCheck(String urlHead) {
        this.doCheckIdAddress();
        this.doCheckPhoto();

        boolean validData = IdcardUtil.isValidCard(this.getItem_documentid());
        if (validData) {
            validData =
                    StringUtils.isNotEmpty(this.getItem_securityname()) &&
                            StringUtils.isNotEmpty(this.getItem_documentid()) &&
                            StringUtils.isNotEmpty(this.getItem_idaddress()) &&
                            StringUtils.isNotEmpty(this.getItem_certificateno()) &&
                            StringUtils.isNotEmpty(this.getItem_certificatefrom());
        } else {
            logger.error("证书数据(id={})的身份证信息({})无效", this.getId(), this.getItem_documentid());
        }

        if (this.getProcessStatus() == ProcessStatus.SUCCESS && !validData) {
            this.setProcessStatus(ProcessStatus.ZHXINXI_BUQUAN);
            if (!StringUtils.isNotEmpty(this.getItem_securityname())) {
                this.setProcessResult(String.format("%s-姓名信息缺失", ProcessStatus.ZHXINXI_BUQUAN.getText()));
            } else if (!StringUtils.isNotEmpty(this.getItem_idaddress())) {
                this.setProcessResult(String.format("%s-身份证地址缺失", ProcessStatus.ZHXINXI_BUQUAN.getText()));
            } else if (!StringUtils.isNotEmpty(this.getItem_certificateno())) {
                this.setProcessResult(String.format("%s-证书编号缺失", ProcessStatus.ZHXINXI_BUQUAN.getText()));
            } else if (!StringUtils.isNotEmpty(this.getItem_certificatefrom())) {
                this.setProcessResult(String.format("%s-发证机关缺失", ProcessStatus.ZHXINXI_BUQUAN.getText()));
            }
        } else {
            String cPhoto = this.getHeadPhoto();
            if (StringUtils.isEmpty(cPhoto)) {
                this.setProcessStatus(ProcessStatus.ZHXINXI_HEAD_PHOTO);
                this.setProcessResult(ProcessStatus.ZHXINXI_HEAD_PHOTO.getText());
            } else {
                String checkPhotoUrl = cPhoto;
                if (!cPhoto.startsWith("http")) {
                    checkPhotoUrl = urlHead + checkPhotoUrl;
                }

                /**
                 * 无效的路径
                 */
                if (!org.springframework.util.StringUtils.hasLength(checkPhotoUrl) ||
                        checkPhotoUrl.length() < 10 ||
                        checkPhotoUrl.contains("[{")) {
                    this.setProcessStatus(ProcessStatus.ZHXINXI_HEAD_PHOTO);
                    this.setProcessResult(String.format("%s:%s", ProcessStatus.ZHXINXI_HEAD_PHOTO.getText(), checkPhotoUrl));
                } else if (!doesFileExist(checkPhotoUrl)) {
                    this.setProcessStatus(ProcessStatus.ZHXINXI_HEAD_PHOTO);
                    this.setProcessResult(ZHXINXI_HEAD_PHOTO_NOT_EXISTS_YET);
                }
            }
        }

        return this.getProcessStatus() == ProcessStatus.SUCCESS;
    }

    public boolean doesFileExist(String urlString) {
        try {
            return RetryUtil.execute(() -> {
                HttpResponse response = HttpRequest.get(urlString).execute();
                if (response.getStatus() == 200) {
                    return true;
                }
                logger.error("图片检测失败：{};status={}", urlString, response.getStatus());

                ThreadUtil.sleep(1000);
                throw new SaasRetryableException(String.format("重试检测图片信息:%s",urlString));
            }, 5);
        } catch (Exception ex) {
            logger.error("重新检测之后，还是找不到图片信息:{}", urlString, ex);
        }

        return false;
    }

    public static CertificateVo create(String id, String item_securityname, String item_documentid,
                                       String item_idaddress, String item_certificateno, String item_certificatefrom,
                                       String item_certificatedate, String item_headphoto, String created,
                                       String item_signatured_processed_status,
                                       String author) {
        CertificateVo certificateVo = new CertificateVo();
        certificateVo.setId(id);
        certificateVo.setItem_securityname(item_securityname);
        certificateVo.setItem_documentid(item_documentid);
        certificateVo.setItem_idaddress(item_idaddress);
        certificateVo.setItem_certificateno(item_certificateno);
        certificateVo.setItem_certificatefrom(item_certificatefrom);
        certificateVo.setItem_certificatedate(item_certificatedate);
        certificateVo.setItem_headphoto(item_headphoto);
        certificateVo.setCreated(created);
        certificateVo.setItem_signatured_processed_status(item_signatured_processed_status);
        certificateVo.setProcessStatus(ProcessStatus.SUCCESS);
        certificateVo.setAuthor(author);

        return certificateVo;
    }

    public static enum ProcessStatus {
        ZHXINXI_BUQUAN {
            public String getText() {
                return ("证书信息不全");
            }

            @Override
            public String getSql() {
                return "UPDATE tlk_certificate SET ITEM_signatured_processed_status = 3,ITEM_last_signatured_processed_result = '证书信息不全'";
            }
        },
        ZHXINXI_ADDERSS {
            public String getText() {
                return ("证书信息不全（身份证住址）");
            }

            @Override
            public String getSql() {
                return "UPDATE tlk_certificate SET ITEM_signatured_processed_status = 3,ITEM_last_signatured_processed_result = '证书信息不全（身份证住址）'";
            }
        },
        ZHXINXI_HEAD_PHOTO {
            public String getText() {
                return ("证书信息不全（身份证头像）");
            }

            @Override
            public String getSql() {
                return "UPDATE tlk_certificate SET ITEM_signatured_processed_status = 3,ITEM_last_signatured_processed_result = '证书信息不全（身份证头像）'";
            }
        },
        ZHXINXI_HEAD_PHOTO_ADDRESS {
            public String getText() {
                return ("证书信息不全（身份证头像、身份证住址）");
            }

            @Override
            public String getSql() {
                return "UPDATE tlk_certificate SET ITEM_signatured_processed_status = 3,ITEM_last_signatured_processed_result = '证书信息不全（身份证头像、身份证住址）'";
            }
        },
        SUCCESS {
            public String getText() {
                return ("数据正确");
            }

            @Override
            public String getSql() {
                return  "UPDATE tlk_certificate SET ITEM_last_signatured_processed_result = '',ITEM_signatured_processed_status = 1,ITEM_signatured_operator = '\"+operator+\"',ITEM_signatured_time = now(),ITEM_CERTIFICATEDATE = IFNULL(ITEM_CERTIFICATEDATE, NOW())";
            }
        };

        public abstract String getText();

        public abstract String getSql();

        public String getInsertSql(){
            return "INSERT INTO obpm2_security.signature_queues (version,template_url,DATA,STATUS,business_id,createdTime,creator,certificatedate)VALUES(?,?,?,?,?,?,?,?)";
        }
    }
}
