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

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
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.ApiAdditionalService;
import com.yd.csf.api.service.ApiAppointmentCheckService;
import com.yd.csf.feign.dto.appointment.ApiProductPlanAdditionalInfoDto;
import com.yd.csf.feign.dto.appointment.ApiProductPlanInfoDto;
import com.yd.csf.feign.request.additional.ApiAdditionalPageRequest;
import com.yd.csf.feign.response.additional.ApiAdditionalPageResponse;
import com.yd.csf.service.dto.AdditionalDto;
import com.yd.csf.service.model.Additional;
import com.yd.csf.service.service.IAdditionalService;
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.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 产品计划-附加险信息业务实现类
 */
@Slf4j
@Service
public class ApiAdditionalServiceImpl implements ApiAdditionalService {

    @Autowired
    private IAdditionalService iAdditionalService;

    @Autowired
    private ApiAppointmentCheckService apiAppointmentCheckService;

    /**
     * 附加险分页查询
     * @param request
     * @return
     */
    @Override
    public Result<IPage<ApiAdditionalPageResponse>> page(ApiAdditionalPageRequest request) {
        Page<ApiAdditionalPageResponse> page = new Page<>(request.getPageNo(), request.getPageSize());
        IPage<ApiAdditionalPageResponse> iPage = iAdditionalService.page(page, request);
        return Result.success(iPage);
    }

    /**
     * 附加险列表查询
     * @param planBizId
     * @return
     */
    @Override
    public Result<List<ApiProductPlanAdditionalInfoDto>> list(String planBizId) {
        List<ApiProductPlanAdditionalInfoDto> dtoList = new ArrayList<>();
        List<Additional> list = iAdditionalService.queryList(AdditionalDto.builder()
                .planBizId(planBizId)
                .build());
        if (!CollectionUtils.isEmpty(list)) {
            dtoList = list.stream().map(dto -> {
                ApiProductPlanAdditionalInfoDto infoDto = new ApiProductPlanAdditionalInfoDto();
                BeanUtils.copyProperties(dto,infoDto);
                return infoDto;
            }).collect(Collectors.toList());
        }
        return Result.success(dtoList);
    }

    /**
     * 新增单个附加险信息
     * @param apiProductPlanAdditionalInfoDto
     * @return
     */
    @Override
    public Result add(ApiProductPlanAdditionalInfoDto apiProductPlanAdditionalInfoDto) {
        List<ApiProductPlanAdditionalInfoDto> list = new ArrayList<>();
        list.add(apiProductPlanAdditionalInfoDto);
        //新增单个附加险信息入参字段校验 - 产品计划信息字段校验 - 产品附加险信息列表字段校验
        apiAppointmentCheckService.checkAddApiProductPlanAdditionalInfoDtoList(list);

        ApiProductPlanInfoDto productPlanInfoDto = new ApiProductPlanInfoDto();
        productPlanInfoDto.setApiProductPlanAdditionalInfoDtoList(list);
        //批量添加产品计划-附加险信息表数据
        batchAddAdditionalData(productPlanInfoDto,apiProductPlanAdditionalInfoDto.getPlanBizId());
        return Result.success();
    }

    /**
     * 编辑单个附加险信息
     * @param apiProductPlanAdditionalInfoDto
     * @return
     */
    @Override
    public Result edit(ApiProductPlanAdditionalInfoDto apiProductPlanAdditionalInfoDto) {
        //编辑预约入参字段校验 - 产品计划信息字段校验 - 编辑产品附加险信息单个对象字段校验
        apiAppointmentCheckService.checkEditApiProductPlanAdditionalInfoDto(apiProductPlanAdditionalInfoDto);

        List<ApiProductPlanAdditionalInfoDto> apiProductPlanAdditionalInfoDtoList = new ArrayList<>();
        apiProductPlanAdditionalInfoDtoList.add(apiProductPlanAdditionalInfoDto);
        ApiProductPlanInfoDto productPlanInfoDto = new ApiProductPlanInfoDto();
        productPlanInfoDto.setApiProductPlanAdditionalInfoDtoList(apiProductPlanAdditionalInfoDtoList);
        //批量编辑产品计划-附加险信息表数据
        batchEditAdditionalData(productPlanInfoDto,apiProductPlanAdditionalInfoDto.getPlanBizId());
        return Result.success();
    }

    /**
     * 单个附加险信息详情
     * @param additionalBizId
     * @return
     */
    @Override
    public Result<ApiProductPlanAdditionalInfoDto> detail(String additionalBizId) {
        ApiProductPlanAdditionalInfoDto dto = new ApiProductPlanAdditionalInfoDto();
        //校验附加险信息是否存在
        Result<Additional> result = checkAdditionalIsExist(additionalBizId);
        Additional additional = result.getData();
        BeanUtils.copyProperties(additional,dto);
        return Result.success(dto);
    }

    /**
     * 删除单个附加险信息
     * @param additionalBizId
     * @return
     */
    @Override
    public Result del(String additionalBizId) {
        //校验附加险信息是否存在
        Result<Additional> result = checkAdditionalIsExist(additionalBizId);
        Additional additional = result.getData();
        iAdditionalService.removeById(additional.getId());
        return Result.success();
    }

    /**
     * 批量添加产品计划-附加险信息表数据
     * @param productPlanInfoDto
     * @param planBizId
     * @return
     */
    @Override
    public Result batchAddAdditionalData(ApiProductPlanInfoDto productPlanInfoDto, String planBizId) {
        if (Objects.isNull(productPlanInfoDto)
                || ( !Objects.isNull(productPlanInfoDto)
                && CollectionUtils.isEmpty(productPlanInfoDto.getApiProductPlanAdditionalInfoDtoList()))){
            //为空放行
            return Result.success();
        }
        //附加险列表信息
        List<ApiProductPlanAdditionalInfoDto> list = productPlanInfoDto.getApiProductPlanAdditionalInfoDtoList();

        //构造需要新增数据的对象集合
        List<Additional> additionalList = list.stream().map(dto -> {
            Additional additional = new Additional();
            BeanUtils.copyProperties(dto,additional);
            //生成附加险信息表唯一业务ID
            additional.setAdditionalBizId(RandomStringGenerator.generateBizId16(CommonEnum.UID_TYPE_ADDITIONAL.getCode()));
            //产品计划信息表唯一业务ID
            additional.setPlanBizId(planBizId);
            return additional;
        }).collect(Collectors.toList());

        iAdditionalService.saveOrUpdateBatch(additionalList);

        return Result.success();
    }

    /**
     * 批量编辑产品计划-附加险信息表数据
     * @param productPlanInfoDto
     * @param planBizId
     * @return
     */
    @Override
    public Result batchEditAdditionalData(ApiProductPlanInfoDto productPlanInfoDto, String planBizId) {
        if (Objects.isNull(productPlanInfoDto)
                || ( !Objects.isNull(productPlanInfoDto)
                && CollectionUtils.isEmpty(productPlanInfoDto.getApiProductPlanAdditionalInfoDtoList()))){
            //为空放行
            return Result.success();
        }

        //入参的附加险列表信息
        List<ApiProductPlanAdditionalInfoDto> list = productPlanInfoDto.getApiProductPlanAdditionalInfoDtoList();
        //获取不为空的附加险信息表唯一业务ID列表
        List<String> additionalBizIdList = list.stream()
                .filter(dto -> StringUtils.isNotBlank(dto.getAdditionalBizId()))
                .map(ApiProductPlanAdditionalInfoDto::getAdditionalBizId)
                .collect(Collectors.toList());

        if (!CollectionUtils.isEmpty(additionalBizIdList)) {
            //入参的附加险业务id列表至少一个不为空就走表数据校验，全部为空是全部新增操作，不走表数据校验

            //根据附加险信息表唯一业务ID列表查询表里面的列表信息
            List<Additional> additionals = iAdditionalService.queryList(AdditionalDto.builder()
                    .additionalBizIdList(additionalBizIdList).build());

            //过滤入参的附加险列表信息在表里不存在的集合，然后抛出这些不存在的列表信息
            // 提取 existingAdditionalBizIds：从 additionals 中获取所有已存在的 additionalBizId 集合
            Set<String> existingAdditionalBizIds = additionals.stream()
                    .map(Additional::getAdditionalBizId)
                    .collect(Collectors.toSet());
            // 过滤 list：保留 additionalBizId 不在 existingAdditionalBizIds 中的对象
            List<ApiProductPlanAdditionalInfoDto> filteredList = list.stream()
                    .filter(dto -> StringUtils.isNotBlank(dto.getAdditionalBizId()) && !existingAdditionalBizIds.contains(dto.getAdditionalBizId()))
                    .collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(filteredList)) {
                //入参对象列表中有传值的业务id在库中不存在的对象，提示
                List<String> additionalProductNameList = filteredList
                        .stream()
                        .map(ApiProductPlanAdditionalInfoDto::getAddProductName)
                        .collect(Collectors.toList());
                throw new BusinessException("以下是在库里不存在的附加险数据的附加产品名称："+String.join(" ；",additionalProductNameList));
            }
        }


        //构造需要新增或者更新数据的对象集合
        List<Additional> updateList = list.stream().map(dto -> {
            Additional additional = new Additional();
            BeanUtils.copyProperties(dto,additional);
            additional.setPlanBizId(planBizId);
            if (StringUtils.isBlank(dto.getAdditionalBizId())) {
                //为空表示新增数据
                //生成附加险信息表唯一业务ID
                additional.setAdditionalBizId(RandomStringGenerator.generateBizId16(CommonEnum.UID_TYPE_ADDITIONAL.getCode()));
            }
            return additional;
        }).collect(Collectors.toList());

        //批量新增或者更新
        iAdditionalService.saveOrUpdateBatch(updateList);

        return Result.success();
    }

    /**
     * 校验附加险信息是否存在
     * @param additionalBizId
     * @return
     */
    public Result<Additional> checkAdditionalIsExist(String additionalBizId) {
        Additional additional = iAdditionalService.queryOne(additionalBizId);
        if (Objects.isNull(additional)) {
            //数据不存在
            throw new BusinessException(ResultCode.NULL_ERROR.getCode(),ResultCode.NULL_ERROR.getMessage());
        }
        return Result.success(additional);
    }
}
