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.transaction.annotation.Transactional;
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
    @Transactional(rollbackFor = Exception.class)
    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();
        }
        //先删后新增
        iAdditionalService.delByPlanBizId(planBizId);

        //新增
        List<Additional> saveList = productPlanInfoDto.getApiProductPlanAdditionalInfoDtoList().stream().map(dto -> {
            Additional additional = new Additional();
            BeanUtils.copyProperties(dto,additional);
            additional.setPlanBizId(planBizId);
            additional.setAdditionalBizId(RandomStringGenerator.generateBizId16(CommonEnum.UID_TYPE_ADDITIONAL.getCode()));
            return additional;
        }).collect(Collectors.toList());
        iAdditionalService.saveOrUpdateBatch(saveList);
        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);
    }
}
