package com.storlead.trade.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.storlead.trade.entity.CustomerAnalysisResultEntity;
import com.storlead.trade.entity.CustomerCompanyEntity;
import com.storlead.trade.entity.CustomerEntity;
import com.storlead.trade.entity.LiaisonEntity;
import com.storlead.trade.service.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.*;

@Service
public class CustomerAiAnalysisServiceImpl implements CustomerAiAnalysisService {

    private static final String AI_ANALYSIS_URL = "http://127.0.0.1:18080/mock/ai/customer/analyze";

    @Resource
    private CustomerEntityService customerEntityService;
    @Resource
    private CustomerCompanyEntityService customerCompanyEntityService;
    @Resource
    private LiaisonEntityService liaisonEntityService;
    @Resource
    private CustomerAnalysisResultEntityService customerAnalysisResultEntityService;

    @Override
    public CustomerAnalysisResultEntity analyzeSingleCustomer(Long customerId, String analysisScene) {
        if (customerId == null) {
            throw new IllegalArgumentException("customerId不能为空");
        }

        CustomerEntity customer = customerEntityService.getOne(new LambdaQueryWrapper<CustomerEntity>()
                .eq(CustomerEntity::getId, customerId)
                .eq(CustomerEntity::getIsDelete, 0)
                .last("limit 1"));
        if (customer == null) {
            throw new IllegalArgumentException("客户不存在");
        }

        CustomerCompanyEntity company = customerCompanyEntityService.getOne(new LambdaQueryWrapper<CustomerCompanyEntity>()
                .eq(CustomerCompanyEntity::getCustomerId, customerId)
                .eq(CustomerCompanyEntity::getIsDelete, 0)
                .orderByDesc(CustomerCompanyEntity::getId)
                .last("limit 1"));

        List<LiaisonEntity> liaisons = liaisonEntityService.list(new LambdaQueryWrapper<LiaisonEntity>()
                .eq(LiaisonEntity::getCustomerId, customerId)
                .eq(LiaisonEntity::getIsDelete, 0)
                .orderByDesc(LiaisonEntity::getHasPrimaryLialison)
                .orderByDesc(LiaisonEntity::getLastFollowUpTime)
                .last("limit 5"));

        String scene = StringUtils.defaultIfBlank(analysisScene, "potential");
        Map<String, Object> requestPayload = buildAiRequest(customer, company, liaisons, scene);

        CustomerAnalysisResultEntity entity = new CustomerAnalysisResultEntity();
        entity.setCustomerId(customer.getId());
//        entity.setTenantId(customer.getTenantId());
        entity.setOwnerBy(customer.getOwnerBy());
        entity.setAnalysisBatchNo(UUID.randomUUID().toString().replace("-", ""));
        entity.setAnalysisScene(scene);
        entity.setAnalysisTime(new Date());

        try {
            @SuppressWarnings("unchecked")
            Map<String, Object> aiResult = new RestTemplate().postForObject(AI_ANALYSIS_URL, requestPayload, Map.class);
            if (aiResult == null || aiResult.isEmpty()) {
                aiResult = buildFallbackResult(customer, company, liaisons);
            }
            applyAiResult(entity, aiResult);
            entity.setAnalysisStatus(1);
        } catch (Exception e) {
            Map<String, Object> fallback = buildFallbackResult(customer, company, liaisons);
            applyAiResult(entity, fallback);
            entity.setAnalysisStatus(0);
            entity.setErrorCode("AI_CALL_FAILED");
            entity.setErrorMessage(e.getMessage());
        }

        customerAnalysisResultEntityService.save(entity);
        return entity;
    }

    private Map<String, Object> buildAiRequest(CustomerEntity customer,
                                               CustomerCompanyEntity company,
                                               List<LiaisonEntity> liaisons,
                                               String scene) {
        Map<String, Object> payload = new HashMap<>();
        payload.put("analysisScene", scene);
        payload.put("customer", customer);
        payload.put("company", company);
        payload.put("liaisons", liaisons);
        return payload;
    }

    private void applyAiResult(CustomerAnalysisResultEntity entity, Map<String, Object> aiResult) {
        entity.setPotentialScore(toDouble(aiResult.get("potentialScore"), 50D));
        entity.setCustomerLevel(String.valueOf(aiResult.getOrDefault("customerLevel", "C")));
        entity.setConfidence(toDouble(aiResult.get("confidence"), 70D));
        entity.setPriority(toInteger(aiResult.get("priority"), 3));
        entity.setCoreTags(String.valueOf(aiResult.getOrDefault("coreTags", "[]")));
        entity.setReasonSummary(String.valueOf(aiResult.getOrDefault("reasonSummary", "基于客户基础信息自动分析")));
        entity.setSuggestedActions(String.valueOf(aiResult.getOrDefault("suggestedActions", "[]")));
        entity.setRiskSignals(String.valueOf(aiResult.getOrDefault("riskSignals", "[]")));
        entity.setFeatureSnapshot(String.valueOf(aiResult.getOrDefault("featureSnapshot", "{}")));
        entity.setModelName(String.valueOf(aiResult.getOrDefault("modelName", "mock-ai")));
        entity.setModelVersion(String.valueOf(aiResult.getOrDefault("modelVersion", "v0")));
        entity.setPromptVersion(String.valueOf(aiResult.getOrDefault("promptVersion", "p0")));
        entity.setErrorCode(null);
        entity.setErrorMessage(null);
        entity.setNextFollowUpAt(calcNextFollowUpDate());
    }

    private Map<String, Object> buildFallbackResult(CustomerEntity customer,
                                                    CustomerCompanyEntity company,
                                                    List<LiaisonEntity> liaisons) {
        Map<String, Object> result = new HashMap<>();
        int score = 40;
        if (customer.getHasOrderForm() != null && customer.getHasOrderForm() == 1) {
            score += 20;
        }
        if (StringUtils.isNotBlank(customer.getIntendedProductsIds())) {
            score += 15;
        }
        if (company != null && StringUtils.isNotBlank(company.getIndustry())) {
            score += 10;
        }
        if (liaisons != null && !liaisons.isEmpty()) {
            score += 10;
        }
        score = Math.min(score, 95);

        String level;
        if (score >= 80) {
            level = "A";
        } else if (score >= 65) {
            level = "B";
        } else if (score >= 50) {
            level = "C";
        } else {
            level = "D";
        }

        result.put("potentialScore", score);
        result.put("customerLevel", level);
        result.put("confidence", 65);
        result.put("priority", "A".equals(level) ? 1 : ("B".equals(level) ? 2 : 3));
        result.put("coreTags", "[\"fallback-rule\",\"single-customer\"]");
        result.put("reasonSummary", "AI接口不可用，已使用本地规则完成潜力分析");
        result.put("suggestedActions", "[\"建议3日内首次触达\",\"建议补全关键联系人信息\"]");
        result.put("riskSignals", score < 60 ? "[\"客户潜力偏低\"]" : "[]");
        result.put("featureSnapshot", "{\"customerId\":" + customer.getId() + "}");
        result.put("modelName", "fallback-rule-engine");
        result.put("modelVersion", "rule-v1");
        result.put("promptVersion", "local");
        return result;
    }

    private Date calcNextFollowUpDate() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_MONTH, 3);
        return calendar.getTime();
    }

    private Double toDouble(Object val, Double defaultValue) {
        if (val == null) {
            return defaultValue;
        }
        try {
            return Double.parseDouble(String.valueOf(val));
        } catch (Exception ignored) {
            return defaultValue;
        }
    }

    private Integer toInteger(Object val, Integer defaultValue) {
        if (val == null) {
            return defaultValue;
        }
        try {
            return Integer.parseInt(String.valueOf(val));
        } catch (Exception ignored) {
            return defaultValue;
        }
    }
}
