package com.erp.customer.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.erp.customer.dto.CustomerCreateRequest;
import com.erp.customer.dto.CustomerUpdateRequest;
import com.erp.customer.entity.Customer;
import com.erp.customer.entity.CustomerAddress;
import com.erp.customer.entity.CustomerContact;
import com.erp.customer.repository.CustomerRepository;
import com.erp.customer.service.CustomerAddressService;
import com.erp.customer.service.CustomerContactService;
import com.erp.customer.service.CustomerRelationshipService;
import com.erp.customer.service.CustomerService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

/**
 * 客户Service实现
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class CustomerServiceImpl extends ServiceImpl<CustomerRepository, Customer> implements CustomerService {
    
    private final CustomerRepository customerRepository;
    private final CustomerContactService customerContactService;
    private final CustomerAddressService customerAddressService;
    private final CustomerRelationshipService customerRelationshipService;
    
    @Override
    public List<Customer> listCustomers(Long tenantId, String level, String status, String keyword,
                                         Long salesId, Integer page, Integer size) {
        int offset = (page - 1) * size;
        
        LambdaQueryWrapper<Customer> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.isNull(Customer::getDeletedAt);
        
        if (tenantId != null) {
            queryWrapper.eq(Customer::getTenantId, tenantId);
        }
        if (StringUtils.hasText(level)) {
            queryWrapper.eq(Customer::getLevel, level);
        }
        if (StringUtils.hasText(status)) {
            queryWrapper.eq(Customer::getStatus, status);
        }
        if (StringUtils.hasText(keyword)) {
            queryWrapper.and(w -> w.like(Customer::getCustomerName, keyword)
                    .or().like(Customer::getCustomerCode, keyword)
                    .or().like(Customer::getPhone, keyword));
        }
        if (salesId != null) {
            queryWrapper.eq(Customer::getSalesId, salesId);
        }
        
        queryWrapper.orderByDesc(Customer::getCreatedAt);
        queryWrapper.last("LIMIT " + offset + ", " + size);
        
        return customerRepository.selectList(queryWrapper);
    }
    
    @Override
    public Customer getCustomerById(Long id) {
        LambdaQueryWrapper<Customer> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Customer::getId, id).isNull(Customer::getDeletedAt);
        return customerRepository.selectOne(queryWrapper);
    }
    
    @Override
    public Customer getCustomerByCode(String customerCode) {
        return customerRepository.findByCustomerCode(customerCode);
    }
    
    @Override
    @Transactional
    public Customer createCustomer(CustomerCreateRequest request) {
        // 验证客户编码唯一性
        if (StringUtils.hasText(request.getCustomerCode())) {
            Customer existing = customerRepository.findByTenantIdAndCustomerCode(
                    request.getTenantId(), request.getCustomerCode());
            if (existing != null) {
                throw new RuntimeException("客户编码已存在: " + request.getCustomerCode());
            }
        } else {
            // 自动生成客户编码
            request.setCustomerCode(generateCustomerCode(request.getTenantId()));
        }
        
        Customer customer = new Customer();
        customer.setTenantId(request.getTenantId());
        customer.setCustomerCode(request.getCustomerCode());
        customer.setCustomerName(request.getCustomerName());
        customer.setShortName(request.getShortName());
        customer.setLevel(request.getLevel() != null ? request.getLevel() : "NORMAL");
        customer.setCustomerType(request.getCustomerType() != null ? request.getCustomerType() : "COMPANY");
        customer.setIndustry(request.getIndustry());
        customer.setPhone(request.getPhone());
        customer.setBackupPhone(request.getBackupPhone());
        customer.setEmail(request.getEmail());
        customer.setWebsite(request.getWebsite());
        customer.setBusinessLicense(request.getBusinessLicense());
        customer.setRegisteredCapital(request.getRegisteredCapital());
        customer.setSource(request.getSource());
        customer.setStatus("ACTIVE");
        customer.setRating(request.getRating() != null ? request.getRating() : 3);
        customer.setBalance(BigDecimal.ZERO);
        customer.setCreditLimit(request.getCreditLimit() != null ? request.getCreditLimit() : BigDecimal.ZERO);
        customer.setCreditUsed(BigDecimal.ZERO);
        customer.setSalesId(request.getSalesId());
        customer.setSalesName(request.getSalesName());
        customer.setTags(request.getTags());
        customer.setDescription(request.getDescription());
        customer.setRemark(request.getRemark());
        
        // 8级客户关系设置
        customer.setRelationshipLevel(request.getRelationshipLevel() != null ? request.getRelationshipLevel() : 1);
        customer.setParentId(request.getParentId());
        customer.setGroupName(request.getGroupName());
        customer.setIsHeadquarters(request.getIsHeadquarters() != null ? request.getIsHeadquarters() : true);
        
        // 设置层级路径
        if (customer.getIsHeadquarters()) {
            customer.setLevelPath("/" + customer.getId() + "/");
        }
        
        customer.setCreatedAt(LocalDateTime.now());
        customer.setUpdatedAt(LocalDateTime.now());
        
        customerRepository.insert(customer);
        log.info("客户创建成功: id={}, customerCode={}, customerName={}", 
                customer.getId(), customer.getCustomerCode(), customer.getCustomerName());
        
        // 如果提供了联系人信息，创建主要联系人
        if (StringUtils.hasText(request.getPrimaryContactName())) {
            CustomerContact contact = new CustomerContact();
            contact.setTenantId(request.getTenantId());
            contact.setCustomerId(customer.getId());
            contact.setCustomerName(customer.getCustomerName());
            contact.setContactName(request.getPrimaryContactName());
            contact.setMobile(request.getPrimaryContactMobile());
            contact.setPosition(request.getPrimaryContactPosition());
            contact.setIsPrimary(true);
            contact.setContactType("PRIMARY");
            customerContactService.createContact(customer.getId(), contact);
        }
        
        // 如果提供了地址信息，创建默认地址
        if (StringUtils.hasText(request.getReceiverName())) {
            CustomerAddress address = new CustomerAddress();
            address.setTenantId(request.getTenantId());
            address.setCustomerId(customer.getId());
            address.setCustomerName(customer.getCustomerName());
            address.setReceiverName(request.getReceiverName());
            address.setReceiverPhone(request.getReceiverPhone());
            address.setReceiverMobile(request.getReceiverMobile());
            address.setProvince(request.getProvince());
            address.setCity(request.getCity());
            address.setDistrict(request.getDistrict());
            address.setStreet(request.getStreet());
            address.setAddressType("DELIVERY");
            address.setIsDefault(true);
            customerAddressService.createAddress(customer.getId(), address);
        }
        
        return customer;
    }
    
    @Override
    @Transactional
    public Customer updateCustomer(Long id, CustomerUpdateRequest request) {
        Customer existing = getCustomerById(id);
        if (existing == null) {
            throw new RuntimeException("客户不存在: " + id);
        }
        
        if (StringUtils.hasText(request.getCustomerName())) {
            existing.setCustomerName(request.getCustomerName());
        }
        if (request.getShortName() != null) {
            existing.setShortName(request.getShortName());
        }
        if (StringUtils.hasText(request.getLevel())) {
            existing.setLevel(request.getLevel());
        }
        if (StringUtils.hasText(request.getCustomerType())) {
            existing.setCustomerType(request.getCustomerType());
        }
        if (StringUtils.hasText(request.getIndustry())) {
            existing.setIndustry(request.getIndustry());
        }
        if (StringUtils.hasText(request.getPhone())) {
            existing.setPhone(request.getPhone());
        }
        if (StringUtils.hasText(request.getEmail())) {
            existing.setEmail(request.getEmail());
        }
        if (StringUtils.hasText(request.getStatus())) {
            existing.setStatus(request.getStatus());
        }
        if (request.getRating() != null) {
            existing.setRating(request.getRating());
        }
        if (request.getBalance() != null) {
            existing.setBalance(request.getBalance());
        }
        if (request.getCreditLimit() != null) {
            existing.setCreditLimit(request.getCreditLimit());
        }
        if (request.getSalesId() != null) {
            existing.setSalesId(request.getSalesId());
        }
        if (StringUtils.hasText(request.getSalesName())) {
            existing.setSalesName(request.getSalesName());
        }
        if (StringUtils.hasText(request.getTags())) {
            existing.setTags(request.getTags());
        }
        if (StringUtils.hasText(request.getDescription())) {
            existing.setDescription(request.getDescription());
        }
        if (StringUtils.hasText(request.getRemark())) {
            existing.setRemark(request.getRemark());
        }
        
        existing.setUpdatedAt(LocalDateTime.now());
        customerRepository.updateById(existing);
        log.info("客户更新成功: id={}", id);
        
        return getCustomerById(id);
    }
    
    @Override
    @Transactional
    public void deleteCustomer(Long id) {
        Customer customer = getCustomerById(id);
        if (customer == null) {
            throw new RuntimeException("客户不存在: " + id);
        }
        
        customer.setDeletedAt(LocalDateTime.now());
        customerRepository.updateById(customer);
        log.info("客户删除成功: id={}, customerName={}", id, customer.getCustomerName());
    }
    
    @Override
    @Transactional
    public Customer toggleCustomerStatus(Long id) {
        Customer customer = getCustomerById(id);
        if (customer == null) {
            throw new RuntimeException("客户不存在: " + id);
        }
        
        String newStatus = "ACTIVE".equals(customer.getStatus()) ? "INACTIVE" : "ACTIVE";
        customer.setStatus(newStatus);
        customer.setUpdatedAt(LocalDateTime.now());
        customerRepository.updateById(customer);
        
        log.info("客户状态切换成功: id={}, newStatus={}", id, newStatus);
        return getCustomerById(id);
    }
    
    @Override
    @Transactional
    public Customer updateCustomerLevel(Long id, String level) {
        Customer customer = getCustomerById(id);
        if (customer == null) {
            throw new RuntimeException("客户不存在: " + id);
        }
        
        customer.setLevel(level);
        customer.setUpdatedAt(LocalDateTime.now());
        customerRepository.updateById(customer);
        
        log.info("客户等级更新成功: id={}, level={}", id, level);
        return getCustomerById(id);
    }
    
    @Override
    public List<Customer> getCustomerBranches(Long customerId) {
        return customerRepository.findBranchesByParentId(customerId);
    }
    
    @Override
    public Customer getCustomerParent(Long customerId) {
        return customerRepository.findParentByCustomerId(customerId);
    }
    
    @Override
    public List<Customer> getLongTimeNoContactCustomers(Long tenantId, Integer days) {
        LocalDateTime before = LocalDateTime.now().minusDays(days);
        return customerRepository.findLongTimeNoContact(tenantId, before);
    }
    
    @Override
    public List<Customer> getTopVipCustomers(Long tenantId, Integer limit) {
        return customerRepository.findTopVipCustomers(tenantId, limit);
    }
    
    @Override
    @Transactional
    public Customer updateCustomerBalance(Long id, BigDecimal amount) {
        Customer customer = getCustomerById(id);
        if (customer == null) {
            throw new RuntimeException("客户不存在: " + id);
        }
        
        customer.setBalance(amount);
        customer.setUpdatedAt(LocalDateTime.now());
        customerRepository.updateById(customer);
        
        return getCustomerById(id);
    }
    
    @Override
    @Transactional
    public Customer addCustomerBalance(Long id, BigDecimal amount) {
        Customer customer = getCustomerById(id);
        if (customer == null) {
            throw new RuntimeException("客户不存在: " + id);
        }
        
        BigDecimal newBalance = customer.getBalance() != null ? customer.getBalance() : BigDecimal.ZERO;
        customer.setBalance(newBalance.add(amount));
        customer.setUpdatedAt(LocalDateTime.now());
        customerRepository.updateById(customer);
        
        log.info("客户余额增加: id={}, amount={}, newBalance={}", id, amount, customer.getBalance());
        return getCustomerById(id);
    }
    
    @Override
    @Transactional
    public Customer deductCustomerBalance(Long id, BigDecimal amount) {
        Customer customer = getCustomerById(id);
        if (customer == null) {
            throw new RuntimeException("客户不存在: " + id);
        }
        
        BigDecimal currentBalance = customer.getBalance() != null ? customer.getBalance() : BigDecimal.ZERO;
        if (currentBalance.compareTo(amount) < 0) {
            throw new RuntimeException("客户余额不足: " + currentBalance + " < " + amount);
        }
        
        customer.setBalance(currentBalance.subtract(amount));
        customer.setUpdatedAt(LocalDateTime.now());
        customerRepository.updateById(customer);
        
        log.info("客户余额扣减: id={}, amount={}, newBalance={}", id, amount, customer.getBalance());
        return getCustomerById(id);
    }
    
    @Override
    @Transactional
    public void updateLastContactTime(Long id) {
        Customer customer = getCustomerById(id);
        if (customer == null) {
            throw new RuntimeException("客户不存在: " + id);
        }
        
        customer.setLastContactAt(LocalDateTime.now());
        customer.setUpdatedAt(LocalDateTime.now());
        customerRepository.updateById(customer);
    }
    
    @Override
    @Transactional
    public void updateDealTime(Long id) {
        Customer customer = getCustomerById(id);
        if (customer == null) {
            throw new RuntimeException("客户不存在: " + id);
        }
        
        LocalDateTime now = LocalDateTime.now();
        if (customer.getFirstDealAt() == null) {
            customer.setFirstDealAt(now);
        }
        customer.setLastDealAt(now);
        customer.setUpdatedAt(now);
        customerRepository.updateById(customer);
    }
    
    /**
     * 生成客户编码
     */
    private String generateCustomerCode(Long tenantId) {
        String dateStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        String seq = String.format("%04d", (int) (System.currentTimeMillis() % 10000));
        return "C" + dateStr + seq;
    }
}
