package com.gxwebsoft.cms.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gxwebsoft.cms.entity.CustomerLeadEntity;
import com.gxwebsoft.cms.entity.LeadDispatch;
import com.gxwebsoft.cms.entity.LeadFollowLog;
import com.gxwebsoft.cms.mapper.CustomerLeadMapper;
import com.gxwebsoft.cms.mapper.LeadDispatchMapper;
import com.gxwebsoft.cms.mapper.LeadFollowLogMapper;
import com.gxwebsoft.cms.param.CustomerLeadParam;
import com.gxwebsoft.cms.param.LeadDispatchParam;
import com.gxwebsoft.cms.param.LeadFollowParam;
import com.gxwebsoft.cms.service.CustomerLeadService;
import com.gxwebsoft.common.system.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
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.util.*;

/**
 * 客资管理服务实现
 *
 * @author 科技小王子
 * @since 2026-04-14
 */
@Service
public class CustomerLeadServiceImpl extends ServiceImpl<CustomerLeadMapper, CustomerLeadEntity> implements CustomerLeadService {

    @Autowired
    private CustomerLeadMapper customerLeadMapper;

    @Autowired
    private LeadDispatchMapper leadDispatchMapper;

    @Autowired
    private LeadFollowLogMapper leadFollowLogMapper;

    /**
     * 获取当前登录用户（与 BaseController.getLoginUser() 逻辑一致）
     */
    private User getLoginUser() {
        try {
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            if (authentication != null) {
                Object principal = authentication.getPrincipal();
                if (principal instanceof User) {
                    return (User) principal;
                }
            }
        } catch (Exception ignored) {
        }
        return null;
    }

    @Override
    public Map<String, Object> getLeadPage(CustomerLeadParam param) {
        // 处理分页参数
        if (param.getPageNum() == null || param.getPageNum() < 1) {
            param.setPageNum(1);
        }
        if (param.getPageSize() == null || param.getPageSize() < 1 || param.getPageSize() > 100) {
            param.setPageSize(10);
        }

        Page<CustomerLeadEntity> page = new Page<>(param.getPageNum(), param.getPageSize());
        List<CustomerLeadEntity> list = customerLeadMapper.selectLeadPage(param);
        long total = page.getTotal();

        Map<String, Object> result = new HashMap<>();
        result.put("list", list);
        result.put("total", total);
        result.put("pageNum", param.getPageNum());
        result.put("pageSize", param.getPageSize());
        result.put("pages", (total + param.getPageSize() - 1) / param.getPageSize());

        return result;
    }

    @Override
    public CustomerLeadEntity getLeadDetail(Integer leadId) {
        return customerLeadMapper.selectLeadDetail(leadId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public CustomerLeadEntity createLead(CustomerLeadParam param) {
        CustomerLeadEntity lead = new CustomerLeadEntity();
        lead.setName(param.getName());
        lead.setPhone(param.getPhone());
        lead.setCompany(param.getCompany());
        lead.setNeed(param.getNeed());
        lead.setStatus(CustomerLeadEntity.STATUS_PENDING); // 默认待跟进
        lead.setSourceType(CustomerLeadEntity.SOURCE_ADMIN); // 管理员录入
        lead.setReferralFee(BigDecimal.ZERO);
        lead.setReferralFeePaid(0);
        lead.setFollowCount(0);
        
        // 如果指定了业务员，直接派单
        if (param.getAssignedUserId() != null) {
            User currentUser = getLoginUser();
            lead.setAssignedUserId(param.getAssignedUserId());
            lead.setDispatchTime(LocalDateTime.now());
            lead.setDispatchAdminId(currentUser != null ? currentUser.getUserId() : null);
            lead.setStatus(CustomerLeadEntity.STATUS_FOLLOWING);
        }
        
        this.save(lead);
        return lead;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateLead(CustomerLeadParam param) {
        CustomerLeadEntity lead = this.getById(param.getLeadId());
        if (lead == null) {
            throw new RuntimeException("客资不存在");
        }

        if (StringUtils.hasText(param.getName())) {
            lead.setName(param.getName());
        }
        if (StringUtils.hasText(param.getPhone())) {
            lead.setPhone(param.getPhone());
        }
        if (StringUtils.hasText(param.getCompany())) {
            lead.setCompany(param.getCompany());
        }
        if (StringUtils.hasText(param.getNeed())) {
            lead.setNeed(param.getNeed());
        }
        if (StringUtils.hasText(param.getRemarks())) {
            lead.setRemarks(param.getRemarks());
        }
        if (param.getDealAmount() != null) {
            lead.setDealAmount(param.getDealAmount());
            lead.setDealTime(LocalDateTime.now());
        }

        return this.updateById(lead);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateLeadStatus(Integer leadId, Integer status, String remarks) {
        CustomerLeadEntity lead = this.getById(leadId);
        if (lead == null) {
            throw new RuntimeException("客资不存在");
        }

        lead.setStatus(status);
        if (StringUtils.hasText(remarks)) {
            lead.setRemarks(remarks);
        }

        // 成交时记录成交时间
        if (status == CustomerLeadEntity.STATUS_DEALED) {
            lead.setDealTime(LocalDateTime.now());
        }

        return this.updateById(lead);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean dispatchLead(LeadDispatchParam param) {
        CustomerLeadEntity lead = this.getById(param.getLeadId());
        if (lead == null) {
            throw new RuntimeException("客资不存在");
        }

        User currentUser = getLoginUser();
        Integer adminId = currentUser != null ? currentUser.getUserId() : null;

        // 更新客资分配信息
        lead.setAssignedUserId(param.getToUserId());
        lead.setDispatchTime(LocalDateTime.now());
        lead.setDispatchAdminId(adminId);
        lead.setStatus(CustomerLeadEntity.STATUS_FOLLOWING); // 派单后变为跟进中

        // 如果有备注，更新备注
        if (StringUtils.hasText(param.getRemarks())) {
            String oldRemarks = lead.getRemarks() != null ? lead.getRemarks() + "\n" : "";
            lead.setRemarks(oldRemarks + "【派单备注】" + param.getRemarks());
        }

        this.updateById(lead);

        // 记录派单历史
        LeadDispatch dispatch = new LeadDispatch();
        dispatch.setLeadId(param.getLeadId());
        dispatch.setFromUserId(lead.getAssignedUserId()); // 原分配用户
        dispatch.setToUserId(param.getToUserId());
        dispatch.setAdminId(adminId);
        dispatch.setDispatchRemarks(param.getRemarks());
        dispatch.setDispatchType(param.getDispatchType() != null ? param.getDispatchType() : LeadDispatch.TYPE_NEW);
        dispatch.setCreateTime(LocalDateTime.now());
        leadDispatchMapper.insert(dispatch);

        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> batchDispatchLeads(LeadDispatchParam param) {
        Map<String, Object> result = new HashMap<>();
        int successCount = 0;
        int failCount = 0;
        List<String> errors = new ArrayList<>();

        if (param.getLeadIds() == null || param.getLeadIds().length == 0) {
            throw new RuntimeException("请选择要派单的客资");
        }

        User currentUser = getLoginUser();
        Integer adminId = currentUser != null ? currentUser.getUserId() : null;

        for (Integer leadId : param.getLeadIds()) {
            try {
                LeadDispatchParam singleParam = new LeadDispatchParam();
                singleParam.setLeadId(leadId);
                singleParam.setToUserId(param.getToUserId());
                singleParam.setRemarks(param.getRemarks());
                singleParam.setDispatchType(LeadDispatch.TYPE_NEW);
                
                this.dispatchLead(singleParam);
                successCount++;
            } catch (Exception e) {
                failCount++;
                errors.add("客资ID[" + leadId + "]: " + e.getMessage());
            }
        }

        result.put("successCount", successCount);
        result.put("failCount", failCount);
        result.put("errors", errors);

        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addFollowLog(LeadFollowParam param) {
        CustomerLeadEntity lead = this.getById(param.getLeadId());
        if (lead == null) {
            throw new RuntimeException("客资不存在");
        }

        User currentUser = getLoginUser();
        Integer userId = currentUser != null ? currentUser.getUserId() : null;

        // 添加跟进记录
        LeadFollowLog followLog = new LeadFollowLog();
        followLog.setLeadId(param.getLeadId());
        followLog.setUserId(userId);
        followLog.setFollowType(param.getFollowType());
        followLog.setFollowContent(param.getFollowContent());
        followLog.setNextFollowPlan(param.getNextFollowPlan());
        followLog.setAttachmentUrls(param.getAttachmentUrls());
        followLog.setCreateTime(LocalDateTime.now());
        
        if (StringUtils.hasText(param.getNextFollowTime())) {
            followLog.setNextFollowTime(LocalDateTime.parse(param.getNextFollowTime().replace(" ", "T")));
        }
        
        leadFollowLogMapper.insert(followLog);

        // 更新客资跟进信息
        lead.setFollowCount(lead.getFollowCount() != null ? lead.getFollowCount() + 1 : 1);
        lead.setLastFollowTime(LocalDateTime.now());
        
        // 如果需要更新状态
        if (Boolean.TRUE.equals(param.getUpdateStatus()) && param.getNewStatus() != null) {
            lead.setStatus(param.getNewStatus());
        }
        
        // 如果是成交
        if (param.getNewStatus() != null && param.getNewStatus() == CustomerLeadEntity.STATUS_DEALED) {
            lead.setDealTime(LocalDateTime.now());
        }

        return this.updateById(lead);
    }

    @Override
    public List<Map<String, Object>> getFollowHistory(Integer leadId) {
        List<LeadFollowLog> logs = leadFollowLogMapper.selectFollowHistory(leadId);
        List<Map<String, Object>> result = new ArrayList<>();
        
        for (LeadFollowLog log : logs) {
            Map<String, Object> item = new HashMap<>();
            item.put("followId", log.getFollowId());
            item.put("followType", log.getFollowType());
            item.put("followTypeText", log.getFollowTypeText());
            item.put("followContent", log.getFollowContent());
            item.put("nextFollowTime", log.getNextFollowTime());
            item.put("nextFollowPlan", log.getNextFollowPlan());
            item.put("userName", log.getUserName());
            item.put("createTime", log.getCreateTime());
            result.add(item);
        }
        
        return result;
    }

    @Override
    public Map<String, Object> getStatistics(CustomerLeadParam param) {
        Map<String, Object> stats = new HashMap<>();
        
        // 基础统计
        Map<String, Object> basicStats = customerLeadMapper.selectStatistics(
                param.getStartDate(), param.getEndDate(), param.getSalesmanId());
        stats.put("basic", basicStats);
        
        // 按状态统计
        stats.put("byStatus", customerLeadMapper.selectStatusStatistics(param.getStartDate(), param.getEndDate()));
        
        // 按来源统计
        stats.put("bySource", customerLeadMapper.selectSourceStatistics(param.getStartDate(), param.getEndDate()));
        
        // 每日趋势
        stats.put("dailyTrend", customerLeadMapper.selectDailyTrend(param.getStartDate(), param.getEndDate()));
        
        return stats;
    }

    @Override
    public List<Map<String, Object>> exportLeads(CustomerLeadParam param) {
        // 设置不分页，导出全部
        param.setPageNum(1);
        param.setPageSize(10000);
        
        List<CustomerLeadEntity> leads = customerLeadMapper.selectLeadPage(param);
        List<Map<String, Object>> result = new ArrayList<>();
        
        for (CustomerLeadEntity lead : leads) {
            Map<String, Object> item = new HashMap<>();
            item.put("客户姓名", lead.getName());
            item.put("联系电话", lead.getPhone());
            item.put("公司名称", lead.getCompany());
            item.put("需求描述", lead.getNeed());
            item.put("状态", lead.getStatusText());
            item.put("来源", lead.getSourceType());
            item.put("业务员", lead.getAssignedUserName());
            item.put("推荐人", lead.getReferrerName());
            item.put("跟进次数", lead.getFollowCount());
            item.put("成交金额", lead.getDealAmount());
            item.put("创建时间", lead.getCreateTime());
            item.put("派单时间", lead.getDispatchTime());
            item.put("成交时间", lead.getDealTime());
            item.put("备注", lead.getRemarks());
            result.add(item);
        }
        
        return result;
    }

    @Override
    public List<CustomerLeadEntity> getUnassignedLeads() {
        return customerLeadMapper.selectUnassignedLeads();
    }

    @Override
    public Map<String, Object> getSalesmanLeadStats(Integer salesmanId) {
        Map<String, Object> stats = new HashMap<>();
        
        stats.put("total", customerLeadMapper.countBySalesman(salesmanId, null));
        stats.put("pending", customerLeadMapper.countBySalesman(salesmanId, CustomerLeadEntity.STATUS_PENDING));
        stats.put("following", customerLeadMapper.countBySalesman(salesmanId, CustomerLeadEntity.STATUS_FOLLOWING));
        stats.put("dealed", customerLeadMapper.countBySalesman(salesmanId, CustomerLeadEntity.STATUS_DEALED));
        stats.put("invalid", customerLeadMapper.countBySalesman(salesmanId, CustomerLeadEntity.STATUS_INVALID));
        
        return stats;
    }
}
