package com.fjhx.service.customer.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fjhx.base.BaseEntity;
import com.fjhx.base.Condition;
import com.fjhx.entity.customer.Customer;
import com.fjhx.entity.customer.CustomerLink;
import com.fjhx.mapper.customer.CustomerMapper;
import com.fjhx.params.customer.CustomerVo;
import com.fjhx.service.customer.CustomerLinkService;
import com.fjhx.service.customer.CustomerService;
import com.fjhx.utils.RegionClientUtil;
import org.springblade.core.secure.utils.AuthUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 客户 服务实现类
 * </p>
 *
 * @author ${author}
 * @since 2022-10-25
 */
@Service
public class CustomerServiceImpl extends ServiceImpl<CustomerMapper, Customer> implements CustomerService {

    @Autowired
    private CustomerLinkService customerLinkService;

    @Override
    public Page<Map<String, Object>> getPage(Condition condition) {
        String keyword = condition.getKeyword();

        LambdaQueryWrapper<Customer> wrapper = Wrappers.lambdaQuery();
        wrapper.and(ObjectUtil.isNotEmpty(keyword), q -> q
                        .like(Customer::getCode, keyword)
                        .like(Customer::getName, keyword)
                )
                .eq(BaseEntity::getTenantId, AuthUtil.getTenantId())
                .orderByDesc(BaseEntity::getId);

        Page<Map<String, Object>> page = pageMaps(condition.getPage(), wrapper);
        List<Map<String, Object>> records = page.getRecords();
        if (records.size() == 0) {
            return page;
        }

        RegionClientUtil.setRegionName(records);

        return page;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void add(CustomerVo customerVo) {

        synchronized (this) {
            customerVo.setCode(getCoded());
            save(customerVo);
        }

        List<CustomerLink> customerLinkList = customerVo.getCustomerLinkList();
        customerLinkList.forEach(customerLink -> customerLink.setCustomerId(customerVo.getId()));

        customerLinkService.saveBatch(customerLinkList);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void edit(CustomerVo customerVo) {
        // 更新客户
        updateById(customerVo);

        // 更新联系人
        List<CustomerLink> customerLinkList = customerVo.getCustomerLinkList();
        customerLinkList.forEach(customerLink -> customerLink.setCustomerId(customerVo.getId()));
        customerLinkService.saveOrUpdateBatch(customerLinkList);

        // 删除没有上传的联系人
        List<Long> customerLinkIdList = customerLinkList.stream().map(BaseEntity::getId).collect(Collectors.toList());
        customerLinkService.remove(
                Wrappers.<CustomerLink>lambdaQuery()
                        .eq(CustomerLink::getCustomerId, customerVo.getId())
                        .notIn(BaseEntity::getId, customerLinkIdList));
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(CustomerVo customerVo) {
        removeById(customerVo.getId());
        customerLinkService.remove(CustomerLink::getCustomerId, customerVo.getId());
    }

    @Override
    public CustomerVo details(Long id) {
        Customer customer = getById(id);
        CustomerVo customerVo = BeanUtil.toBean(customer, CustomerVo.class);

        List<CustomerLink> list = customerLinkService.list(CustomerLink::getCustomerId, id);
        customerVo.setCustomerLinkList(list);

        return customerVo;
    }

    private String getCoded() {
        Customer customer = getOne(Wrappers.<Customer>lambdaQuery()
                .eq(BaseEntity::getTenantId, AuthUtil.getTenantId())
                .select(Customer::getCode)
                .orderByDesc(Customer::getCode)
                .last("limit 1")
        );

        if (customer == null) {
            return "C00001";
        }
        String code = customer.getCode();
        int num = Convert.toInt(code.replace("C", "")) + 1;

        if (num < 10) {
            return "C0000" + num;
        }
        if (num < 100) {
            return "C000" + num;
        }
        if (num < 1000) {
            return "C00" + num;
        }
        if (num < 10000) {
            return "C0" + num;
        }
        return "C" + num;
    }

}
