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

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.yd.base.feign.dto.ApiCertificateDto;
import com.yd.common.enums.CommonEnum;
import com.yd.common.exception.BusinessException;
import com.yd.common.utils.ChineseTextConverter;
import com.yd.common.utils.EnglishTextUtil;
import com.yd.common.utils.RandomStringGenerator;
import com.yd.csf.service.common.ErrorCode;
import com.yd.csf.service.dao.CustomerMapper;
import com.yd.csf.service.dto.*;
import com.yd.csf.service.model.Customer;
import com.yd.csf.service.model.FnaCustomer;
import com.yd.csf.service.model.FnaForm;
import com.yd.csf.service.service.CustomerService;
import com.yd.csf.service.service.FnaCustomerService;
import com.yd.csf.service.service.FnaFormService;
import com.yd.csf.service.service.FnaService;
import com.yd.csf.service.utils.GSONUtil;
import com.yd.csf.service.utils.ValidateUtil;
import com.yd.csf.service.vo.CustomerVO;
import org.apache.commons.collections4.CollectionUtils;
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 javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Zhang Jianan
 * @description 针对表【customer(客户信息表)】的数据库操作Service实现
 * @createDate 2025-08-29 17:38:23
 */
@Service
public class CustomerServiceImpl extends ServiceImpl<CustomerMapper, Customer>
        implements CustomerService {

    private final static Gson GSON = new Gson();

    @Resource
    private CustomerService customerService;
    @Resource
    private FnaService fnaService;
    @Resource
    private FnaFormService fnaFormService;
    @Resource
    private FnaCustomerService fnaCustomerService;


    @Override
    public CustomerVO getCustomerVO(Customer customer) {
        return CustomerVO.objToVo(customer);
    }

    @Override
    public Wrapper<Customer> getQueryWrapper(CustomerQueryRequest customerQueryRequest) {
        QueryWrapper<Customer> queryWrapper = new QueryWrapper<>();
        String name = customerQueryRequest.getName();
        String mobile = customerQueryRequest.getMobile();
        String email = customerQueryRequest.getEmail();

        // 中文转简体
        String nameSc = ChineseTextConverter.traditionalToSimplified(name);
        // 英文转小写
        String nameEnLc = EnglishTextUtil.toLowerCase(name);

        queryWrapper.like(StringUtils.isNotBlank(nameSc), "name_sc", nameSc)
                .or().like(StringUtils.isNotBlank(nameEnLc), "name_en_lc", nameEnLc);

        queryWrapper.like(StringUtils.isNotBlank(mobile), "mobile", mobile);
        queryWrapper.like(StringUtils.isNotBlank(email), "email", email);

        return queryWrapper;
    }

    @Override
    public Page<CustomerVO> getCustomerVOPage(Page<Customer> customerPage) {
        List<Customer> customerList = customerPage.getRecords();
        Page<CustomerVO> customerVOPage = new Page<>(customerPage.getCurrent(), customerPage.getSize(), customerPage.getTotal());
        if (CollUtil.isEmpty(customerList)) {
            return customerVOPage;
        }
        // 对象列表 => 封装对象列表
        List<CustomerVO> customerVOList = customerList.stream().map(CustomerVO::objToVo).collect(Collectors.toList());

        customerVOPage.setRecords(customerVOList);
        return customerVOPage;
    }

    @Override
    public Customer getByCustomerBizId(String customerBizId) {
        return baseMapper.selectOne(new LambdaQueryWrapper<Customer>().eq(Customer::getCustomerBizId, customerBizId));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> addCustomer(CustomerAddRequest customerAddRequest) {
        // 校验 请求 对象中，参数是否全部为空
        if (ValidateUtil.isAllFieldsNull(customerAddRequest)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR.getCode(), ErrorCode.PARAMS_ERROR.getMessage());
        }
        String customerBizId = customerAddRequest.getCustomerBizId();
        Customer customer = null;
        if (StringUtils.isNotBlank(customerAddRequest.getCustomerBizId())) {
            customer = customerService.queryOneByCustomerBizId(customerAddRequest.getCustomerBizId());
        }
        if (customer == null) {
            // 检查字段 certificate_list，根据证件类型、证件号码查询客户是否存在
            customer = queryByCertificate(customerAddRequest.getApiCertificateDtoList());
            if (customer == null) {
                customer = new Customer();
                // 客户主表业务唯一id
                customerBizId = RandomStringGenerator.generateBizId16(CommonEnum.UID_TYPE_CUSTOMER.getCode());
            }else {
                customerBizId = customer.getCustomerBizId();
            }
        }

        // 客户主表信息
        BeanUtils.copyProperties(customerAddRequest, customer, "addressList", "apiTaxationDtoList", "apiCertificateDtoList");
        // 地址列表
        if (CollUtil.isNotEmpty(customerAddRequest.getAddressList())) {
            customer.setAddressList(GSON.toJson(customerAddRequest.getAddressList()));
        }
        // 税务国家列表冗余存储
        if (CollUtil.isNotEmpty(customerAddRequest.getApiTaxationDtoList())) {
            customer.setTaxList(GSON.toJson(customerAddRequest.getApiTaxationDtoList()));
        }
        // 证件列表冗余存储
        if (CollUtil.isNotEmpty(customerAddRequest.getApiCertificateDtoList())) {
            customer.setCertificateList(GSON.toJson(customerAddRequest.getApiCertificateDtoList()));
        }
        // 校验客户主表信息
        validCustomer(customer);

        customer.setCustomerBizId(customerBizId);

        // 中文转简体
        String nameSc = ChineseTextConverter.traditionalToSimplified(customerAddRequest.getNameCn());
        // 英文转小写
        String nameEnLc = EnglishTextUtil.toLowerCase(customerAddRequest.getNamePyEn());

        customer.setNameSc(nameSc);
        customer.setNameEnLc(nameEnLc);
        boolean result = customerService.saveOrUpdate(customer);
        if (!result) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR.getCode(), ErrorCode.OPERATION_ERROR.getMessage());
        }

        // 保存 fna_customer
        FnaCustomer fnaCustomer = new FnaCustomer();
        BeanUtils.copyProperties(customer, fnaCustomer);
        fnaCustomer.setFnaBizId(customerAddRequest.getFnaBizId());
        fnaCustomer.setFnaCustomerBizId(RandomStringGenerator.generateBizId16("fna_customer"));
        result = fnaCustomerService.saveOrUpdate(fnaCustomer);
        if (!result) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR.getCode(), ErrorCode.OPERATION_ERROR.getMessage());
        }

        Map<String, Object> map = new HashMap<>();
        map.put("customerBizId", customer.getCustomerBizId());
        return map;
    }



    private Customer queryByCertificate(List<ApiCertificateDto> certificateList) {
        if (CollUtil.isNotEmpty(certificateList)) {
            for (ApiCertificateDto certificate : certificateList) {
                if (StringUtils.isNotBlank(certificate.getDocumentType()) && StringUtils.isNotBlank(certificate.getIdNumber())) {
                    // 查询所有有 certificateList 的客户
                    List<Customer> existingCustomers = customerService.lambdaQuery()
                            .isNotNull(Customer::getCertificateList)
                            .ne(Customer::getCertificateList, "")
                            .list();

                    if (CollUtil.isNotEmpty(existingCustomers)) {
                        for (Customer existingCustomer : existingCustomers) {
                            if (ObjectUtils.isNotEmpty(existingCustomer.getCertificateList())) {
                                try {
                                    // 解析 JSON 中的证件列表
                                    List<ApiCertificateDto> certList = GSON.fromJson(
                                            (String) existingCustomer.getCertificateList(),
                                            new TypeToken<List<ApiCertificateDto>>() {}.getType()
                                    );
                                    if (CollUtil.isNotEmpty(certList)) {
                                        for (ApiCertificateDto cert : certList) {
                                            String docType = cert.getDocumentType();
                                            String idNum = cert.getIdNumber();
                                            // 比对证件类型和证件号码
                                            if (certificate.getDocumentType().equals(docType)
                                                    && certificate.getIdNumber().equals(idNum)) {
                                                return existingCustomer;
                                            }
                                        }
                                    }
                                } catch (Exception e) {
                                    // JSON 解析失败，跳过该客户
                                }
                            }
                        }
                    }
                }
            }
        }
        return null;
    }

    @Override
    public void validCustomer(Customer customer) {
        if (StringUtils.isBlank(customer.getNamePyEn())) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR.getCode(), "名字-英文不能为空");
        }
        if (StringUtils.isBlank(customer.getMobile())) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR.getCode(), "客户手机号不能为空");
        }
        if (StringUtils.isBlank(customer.getAge())) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR.getCode(), "年龄不能为空");
        }
        if (StringUtils.isBlank(customer.getNationality())) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR.getCode(), "国籍不能为空");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateCustomer(CustomerUpdateRequest customerUpdateRequest) {
        // 判断是否存在
        String customerBizId = customerUpdateRequest.getCustomerBizId();
        Customer oldCustomer = customerService.getByCustomerBizId(customerBizId);
        if (oldCustomer == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR.getCode(), ErrorCode.NOT_FOUND_ERROR.getMessage());
        }

        BeanUtils.copyProperties(customerUpdateRequest, oldCustomer, "customerBizId", "apiCertificateDtoList");
        // 地址列表
        if (CollUtil.isNotEmpty(customerUpdateRequest.getAddressList())) {
            oldCustomer.setAddressList(GSON.toJson(customerUpdateRequest.getAddressList()));
        }
        // 税务国家列表冗余存储
        if (CollUtil.isNotEmpty(customerUpdateRequest.getApiTaxationDtoList())) {
            oldCustomer.setTaxList(GSON.toJson(customerUpdateRequest.getApiTaxationDtoList()));
        }
        // 证件列表冗余存储
        if (CollUtil.isNotEmpty(customerUpdateRequest.getApiCertificateDtoList())) {
            oldCustomer.setCertificateList(GSON.toJson(customerUpdateRequest.getApiCertificateDtoList()));
        }
        // 数据校验
        customerService.validCustomer(oldCustomer);
        // 更新主表
        // 中文转简体
        String nameSc = ChineseTextConverter.traditionalToSimplified(customerUpdateRequest.getNameCn());
        // 英文转小写
        String nameEnLc = EnglishTextUtil.toLowerCase(customerUpdateRequest.getNamePyEn());
        oldCustomer.setNameSc(nameSc);
        oldCustomer.setNameEnLc(nameEnLc);
        boolean result = customerService.updateById(oldCustomer);
        if (StringUtils.isNotBlank(customerUpdateRequest.getNamePyEn())) {
            fnaService.updateCustomerNameByCustomerBizId(customerUpdateRequest.getNamePyEn(), customerBizId);
        }

        // 更新 fna_customer 表
        FnaCustomer fnaCustomer = fnaCustomerService.lambdaQuery().eq(FnaCustomer::getFnaBizId, customerBizId).one();
        if (fnaCustomer != null) {
            BeanUtils.copyProperties(oldCustomer, fnaCustomer, "id", "fna_customer_biz_id", "fnaBizId", "customerBizId");
            fnaCustomerService.updateById(fnaCustomer);
        }

        return true;
    }

    @Override
    public void queryDependentsNum(Customer customer) {
        QueryWrapper<FnaForm> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("customer_biz_id", customer.getCustomerBizId());
        queryWrapper.orderByDesc("id");
        List<FnaForm> fnaFormList = fnaFormService.list(queryWrapper);
        if (CollectionUtils.isNotEmpty(fnaFormList)) {
            FnaForm fnaForm = fnaFormList.get(0);
            if (StringUtils.isNotBlank((CharSequence) fnaForm.getDependantList()) && !"null".equals(fnaForm.getDependantList())) {
                List<DependantData> dependantList = GSONUtil.fromJson((String) fnaForm.getDependantList(), new TypeToken<List<DependantData>>() {
                }.getType());
                customer.setDependentsNum(dependantList.size());
            } else {
                customer.setDependentsNum(0);
            }
        }
    }

    @Override
    public Customer queryOneByCustomerBizId(String customerBizId) {
        return this.baseMapper.selectOne(new LambdaQueryWrapper<Customer>()
                .eq(Customer::getCustomerBizId,customerBizId).last(" limit 1 "));
    }

}




