package com.fs.sop.service.impl;

import com.fs.common.utils.StringUtils;
import com.fs.company.domain.Company;
import com.fs.company.mapper.CompanyMapper;
import com.fs.course.domain.FsUserCourse;
import com.fs.course.domain.FsUserCourseVideo;
import com.fs.course.mapper.FsUserCourseMapper;
import com.fs.course.mapper.FsUserCourseVideoMapper;
import com.fs.qw.cache.QwSopCacheService;
import com.fs.sop.domain.QwMassSendLog;
import com.fs.sop.domain.QwSop;
import com.fs.sop.mapper.QwMassSendLogMapper;
import com.fs.sop.mapper.QwSopMapper;
import com.fs.sop.params.SendUserLogsInfoMsgParam;
import com.fs.sop.service.IQwMassSendLogService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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 java.lang.reflect.Method;
import java.util.List;

/**
 * 一键群发销售点击行为日志（默认主库 fs_his，无需切 SOP）
 */
@Service
public class QwMassSendLogServiceImpl implements IQwMassSendLogService {

    private static final Logger log = LoggerFactory.getLogger(QwMassSendLogServiceImpl.class);

    @Autowired
    private QwMassSendLogMapper qwMassSendLogMapper;

    @Autowired
    private CompanyMapper companyMapper;

    @Autowired
    private FsUserCourseMapper fsUserCourseMapper;

    @Autowired
    private FsUserCourseVideoMapper fsUserCourseVideoMapper;

    @Autowired
    private QwSopMapper qwSopMapper;

    /**
     * 与主库统计同口径：内部调用 QwSopMapper.selectQwSopNameBySopId（@DataSource(SOP)）
     */
    @Autowired
    private QwSopCacheService qwSopCacheService;

    @Override
    public void saveMassSendClickLog(SendUserLogsInfoMsgParam param, int customerCount, int sendSource, Long companyIdHint) {
        try {
            QwMassSendLog row = new QwMassSendLog();
            row.setCustomerCount(customerCount < 0 ? 0 : customerCount);
            row.setSendSource(sendSource);
            if (param != null) {
                row.setContentJson(param.getSetting());
                row.setCorpId(param.getCorpId());
                row.setSopId(resolveSopId(param));
                if (param.getSopName() != null && !param.getSopName().isEmpty()) {
                    row.setSopName(param.getSopName());
                }
                if (param.getCourseId() != null) {
                    row.setCourseId(param.getCourseId().longValue());
                }
                if (param.getVideoId() != null) {
                    row.setVideoId(param.getVideoId().longValue());
                }
            }
            fillOperator(row);
            fillCompany(row, companyIdHint);
            fillCourseName(row);
            fillVideoName(row);
            fillSopName(row);
            qwMassSendLogMapper.insertQwMassSendLog(row);
        } catch (Exception e) {
            log.error("记录一键群发点击日志失败，不影响群发主流程", e);
        }
    }

    @Override
    public QwMassSendLog selectQwMassSendLogById(Long id) {
        return qwMassSendLogMapper.selectQwMassSendLogById(id);
    }

    @Override
    public List<QwMassSendLog> selectQwMassSendLogList(QwMassSendLog query) {
        return qwMassSendLogMapper.selectQwMassSendLogList(query);
    }

    /**
     * 解析 sopId：优先 param.sopId，否则取 sopIds 首个
     */
    private static String resolveSopId(SendUserLogsInfoMsgParam param) {
        if (param == null) {
            return null;
        }
        if (param.getSopId() != null && !param.getSopId().isEmpty()) {
            return param.getSopId();
        }
        if (param.getSopIds() != null && param.getSopIds().length > 0
                && param.getSopIds()[0] != null && !param.getSopIds()[0].isEmpty()) {
            return param.getSopIds()[0];
        }
        return null;
    }

    /**
     * 兼容公司端 LoginUser（CompanyUser）与总后台 LoginUser（SysUser）
     */
    private void fillOperator(QwMassSendLog row) {
        try {
            Authentication auth = SecurityContextHolder.getContext().getAuthentication();
            if (auth == null || auth.getPrincipal() == null) {
                return;
            }
            Object principal = auth.getPrincipal();
            Object user = invokeNoArg(principal, "getUser");
            if (user != null) {
                Object userId = invokeNoArg(user, "getUserId");
                if (userId instanceof Number) {
                    row.setCompanyUserId(((Number) userId).longValue());
                }
                Object nickName = invokeNoArg(user, "getNickName");
                if (nickName != null) {
                    row.setCompanyUserName(String.valueOf(nickName));
                } else {
                    Object userName = invokeNoArg(user, "getUserName");
                    if (userName != null) {
                        row.setCompanyUserName(String.valueOf(userName));
                    }
                }
                row.setCreateBy(row.getCompanyUserName());
            }
            Object company = invokeNoArg(principal, "getCompany");
            if (company != null) {
                Object companyId = invokeNoArg(company, "getCompanyId");
                if (companyId instanceof Number) {
                    row.setCompanyId(((Number) companyId).longValue());
                }
                Object companyName = invokeNoArg(company, "getCompanyName");
                if (companyName != null) {
                    row.setCompanyName(String.valueOf(companyName));
                }
            }
        } catch (Exception e) {
            log.warn("解析一键群发操作人信息失败: {}", e.getMessage());
        }
    }

    private void fillCompany(QwMassSendLog row, Long companyIdHint) {
        if (row.getCompanyId() == null && companyIdHint != null) {
            row.setCompanyId(companyIdHint);
        }
        if (row.getCompanyId() != null && (row.getCompanyName() == null || row.getCompanyName().isEmpty())) {
            try {
                Company company = companyMapper.selectCompanyById(row.getCompanyId());
                if (company != null) {
                    row.setCompanyName(company.getCompanyName());
                }
            } catch (Exception e) {
                log.warn("查询公司名称失败 companyId={}", row.getCompanyId());
            }
        }
    }

    private void fillCourseName(QwMassSendLog row) {
        if (row.getCourseId() == null) {
            return;
        }
        try {
            FsUserCourse course = fsUserCourseMapper.selectFsUserCourseByCourseId(row.getCourseId());
            if (course != null) {
                row.setCourseName(course.getCourseName());
            }
        } catch (Exception e) {
            log.warn("查询课程名称失败 courseId={}", row.getCourseId());
        }
    }

    /**
     * 按 videoId 查课节/小结标题
     */
    private void fillVideoName(QwMassSendLog row) {
        if (row.getVideoId() == null) {
            return;
        }
        try {
            FsUserCourseVideo video = fsUserCourseVideoMapper.selectFsUserCourseVideoByVideoId(row.getVideoId());
            if (video != null) {
                row.setVideoName(video.getTitle());
            }
        } catch (Exception e) {
            log.warn("查询课节名称失败 videoId={}", row.getVideoId());
        }
    }

    /**
     * 填充 SOP 名称：已有前端/调用方传入则不覆盖；否则按 sopId 查 SOP 库
     * 1) QwSopCacheService（内部走 Mapper，与主库统计同口径）
     * 2) 回退 qwSopMapper.selectQwSopNameBySopId / selectQwSopById（Mapper 上已有 @DataSource(SOP) AOP）
     */
    private void fillSopName(QwMassSendLog row) {
        if (row.getSopName() != null && !row.getSopName().isEmpty()) {
            return;
        }
        if (row.getSopId() == null || row.getSopId().isEmpty()) {
            return;
        }
        try {
            String cached = qwSopCacheService.getQwSopNameBySopId(row.getSopId());
            if (StringUtils.isNotBlank(cached) && !"-".equals(cached)) {
                row.setSopName(cached);
                return;
            }
        } catch (Exception e) {
            log.warn("QwSopCacheService查SOP名称失败 sopId={} err={}", row.getSopId(), e.getMessage());
        }
        try {
            String name = qwSopMapper.selectQwSopNameBySopId(row.getSopId());
            if (StringUtils.isNotBlank(name)) {
                row.setSopName(name);
                return;
            }
            QwSop sop = qwSopMapper.selectQwSopById(row.getSopId());
            if (sop != null && StringUtils.isNotBlank(sop.getName())) {
                row.setSopName(sop.getName());
            } else {
                log.warn("查询SOP名称为空 sopId={}", row.getSopId());
            }
        } catch (Exception e) {
            log.warn("查询SOP名称失败 sopId={} err={}", row.getSopId(), e.getMessage());
        }
    }

    private static Object invokeNoArg(Object target, String methodName) {
        if (target == null) {
            return null;
        }
        try {
            Method method = target.getClass().getMethod(methodName);
            return method.invoke(target);
        } catch (Exception e) {
            return null;
        }
    }
}
