package com.yd.csf.api.service.impl;

import com.yd.base.feign.client.relobjectcertificate.ApiRelObjectCertificateFeignClient;
import com.yd.base.feign.dto.ApiCertificateDto;
import com.yd.base.feign.request.relobjectcertificate.ApiRelObjectCertificateListAddRequest;
import com.yd.base.feign.request.relobjectcertificate.ApiRelObjectCertificateListRequest;
import com.yd.base.feign.response.relobjectcertificate.ApiRelObjectCertificateListResponse;
import com.yd.common.enums.CommonEnum;
import com.yd.common.enums.ResultCode;
import com.yd.common.exception.BusinessException;
import com.yd.common.result.Result;
import com.yd.common.utils.RandomStringGenerator;
import com.yd.csf.api.service.ApiAppointmentCheckService;
import com.yd.csf.api.service.ApiPolicyholderService;
import com.yd.csf.api.service.ApiTaxationService;
import com.yd.csf.feign.dto.appointment.ApiPolicyholderInfoDto;
import com.yd.csf.feign.dto.taxation.ApiObjectTaxationDto;
import com.yd.csf.feign.utils.CommonUtil;
import com.yd.csf.service.model.Policyholder;
import com.yd.csf.service.service.IPolicyholderService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 投保人信息业务实现类
 */
@Slf4j
@Service
public class ApiPolicyholderServiceImpl implements ApiPolicyholderService {

    @Autowired
    private IPolicyholderService iPolicyholderService;

    @Autowired
    private ApiAppointmentCheckService apiAppointmentCheckService;

    @Autowired
    private ApiTaxationService apiTaxationService;

    @Autowired
    private ApiRelObjectCertificateFeignClient apiRelObjectCertificateFeignClient;

    /**
     * 投保人信息详情
     * @param appointmentBizId 预约信息主表唯一业务ID
     * @param policyholderBizId 投保人信息表唯一业务ID
     * @return
     */
    @Override
    public Result<ApiPolicyholderInfoDto> detail(String appointmentBizId,
                                                 String policyholderBizId) {
        Policyholder policyholder = iPolicyholderService.queryOne(appointmentBizId,policyholderBizId);
        ApiPolicyholderInfoDto dto = null;
        if (!Objects.isNull(policyholder)) {
            dto = new ApiPolicyholderInfoDto();
            BeanUtils.copyProperties(policyholder,dto);
            //地址列表
            dto.setAddressList(CommonUtil.getAddressList(policyholder.getAddressList()));

            dto.setApiCertificateDtoList(apiCertificateDtoList(policyholder.getPolicyholderBizId()));

            dto.setApiTaxationDtoList(apiTaxationService.apiTaxationDtoList(policyholder.getPolicyholderBizId()));
        }
        return Result.success(dto);
    }

    /**
     * 查询证件列表信息
     * @param policyholderBizId
     * @return
     */
    public List<ApiCertificateDto> apiCertificateDtoList(String policyholderBizId) {
        List<ApiCertificateDto> apiCertificateDtoList = new ArrayList<>();
        //查询投保人证件列表信息
        Result<List<ApiRelObjectCertificateListResponse>> result = apiRelObjectCertificateFeignClient.list(ApiRelObjectCertificateListRequest.builder()
                .objectBizId(policyholderBizId)
                .build());
        if (!CollectionUtils.isEmpty(result.getData())) {
            apiCertificateDtoList = result.getData().stream().map(dto -> {
                ApiCertificateDto apiCertificateDto = new ApiCertificateDto();
                BeanUtils.copyProperties(dto,apiCertificateDto);
                return apiCertificateDto;
            }).collect(Collectors.toList());
        }
        return apiCertificateDtoList;
    }

    /**
     * 编辑投保人信息
     * @param apiPolicyholderInfoDto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result edit(ApiPolicyholderInfoDto apiPolicyholderInfoDto) {
        //编辑预约入参字段校验 - 投保人信息字段校验
        apiAppointmentCheckService.checkEditApiPolicyholderInfoDto(apiPolicyholderInfoDto);
        //编辑投保人信息表数据
//        editPolicyholderData(apiPolicyholderInfoDto,apiPolicyholderInfoDto.getAppointmentBizId());
        return Result.success();
    }

    /**
     * 添加投保人信息表数据
     * @param dto
     * @param appointmentBizId
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Policyholder> addPolicyholderData(ApiPolicyholderInfoDto dto, String appointmentBizId) {
        if (Objects.isNull(dto)){
            //为空设置，方便新建暂存公用方法
            dto = new ApiPolicyholderInfoDto();
        }
        //投保人信息信息
        Policyholder policyholder = new Policyholder();
        BeanUtils.copyProperties(dto,policyholder);
        //生成投保人信息表唯一业务ID
        policyholder.setPolicyholderBizId(RandomStringGenerator.generateBizId16(CommonEnum.UID_TYPE_POLICYHOLDER.getCode()));
        //预约信息主表唯一业务ID
        policyholder.setAppointmentBizId(appointmentBizId);
        //地址信息（json串）
        policyholder.setAddressList(CommonUtil.getAddressListJsonStr(dto.getAddressList()));
        iPolicyholderService.saveOrUpdate(policyholder);

        //添加投保人税务列表信息
        if (!CollectionUtils.isEmpty(dto.getApiTaxationDtoList())) {
            apiTaxationService.saveTaxationList(ApiObjectTaxationDto.builder()
                    .objectBizId(policyholder.getPolicyholderBizId())
                    .objectName(CommonEnum.UID_TYPE_POLICYHOLDER.getName())
                    .objectTableName(CommonEnum.UID_TYPE_POLICYHOLDER.getCode())
                    .objectType(CommonEnum.UID_TYPE_POLICYHOLDER.getCode())
                    .apiTaxationDtoList(dto.getApiTaxationDtoList())
                    .build());
        }
        //添加投保人证件列表信息
        if (!CollectionUtils.isEmpty(dto.getApiCertificateDtoList())) {
            //新增对象证件关系信息
            addRelObjectCertificateList(policyholder.getPolicyholderBizId(),
                                        CommonEnum.UID_TYPE_POLICYHOLDER.getCode(),
                                        CommonEnum.UID_TYPE_POLICYHOLDER.getCode(),
                                        CommonEnum.UID_TYPE_POLICYHOLDER.getName(),
                                        dto.getApiCertificateDtoList()
            );
        }
        return Result.success(policyholder);
    }

    /**
     * 新增对象证件关系信息
     * @param objectBizId
     * @param objectType
     * @param objectTableName
     * @param objectName
     * @param apiCertificateDtoList
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Result addRelObjectCertificateList(String objectBizId,
                                              String objectType,
                                              String objectTableName,
                                              String objectName,
                                              List<ApiCertificateDto> apiCertificateDtoList) {
        ApiRelObjectCertificateListAddRequest addRequest = new ApiRelObjectCertificateListAddRequest();
        addRequest.setObjectBizId(objectBizId);
        addRequest.setObjectName(objectName);
        addRequest.setObjectTableName(objectTableName);
        addRequest.setObjectType(objectType);
        addRequest.setApiCertificateDtoList(apiCertificateDtoList);
        apiRelObjectCertificateFeignClient.addRelObjectCertificateList(addRequest);
        return Result.success();
    }

    /**
     * 编辑投保人信息表数据
     * @param dto
     * @param appointmentBizId
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Policyholder> editPolicyholderData(ApiPolicyholderInfoDto dto, String appointmentBizId) {
        if (Objects.isNull(dto)) {
            //投保人信息对象不能为空
            throw new BusinessException("投保人信息对象不能为空");
        }
        if (StringUtils.isBlank(dto.getPolicyholderBizId())) {
            throw new BusinessException("投保人信息表唯一业务ID不能为空");
        }
        //校验投保人信息是否存在
        Result<Policyholder> result = checkPolicyholderIsExist(dto.getPolicyholderBizId());
        Policyholder policyholder = result.getData();

        BeanUtils.copyProperties(dto,policyholder);
        policyholder.setAppointmentBizId(appointmentBizId);
        //地址信息（json串）
        policyholder.setAddressList(CommonUtil.getAddressListJsonStr(dto.getAddressList()));
        iPolicyholderService.saveOrUpdate(policyholder);

        //添加税务信息列表信息
        if (!CollectionUtils.isEmpty(dto.getApiTaxationDtoList())) {
            apiTaxationService.saveTaxationList(ApiObjectTaxationDto.builder()
                    .objectBizId(policyholder.getPolicyholderBizId())
                    .objectName(CommonEnum.UID_TYPE_POLICYHOLDER.getName())
                    .objectTableName(CommonEnum.UID_TYPE_POLICYHOLDER.getCode())
                    .objectType(CommonEnum.UID_TYPE_POLICYHOLDER.getCode())
                    .apiTaxationDtoList(dto.getApiTaxationDtoList())
                    .build());
        }
        //添加投保人证件列表信息
        if (!CollectionUtils.isEmpty(dto.getApiCertificateDtoList())) {
            //新增对象证件关系信息
            addRelObjectCertificateList(policyholder.getPolicyholderBizId(),
                    CommonEnum.UID_TYPE_POLICYHOLDER.getCode(),
                    CommonEnum.UID_TYPE_POLICYHOLDER.getCode(),
                    CommonEnum.UID_TYPE_POLICYHOLDER.getName(),
                    dto.getApiCertificateDtoList()
            );
        }
        return Result.success(policyholder);
    }

    /**
     * 校验投保人信息是否存在
     * @param policyholderBizId
     * @return
     */
    public Result<Policyholder> checkPolicyholderIsExist(String policyholderBizId) {
        Policyholder policyholder = iPolicyholderService.queryOne(policyholderBizId);
        if (Objects.isNull(policyholder)) {
            //数据不存在
            throw new BusinessException(ResultCode.NULL_ERROR.getCode(),ResultCode.NULL_ERROR.getMessage());
        }
        return Result.success(policyholder);
    }

}
