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

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yd.common.enums.ResultCode;
import com.yd.common.exception.BusinessException;
import com.yd.common.result.Result;
import com.yd.csf.feign.dto.appointment.ApiProductPlanAdditionalInfoDto;
import com.yd.csf.feign.dto.appointment.ApiProductPlanMainInfoDto;
import com.yd.csf.service.dto.*;
import com.yd.csf.service.model.Policy;
import com.yd.csf.service.model.PolicyAdditional;
import com.yd.csf.service.service.PolicyAdditionalService;
import com.yd.csf.service.service.PolicyService;
import com.yd.csf.service.dao.PolicyMapper;
import com.yd.csf.service.vo.PolicyVO;
import com.yd.product.feign.client.relprojectproductlaunch.ApiRelProjectProductLaunchFeignClient;
import com.yd.product.feign.request.productlaunch.ApiProductLaunchParameterPageRequest;
import com.yd.product.feign.request.relprojectproductlaunch.ApiRelProjectProductLaunchPageRequest;
import com.yd.product.feign.response.productlaunch.ApiAttributeSettingDto;
import com.yd.product.feign.response.relprojectproductlaunch.ApiRelProjectProductLaunchPageResponse;
import io.swagger.v3.core.util.Json;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author Zhang Jianan
 * @description 针对表【policy(保单表)】的数据库操作Service实现
 * @createDate 2025-09-18 15:07:25
 */
@Service
@Slf4j
public class PolicyServiceImpl extends ServiceImpl<PolicyMapper, Policy>
        implements PolicyService {

    @Resource
    private PolicyAdditionalService policyAdditionalService;

    @Resource
    private ApiRelProjectProductLaunchFeignClient apiRelProjectProductLaunchFeignClient;

    @Override
    public QueryWrapper<Policy> getQueryWrapper(PolicyQueryRequest policyQueryRequest) {
        QueryWrapper<Policy> queryWrapper = new QueryWrapper<>();
        if (policyQueryRequest == null) {
            return queryWrapper;
        }
        String status = policyQueryRequest.getStatus();
        String policyNo = policyQueryRequest.getPolicyNo();
        String customerName = policyQueryRequest.getCustomerName();
        String customerBizId = policyQueryRequest.getCustomerBizId();
        String insurer = policyQueryRequest.getInsurer();
        String productName = policyQueryRequest.getProductName();
        String issueDateStart = policyQueryRequest.getIssueDateStart();
        String issueDateEnd = policyQueryRequest.getIssueDateEnd();

        queryWrapper.eq(StringUtils.isNotBlank(status), "status", status);
        queryWrapper.eq(StringUtils.isNotBlank(policyNo), "policy_no", policyNo);
        queryWrapper.eq(StringUtils.isNotBlank(customerName), "customer_name", customerName);
        queryWrapper.eq(StringUtils.isNotBlank(customerBizId), "customer_biz_id", customerBizId);
        queryWrapper.eq(StringUtils.isNotBlank(insurer), "insurer", insurer);
        queryWrapper.eq(StringUtils.isNotBlank(productName), "product_name", productName);
        queryWrapper.ge(StringUtils.isNotBlank(issueDateStart), "issue_date", issueDateStart);
        queryWrapper.le(StringUtils.isNotBlank(issueDateEnd), "issue_date", issueDateEnd);

        // 默认排序
        queryWrapper.orderByDesc("id");

        return queryWrapper;
    }

    @Override
    public Page<PolicyVO> getPolicyVOPage(Page<Policy> policyPage) {
        List<Policy> policyList = policyPage.getRecords();
        Page<PolicyVO> policyVOPage = new Page<>(policyPage.getCurrent(), policyPage.getSize(), policyPage.getTotal());
        if (CollUtil.isEmpty(policyList)) {
            return policyVOPage;
        }

        // 填充信息
        List<PolicyVO> policyVOList = policyList.stream().map(policy -> {
            PolicyVO policyVO = PolicyVO.objToVo(policy);
            return policyVO;
        }).collect(Collectors.toList());
        policyVOPage.setRecords(policyVOList);
        return policyVOPage;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updatePolicy(PolicyUpdateRequest policyUpdateRequest) {
        String policyBizId = policyUpdateRequest.getPolicyBizId();
        if (StringUtils.isBlank(policyBizId)) {
            throw new BusinessException(ResultCode.PARAMS_ERROR.getCode(), "policyBizId不能为空");
        }
        Policy policy = this.getOne(new QueryWrapper<Policy>().eq("policy_biz_id", policyBizId));
        if (policy == null) {
            throw new BusinessException(ResultCode.NULL_ERROR.getCode(), "保单不存在");
        }
        Date now = new Date();
        // 保单信息
        ApiProductPlanMainInfoDto apiProductPlanMainInfoDto = policyUpdateRequest.getApiProductPlanMainInfoDto();
        if (apiProductPlanMainInfoDto != null) {
            BeanUtils.copyProperties(apiProductPlanMainInfoDto, policy, "policyBizId", "id");
            policy.setPaymentPremium(apiProductPlanMainInfoDto.getEachIssuePremium());
            policy.setIsPrepaid(apiProductPlanMainInfoDto.getIsPrepay());
            policy.setUpdateTime(now);
            // 更新保单
            this.updateById(policy);
        }
        String policyNo = policy.getPolicyNo();

        // 先删除旧的附加险
        policyAdditionalService.remove(new QueryWrapper<PolicyAdditional>().eq("policy_biz_id", policyBizId));
        // 保单附加险列表
        List<ApiProductPlanAdditionalInfoDto> apiProductPlanAdditionalInfoDtoList = policyUpdateRequest.getApiProductPlanAdditionalInfoDtoList();
        if (CollUtil.isNotEmpty(apiProductPlanAdditionalInfoDtoList)) {
            // 转换为实体类
            List<PolicyAdditional> policyAdditionalList = apiProductPlanAdditionalInfoDtoList.stream().map(additionalDto -> {
                PolicyAdditional policyAdditional = new PolicyAdditional();
                BeanUtils.copyProperties(additionalDto, policyAdditional);

                policyAdditional.setPolicyBizId(policyBizId);
                policyAdditional.setPolicyNo(policyNo);
                policyAdditional.setUpdateTime(now);
                policyAdditional.setCreateTime(now);
                return policyAdditional;
            }).collect(Collectors.toList());
            // 批量插入
            policyAdditionalService.saveBatch(policyAdditionalList);
        }

        policy.setUpdateTime(now);
        return true;
    }


    /**
     * 查询列表
     *
     * @param dto
     * @return
     */
    @Override
    public List<Policy> queryList(QueryPolicyDto dto) {
        List<Policy> list = baseMapper.selectList(new LambdaQueryWrapper<Policy>()
                .in(!CollectionUtils.isEmpty(dto.getPolicyNoList()), Policy::getPolicyNo, dto.getPolicyNoList())
        );
        return list;
    }

    /**
     * 根据保单号查询单个对象
     *
     * @param policyNo
     * @return
     */
    @Override
    public Policy queryOne(String policyNo) {
        return this.getOne(new LambdaQueryWrapper<Policy>().eq(Policy::getPolicyNo, policyNo).last(" limit 1 "));
    }

    @Override
    public List<QueryPolicyAndBrokerDto> queryPolicyBrokerList(String policyNo) {
        return baseMapper.queryPolicyBrokerList(policyNo);
    }

    @Override
    public List<PolicyProductInfo> getPolicyProductInfo(List<String> productLaunchBizIdList) {
        ApiRelProjectProductLaunchPageRequest pageRequest = new ApiRelProjectProductLaunchPageRequest();
        pageRequest.setProductLaunchBizIdList(productLaunchBizIdList);
        pageRequest.setPageNo(1);
        pageRequest.setPageSize(1000);

        log.info("查询保单产品信息请求参数: {}", JSONUtil.toJsonStr(pageRequest));

        // 修改为使用Result<Object>来接收
        Result result = apiRelProjectProductLaunchFeignClient.page(pageRequest);
        if (result == null || ObjectUtils.isEmpty(result.getData())) {
            return CollUtil.newArrayList();
        }
        try {
            // 直接使用Map来处理数据，避免复杂的类型转换
            Object data = result.getData();
            List<PolicyProductInfo> policyProductInfoList = new ArrayList<>();

            // 将数据转换为JSONObject进行解析
            JSONObject jsonObject = JSONUtil.parseObj(data);

            // 获取records数组
            JSONArray recordsArray = jsonObject.getJSONArray("records");
            if (recordsArray != null) {
                for (int i = 0; i < recordsArray.size(); i++) {
                    JSONObject record = recordsArray.getJSONObject(i);

                    PolicyProductInfo productInfo = new PolicyProductInfo();
                    productInfo.setProductLaunchBizId(record.getStr("productLaunchBizId"));
                    productInfo.setProductName(record.getStr("productName"));
                    productInfo.setTitle(record.getStr("title"));
                    productInfo.setShortTitle(record.getStr("shortTitle"));
                    productInfo.setStatus(record.getStr("status"));

                    // 解析自定义属性
                    JSONArray attributeSettingArray = record.getJSONArray("apiAttributeSettingDtoList");
                    if (attributeSettingArray != null) {
                        getInfoFromJsonArray(attributeSettingArray, productInfo);
                    }

                    policyProductInfoList.add(productInfo);
                }
            }

            log.info("解析后的保单产品信息: {}", JSONUtil.toJsonStr(policyProductInfoList));
            return policyProductInfoList;
        } catch (Exception e) {
            log.error("解析Feign返回数据失败: {}", e.getMessage(), e);
            return CollUtil.newArrayList();
        }
    }

    @Override
    public Map<String, PolicyProductInfo> getPolicyProductInfoMap(Collection<String> productLaunchBizIdList) {
        // 校验参数
        if (CollectionUtils.isEmpty(productLaunchBizIdList)) {
            return Collections.emptyMap();
        }

        List<PolicyProductInfo> policyProductInfoList = getPolicyProductInfo(new ArrayList<>(productLaunchBizIdList));

        return policyProductInfoList.stream()
                .collect(Collectors.toMap(PolicyProductInfo::getProductLaunchBizId, Function.identity(), (oldValue, newValue) -> newValue));
    }

    /**
     * 从JSON数组中解析自定义属性
     */
    private void getInfoFromJsonArray(JSONArray attributeSettingArray, PolicyProductInfo productInfo) {
        if (attributeSettingArray == null || attributeSettingArray.isEmpty()) {
            return;
        }

        for (int i = 0; i < attributeSettingArray.size(); i++) {
            JSONObject attribute = attributeSettingArray.getJSONObject(i);
            String name = attribute.getStr("name");
            String value = attribute.getStr("value");

            // 根据属性名称设置对应的字段
            switch (name) {
                case "保险公司":
                    productInfo.setInsuranceCompany(value);
                    productInfo.setInsuranceCompanyBizId(attribute.getStr("fieldValueBizId"));
                    break;
                case "对账公司":
                    productInfo.setReconciliationCompany(value);
                    productInfo.setReconciliationCompanyBizId(attribute.getStr("fieldValueBizId"));
                    // 尝试获取对账公司编码（如果 API 响应中有 fieldValueCode 字段）
                    String reconciliationCompanyCode = attribute.getStr("fieldValueCode");
                    if (StringUtils.isBlank(reconciliationCompanyCode)) {
                        // 如果没有 fieldValueCode，尝试从其他字段获取
                        reconciliationCompanyCode = attribute.getStr("code");
                    }
                    productInfo.setReconciliationCompanyCode(reconciliationCompanyCode);
                    break;
                case "产品计划类型":
                    productInfo.setProductPlanType(value);
                    break;
                case "是否区分吸烟":
                    productInfo.setIsSmokingDistinguish(value);
                    break;
                default:
                    // 其他自定义属性
                    break;
            }
        }
    }
}





