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.common.enums.CommonEnum;
import com.yd.common.exception.BusinessException;
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.CustomerExpand;
import com.yd.csf.service.model.FnaForm;
import com.yd.csf.service.service.CustomerService;
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.AddressVO;
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;


    @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();

        queryWrapper.like(StringUtils.isNotBlank(name), "name_cn", name)
                .or().like(StringUtils.isNotBlank(name), "name_py_en", name);

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

        return queryWrapper;
    }

    @Override
    public CustomerExpand getCustomerExpand(CustomerAddRequest customerAddRequest) {
        CustomerExpand customerExpand = new CustomerExpand();
        BeanUtils.copyProperties(customerAddRequest, customerExpand, "addressList");
        List<AddressVO> addressList = customerAddRequest.getAddressList();
        if (CollUtil.isNotEmpty(addressList)) {
            customerExpand.setAddressList(GSON.toJson(addressList));
        }

        return customerExpand;
    }

    @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());
        }
        // 客户主表信息
        Customer customer = new Customer();
        BeanUtils.copyProperties(customerAddRequest, customer, "addressList");
        // 地址列表
        if (CollUtil.isNotEmpty(customerAddRequest.getAddressList())) {
            customer.setAddressList(GSON.toJson(customerAddRequest.getAddressList()));
        }
        // 税务国家列表
        if (CollUtil.isNotEmpty(customerAddRequest.getApiTaxationDtoList())) {
            customer.setTaxList(GSON.toJson(customerAddRequest.getApiTaxationDtoList()));
        }
        // 校验客户主表信息
        validCustomer(customer);

        // 客户主表业务唯一id
        customer.setCustomerBizId(RandomStringGenerator.generateBizId16(CommonEnum.UID_TYPE_CUSTOMER.getCode()));
        boolean result = customerService.save(customer);
        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;
    }

    @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");
        // 税务国家列表
        if (CollUtil.isNotEmpty(customerUpdateRequest.getApiTaxationDtoList())) {
            oldCustomer.setTaxList(GSON.toJson(customerUpdateRequest.getApiTaxationDtoList()));
        }
        // 地址列表
        if (CollUtil.isNotEmpty(customerUpdateRequest.getAddressList())) {
            oldCustomer.setAddressList(GSON.toJson(customerUpdateRequest.getAddressList()));
        }
        // 数据校验
        customerService.validCustomer(oldCustomer);
        // 更新主表
        boolean result = customerService.updateById(oldCustomer);
        if (StringUtils.isNotBlank(customerUpdateRequest.getNamePyEn())) {
            fnaService.updateCustomerNameByCustomerBizId(customerUpdateRequest.getNamePyEn(), customerBizId);
        }
        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 (ObjectUtils.isNotEmpty(fnaForm.getDependantList())) {
                List<DependantData> dependantList = GSONUtil.fromJson((String) fnaForm.getDependantList(), new TypeToken<List<DependantData>>() {
                }.getType());
                customer.setDependentsNum(dependantList.size());
            }
        }
    }

}




