package com.erp.product.sku.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.erp.common.core.exception.BusinessException;
import com.erp.product.sku.dto.*;
import com.erp.product.sku.entity.*;
import com.erp.product.sku.repository.*;
import com.erp.product.sku.service.SkuMatchService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * SKU匹配服务实现
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SkuMatchServiceImpl implements SkuMatchService {
    
    private final PlatformSkuBindingRepository bindingRepository;
    private final PlatformRepository platformRepository;
    private final ErpSkuRepository erpSkuRepository;
    private final OrderItemRepository orderItemRepository;
    private final MatchLogRepository matchLogRepository;
    private final UnmatchedLogRepository unmatchedLogRepository;
    private final StringRedisTemplate redisTemplate;
    
    @Value("${erp.sku-match.ai-queue:erp:queue:jarvis}")
    private String aiQueueName;
    
    // 默认规则
    private static final List<String> DEFAULT_RULES = Arrays.asList("exact_code", "exact_alias", "fuzzy_name");
    
    // ==================== 查询接口实现 ====================
    
    @Override
    public IPage<SkuBindingDTO> listBindings(SkuMatchPageRequest request) {
        int page = request.getPage() != null ? request.getPage() : 1;
        int pageSize = request.getPageSize() != null ? request.getPageSize() : 20;
        
        Page<PlatformSkuBinding> pageParam = new Page<>(page, pageSize);
        
        LambdaQueryWrapper<PlatformSkuBinding> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PlatformSkuBinding::getIsActive, true)
                    .orderByDesc(PlatformSkuBinding::getUpdatedAt);
        
        IPage<PlatformSkuBinding> bindingPage = bindingRepository.selectPage(pageParam, queryWrapper);
        
        // 获取关联数据
        Set<Long> platformSkuIds = bindingPage.getRecords().stream()
                .map(PlatformSkuBinding::getPlatformSkuId)
                .collect(Collectors.toSet());
        Set<Long> erpSkuIds = bindingPage.getRecords().stream()
                .map(PlatformSkuBinding::getErpSkuId)
                .collect(Collectors.toSet());
        
        Map<Long, Platform> platformMap = platformRepository.selectBatchIds(platformSkuIds)
                .stream().collect(Collectors.toMap(Platform::getId, p -> p));
        Map<Long, ErpSku> erpSkuMap = erpSkuRepository.selectBatchIds(erpSkuIds)
                .stream().collect(Collectors.toMap(ErpSku::getId, e -> e));
        
        // 转换为DTO
        List<SkuBindingDTO> dtoList = bindingPage.getRecords().stream()
                .map(binding -> {
                    SkuBindingDTO dto = new SkuBindingDTO();
                    dto.setId(binding.getId());
                    dto.setPlatformSkuId(binding.getPlatformSkuId());
                    dto.setErpSkuId(binding.getErpSkuId());
                    dto.setBoundAt(binding.getBoundAt());
                    dto.setCreatedAt(binding.getCreatedAt());
                    dto.setUpdatedAt(binding.getUpdatedAt());
                    
                    Platform platform = platformMap.get(binding.getPlatformSkuId());
                    if (platform != null) {
                        dto.setPlatformTitle(platform.getTitle());
                        dto.setPlatformProductId(platform.getPlatformProductId());
                        dto.setPlatformPrice(platform.getPrice() != null ? platform.getPrice().doubleValue() : null);
                    }
                    
                    ErpSku erpSku = erpSkuMap.get(binding.getErpSkuId());
                    if (erpSku != null) {
                        dto.setErpSkuCode(erpSku.getSkuCode());
                        dto.setErpSkuName(erpSku.getName());
                        dto.setErpSkuAlias(erpSku.getAlias());
                    }
                    return dto;
                })
                .collect(Collectors.toList());
        
        // 构建返回分页
        Page<SkuBindingDTO> resultPage = new Page<>(bindingPage.getCurrent(), bindingPage.getSize(), bindingPage.getTotal());
        resultPage.setRecords(dtoList);
        return resultPage;
    }
    
    @Override
    public IPage<UnmatchedSkuDTO> listUnmatched(SkuMatchPageRequest request) {
        int page = request.getPage() != null ? request.getPage() : 1;
        int pageSize = request.getPageSize() != null ? request.getPageSize() : 20;
        
        // 查询未绑定的平台SKU
        List<Platform> unmatchedPlatforms = platformRepository.findUnmatched();
        
        // 过滤
        List<Platform> filtered = unmatchedPlatforms;
        if (request.getPlatform() != null && !request.getPlatform().isEmpty()) {
            // 根据平台类型过滤（如果有店铺授权信息）
        }
        if (request.getKeyword() != null && !request.getKeyword().isEmpty()) {
            String keyword = request.getKeyword().toLowerCase();
            filtered = filtered.stream()
                    .filter(p -> (p.getTitle() != null && p.getTitle().toLowerCase().contains(keyword)) ||
                                  (p.getPlatformProductId() != null && p.getPlatformProductId().toLowerCase().contains(keyword)))
                    .collect(Collectors.toList());
        }
        
        // 分页
        int total = filtered.size();
        int fromIndex = (page - 1) * pageSize;
        int toIndex = Math.min(fromIndex + pageSize, total);
        List<Platform> pagedList = fromIndex < total ? filtered.subList(fromIndex, toIndex) : Collections.emptyList();
        
        // 转换为DTO
        List<UnmatchedSkuDTO> dtoList = pagedList.stream()
                .map(platform -> {
                    UnmatchedSkuDTO dto = new UnmatchedSkuDTO();
                    dto.setId(platform.getId());
                    dto.setPlatformProductId(platform.getPlatformProductId());
                    dto.setPlatformSkuId(platform.getPlatformSkuId());
                    dto.setTitle(platform.getTitle());
                    dto.setPrice(platform.getPrice() != null ? platform.getPrice().doubleValue() : null);
                    dto.setStock(platform.getStock());
                    dto.setStatus(platform.getStatus());
                    dto.setStatusText(platform.getStatusLabel());
                    dto.setLastSyncAt(platform.getLastSyncAt());
                    return dto;
                })
                .collect(Collectors.toList());
        
        // 构建返回分页
        Page<UnmatchedSkuDTO> resultPage = new Page<>(page, pageSize, total);
        resultPage.setRecords(dtoList);
        return resultPage;
    }
    
    // ==================== 绑定/解绑接口实现 ====================
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public SkuBindingDTO manualBind(ManualBindRequest request, Long tenantId) {
        Long platformSkuId = request.getPlatformSkuId();
        Long erpSkuId = request.getErpSkuId();
        
        // 校验平台SKU是否存在
        Platform platformSku = platformRepository.selectById(platformSkuId);
        if (platformSku == null) {
            throw new BusinessException("平台SKU不存在");
        }
        
        // 校验ERP SKU是否存在
        ErpSku erpSku = erpSkuRepository.selectById(erpSkuId);
        if (erpSku == null) {
            throw new BusinessException("ERP SKU不存在");
        }
        
        // 解绑旧的生效绑定
        bindingRepository.deactivateByPlatformSkuId(platformSkuId);
        
        // 创建新绑定
        PlatformSkuBinding binding = new PlatformSkuBinding();
        binding.setPlatformSkuId(platformSkuId);
        binding.setErpSkuId(erpSkuId);
        binding.setIsActive(true);
        binding.setBoundAt(LocalDateTime.now());
        binding.setReason(request.getReason() != null ? request.getReason() : "manual");
        binding.setCreatedAt(LocalDateTime.now());
        binding.setUpdatedAt(LocalDateTime.now());
        bindingRepository.insert(binding);
        
        // 同步更新订单明细的匹配状态
        orderItemRepository.updateMatchByPlatformSku(
                platformSku.getPlatformProductId(),
                erpSkuId,
                erpSku.getSkuCode()
        );
        
        // 记录匹配日志
        List<OrderItem> orderItems = orderItemRepository.findByOrderId(null); // 需要根据platformProductId查询
        // 注意：这里需要修改查询逻辑，根据platformProductId查询订单明细
        saveMatchLogs(orderItems, platformSku.getPlatformProductId(), erpSkuId, "manual");
        
        log.info("SKU手动匹配 - tenantId:{}, platformSkuId:{}, erpSkuId:{}, boundAt:{}",
                tenantId, platformSkuId, erpSkuId, binding.getBoundAt());
        
        // 构建返回DTO
        SkuBindingDTO dto = new SkuBindingDTO();
        dto.setId(binding.getId());
        dto.setPlatformSkuId(platformSkuId);
        dto.setPlatformTitle(platformSku.getTitle());
        dto.setPlatformProductId(platformSku.getPlatformProductId());
        dto.setPlatformPrice(platformSku.getPrice() != null ? platformSku.getPrice().doubleValue() : null);
        dto.setErpSkuId(erpSkuId);
        dto.setErpSkuCode(erpSku.getSkuCode());
        dto.setErpSkuName(erpSku.getName());
        dto.setErpSkuAlias(erpSku.getAlias());
        dto.setBoundAt(binding.getBoundAt());
        dto.setCreatedAt(binding.getCreatedAt());
        dto.setUpdatedAt(binding.getUpdatedAt());
        
        return dto;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void unbind(Long bindingId, Long tenantId) {
        PlatformSkuBinding binding = bindingRepository.selectById(bindingId);
        if (binding == null) {
            throw new BusinessException("绑定记录不存在");
        }
        
        // 解绑
        binding.setIsActive(false);
        binding.setUnboundAt(LocalDateTime.now());
        binding.setUpdatedAt(LocalDateTime.now());
        bindingRepository.updateById(binding);
        
        // 查找并更新关联的订单明细
        Platform platformSku = platformRepository.selectById(binding.getPlatformSkuId());
        if (platformSku != null) {
            orderItemRepository.resetMatchStatus(platformSku.getPlatformProductId(), binding.getErpSkuId());
        }
        
        log.info("SKU解绑 - tenantId:{}, bindingId:{}", tenantId, bindingId);
    }
    
    // ==================== 规则匹配接口实现 ====================
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public RuleMatchResponse ruleMatch(RuleMatchRequest request, Long tenantId) {
        List<String> rules = request.getRules() != null && !request.getRules().isEmpty() 
                ? request.getRules() 
                : DEFAULT_RULES;
        String matchScope = request.getMatchScope() != null ? request.getMatchScope() : "unmatched_only";
        
        // 获取待匹配的平台SKU
        List<Platform> platformSkus;
        if ("all".equals(matchScope)) {
            platformSkus = platformRepository.selectList(null);
        } else {
            // 只匹配在售且未绑定的
            platformSkus = platformRepository.findUnmatchedByStatus("on_sale");
        }
        
        // 加载所有ERP SKU并建立映射
        List<ErpSku> allErpSkus = erpSkuRepository.selectList(null);
        Map<String, ErpSku> erpSkuByCode = allErpSkus.stream()
                .collect(Collectors.toMap(ErpSku::getSkuCode, e -> e, (e1, e2) -> e1));
        Map<String, ErpSku> erpSkuByAlias = allErpSkus.stream()
                .filter(e -> e.getAlias() != null && !e.getAlias().isEmpty())
                .collect(Collectors.toMap(ErpSku::getAlias, e -> e, (e1, e2) -> e1));
        
        int matched = 0;
        int failed = 0;
        List<RuleMatchResultDTO> details = new ArrayList<>();
        
        for (Platform platformSku : platformSkus) {
            // 应用匹配规则
            MatchResult result = applyMatchRules(platformSku, erpSkuByCode, erpSkuByAlias, rules);
            
            if (result.matched()) {
                ErpSku erpSku = result.erpSku();
                String rule = result.rule();
                
                // 解绑旧的
                bindingRepository.deactivateByPlatformSkuId(platformSku.getId());
                
                // 创建新绑定
                PlatformSkuBinding binding = new PlatformSkuBinding();
                binding.setPlatformSkuId(platformSku.getId());
                binding.setErpSkuId(erpSku.getId());
                binding.setIsActive(true);
                binding.setBoundAt(LocalDateTime.now());
                binding.setReason("rule:" + rule);
                binding.setCreatedAt(LocalDateTime.now());
                binding.setUpdatedAt(LocalDateTime.now());
                bindingRepository.insert(binding);
                
                // 同步订单明细
                orderItemRepository.updateMatchByPlatformSku(
                        platformSku.getPlatformProductId(),
                        erpSku.getId(),
                        erpSku.getSkuCode()
                );
                
                // 记录日志
                saveMatchLogs(null, platformSku.getPlatformProductId(), erpSku.getId(), "rule");
                
                matched++;
                RuleMatchResultDTO detail = new RuleMatchResultDTO();
                detail.setPlatformSkuId(platformSku.getId());
                detail.setPlatformProductId(platformSku.getPlatformProductId());
                detail.setTitle(platformSku.getTitle());
                detail.setErpSkuId(erpSku.getId());
                detail.setErpSkuCode(erpSku.getSkuCode());
                detail.setErpSkuName(erpSku.getName());
                detail.setRule(rule);
                details.add(detail);
            } else {
                failed++;
            }
        }
        
        log.info("SKU规则匹配 - tenantId:{}, matched:{}, failed:{}, rules:{}", tenantId, matched, failed, rules);
        
        RuleMatchResponse response = new RuleMatchResponse();
        response.setMatched(matched);
        response.setFailed(failed);
        response.setDetails(details);
        return response;
    }
    
    /**
     * 应用匹配规则
     */
    @Override
    public MatchResult applyMatchRules(Platform platformSku, Map<String, ErpSku> erpSkuMap, List<String> rules) {
        // 需要同时传入byCode和byAlias两个map
        return applyMatchRules(platformSku, erpSkuMap, new HashMap<>(), rules);
    }
    
    private MatchResult applyMatchRules(Platform platformSku, 
                                         Map<String, ErpSku> erpSkuByCode,
                                         Map<String, ErpSku> erpSkuByAlias,
                                         List<String> rules) {
        String platformProductId = platformSku.getPlatformProductId();
        String title = platformSku.getTitle();
        
        // 规则1: 精确匹配 SKU code
        if (rules.contains("exact_code")) {
            ErpSku erpSku = erpSkuByCode.get(platformProductId);
            if (erpSku != null) {
                return new MatchResult(true, erpSku, "exact_code");
            }
        }
        
        // 规则2: 精确匹配别名
        if (rules.contains("exact_alias")) {
            ErpSku erpSku = erpSkuByAlias.get(platformProductId);
            if (erpSku != null) {
                return new MatchResult(true, erpSku, "exact_alias");
            }
        }
        
        // 规则3: 模糊匹配名称
        if (rules.contains("fuzzy_name") && title != null) {
            for (ErpSku erpSku : erpSkuByCode.values()) {
                String name = erpSku.getName();
                if (name != null && !name.isEmpty() && title.contains(name)) {
                    return new MatchResult(true, erpSku, "fuzzy_name");
                }
            }
        }
        
        return new MatchResult(false, null, null);
    }
    
    // ==================== AI匹配接口实现 ====================
    
    @Override
    public SkuMatchAiTaskResponse aiMatch(AiMatchRequest request, Long tenantId) {
        // 获取待匹配的平台SKU
        List<Platform> platformSkus;
        if (request.getPlatformSkuIds() != null && !request.getPlatformSkuIds().isEmpty()) {
            platformSkus = platformRepository.findUnmatchedByIds(request.getPlatformSkuIds());
        } else if ("all".equals(request.getMatchScope())) {
            platformSkus = platformRepository.selectList(null);
        } else {
            platformSkus = platformRepository.findUnmatchedByStatus("on_sale");
        }
        
        if (platformSkus.isEmpty()) {
            throw new BusinessException("没有需要匹配的SKU");
        }
        
        // 生成任务ID
        String taskId = "ai_match_" + UUID.randomUUID().toString().replace("-", "");
        
        // 构建任务数据
        Map<String, Object> taskData = new HashMap<>();
        taskData.put("task_id", taskId);
        taskData.put("tenant_id", tenantId);
        taskData.put("platform_sku_ids", platformSkus.stream().map(Platform::getId).collect(Collectors.toList()));
        taskData.put("initiated_at", LocalDateTime.now().toString());
        
        Map<String, Object> queueMessage = new HashMap<>();
        queueMessage.put("type", "ai_sku_match");
        queueMessage.put("payload", taskData);
        
        // 投递到Redis队列
        try {
            redisTemplate.opsForList().leftPush(aiQueueName, new com.fasterxml.jackson.databind.ObjectMapper().writeValueAsString(queueMessage));
        } catch (com.fasterxml.jackson.core.JsonProcessingException e) {
            log.error("序列化AI匹配任务失败", e);
            throw new RuntimeException("序列化AI匹配任务失败", e);
        }
        
        log.info("AI匹配任务已投递 - taskId:{}, totalSkus:{}", taskId, platformSkus.size());
        
        SkuMatchAiTaskResponse response = new SkuMatchAiTaskResponse();
        response.setTaskId(taskId);
        response.setTotalSkus(platformSkus.size());
        response.setStatus("pending");
        return response;
    }
    
    // ==================== 订单匹配接口实现 ====================
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public OrderMatchResult matchOrderItems(Long orderId) {
        // 查询订单明细
        List<OrderItem> orderItems = orderItemRepository.findByOrderId(orderId);
        boolean allMatched = true;
        
        for (OrderItem item : orderItems) {
            String platformSkuCode = item.getPlatformSku();
            if (platformSkuCode == null || platformSkuCode.isEmpty()) {
                continue;
            }
            
            // 查找平台SKU
            LambdaQueryWrapper<Platform> platformQuery = new LambdaQueryWrapper<>();
            platformQuery.eq(Platform::getPlatformProductId, platformSkuCode);
            Platform platformSku = platformRepository.selectOne(platformQuery);
            
            if (platformSku != null) {
                // 查找当前生效的绑定
                PlatformSkuBinding activeBinding = bindingRepository.findActiveByPlatformSkuId(platformSku.getId());
                
                if (activeBinding != null) {
                    item.setErpSkuId(activeBinding.getErpSkuId());
                    item.setMatchStatus(1);
                    orderItemRepository.updateById(item);
                    
                    // 记录匹配日志
                    MatchLog matchLog = new MatchLog();
                    matchLog.setOrderItemId(item.getId());
                    matchLog.setPlatformSku(platformSkuCode);
                    matchLog.setErpSkuId(activeBinding.getErpSkuId());
                    matchLog.setMatchType("auto");
                    matchLog.setCreatedAt(LocalDateTime.now());
                    matchLogRepository.insert(matchLog);
                } else {
                    allMatched = false;
                    item.setMatchStatus(0);
                    orderItemRepository.updateById(item);
                    
                    // 记录未匹配日志
                    UnmatchedLog unmatchedLog = new UnmatchedLog();
                    unmatchedLog.setOrderItemId(item.getId());
                    unmatchedLog.setPlatformSku(platformSkuCode);
                    unmatchedLog.setReason("no_active_binding");
                    unmatchedLog.setCreatedAt(LocalDateTime.now());
                    unmatchedLogRepository.insert(unmatchedLog);
                }
            } else {
                allMatched = false;
                item.setMatchStatus(0);
                orderItemRepository.updateById(item);
                
                // 记录未匹配日志
                UnmatchedLog unmatchedLog = new UnmatchedLog();
                unmatchedLog.setOrderItemId(item.getId());
                unmatchedLog.setPlatformSku(platformSkuCode);
                unmatchedLog.setReason("platform_sku_not_found");
                unmatchedLog.setCreatedAt(LocalDateTime.now());
                unmatchedLogRepository.insert(unmatchedLog);
            }
        }
        
        int matchedCount = (int) orderItems.stream().filter(i -> i.getMatchStatus() != null && i.getMatchStatus() == 1).count();
        
        return new OrderMatchResult(orderId, allMatched, matchedCount, orderItems.size());
    }
    
    // ==================== 内部方法 ====================
    
    private void saveMatchLogs(List<OrderItem> orderItems, String platformProductId, Long erpSkuId, String matchType) {
        // 如果没有传入orderItems，根据platformProductId查询
        if (orderItems == null || orderItems.isEmpty()) {
            LambdaQueryWrapper<OrderItem> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(OrderItem::getPlatformSku, platformProductId);
            orderItems = orderItemRepository.selectList(queryWrapper);
        }
        
        for (OrderItem item : orderItems) {
            MatchLog matchLog = new MatchLog();
            matchLog.setOrderItemId(item.getId());
            matchLog.setPlatformSku(platformProductId);
            matchLog.setErpSkuId(erpSkuId);
            matchLog.setMatchType(matchType);
            matchLog.setCreatedAt(LocalDateTime.now());
            matchLogRepository.insert(matchLog);
        }
    }
}
