package com.gic.haoban.manage.service.service.contact.impl;

import cn.hutool.core.date.*;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.gic.api.base.commons.BusinessException;
import com.gic.api.base.commons.Constant;
import com.gic.api.base.commons.ServiceResponse;
import com.gic.clerk.api.dto.ClerkDTO;
import com.gic.clerk.api.service.ClerkService;
import com.gic.commons.util.UniqueIdUtils;
import com.gic.enterprise.api.constant.EnterpriseServiceEnum;
import com.gic.enterprise.api.dto.StoreDTO;
import com.gic.enterprise.api.service.StoreService;
import com.gic.haoban.app.customer.dto.CustomerDTO;
import com.gic.haoban.app.customer.dto.MemberInfoListParamsDTO;
import com.gic.haoban.app.customer.dto.contact.ContactParamDTO;
import com.gic.haoban.app.customer.dto.contact.ContactSumDTO;
import com.gic.haoban.app.customer.service.api.service.CustomerApiService;
import com.gic.haoban.base.api.common.BasePageInfo;
import com.gic.haoban.manage.api.constants.Manage3Constants;
import com.gic.haoban.manage.api.dto.contact.ContactConfigDTO;
import com.gic.haoban.manage.api.enums.contact.ContactAutoTypeEnum;
import com.gic.haoban.manage.api.enums.contact.ContactFollowTypeEnum;
import com.gic.haoban.manage.api.qdto.contact.ContactFollowQDTO;
import com.gic.haoban.manage.api.qdto.contact.ContactLogQDTO;
import com.gic.haoban.manage.service.dao.mapper.contact.TabContactLogMapper;
import com.gic.haoban.manage.service.entity.contact.TabContactLog;
import com.gic.haoban.manage.service.service.contact.ContactConfigService;
import com.gic.haoban.manage.service.service.contact.ContactFollowService;
import com.gic.haoban.manage.service.service.contact.ContactLogService;
import com.gic.haoban.manage.service.service.content.adaptor.EnterpriseAdaptor;
import com.gic.member.api.dto.MemberStoreClerkDTO;
import com.gic.member.api.dto.es.MemberDataDTO;
import com.gic.member.api.service.MemberService;
import com.gic.search.engine.api.dto.ESResponse;
import com.gic.search.engine.api.dto.dynamic.DynamicDocDTO;
import com.gic.search.engine.api.service.dynamic.ESDataDynamicOperationApiService;
import com.gic.store.goods.service.StoreGoodsService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Objects;

@Service("contactLogService")
public class ContactLogServiceImpl implements ContactLogService {

    private static final Logger logger = LogManager.getLogger(ContactFollowService.class);

    @Autowired
    private TabContactLogMapper contactLogMapper;
    @Autowired
    private ContactConfigService contactConfigService;
    @Autowired
    private ContactFollowService contactFollowService;
    @Autowired
    private StoreGoodsService storeGoodsService;
    @Autowired
    private ClerkService clerkService;
    @Autowired
    private StoreService storeService;
    @Autowired
    private MemberService memberService;
    @Autowired
    private CustomerApiService customerApiService;
    @Autowired
    private ESDataDynamicOperationApiService esDataDynamicOperationApiService;
    @Autowired
    private EnterpriseAdaptor enterpriseAdaptor;

    @Override
    public boolean contactCheck(String enterpriseId,String memberId,ClerkDTO clerkDTO) {
        if (clerkDTO == null) {
            return false;
        }
        CustomerDTO params = new CustomerDTO();
        int clerkType = clerkDTO.getClerkType();
        String clerkId = clerkDTO.getClerkId();
        String storeId = "";
        if (clerkType == 0 || clerkType == 1) {
            storeId = clerkDTO.getStoreId();
        }
        params.setClerkType(clerkType + "");
        params.setSearchParams("");
        params.setStoreId(storeId);
        params.setClerkId(clerkId);
        params.setEnterpriseId(enterpriseId);
        ContactParamDTO contact = new ContactParamDTO();
        // 搜索信息
        MemberInfoListParamsDTO memberInfoListParamsDTO = com.gic.haoban.common.utils.StringUtil.getBean("{}", MemberInfoListParamsDTO.class);
        memberInfoListParamsDTO.setMemberId(memberId);
        contact.setContactType(0);
        params.setContactParamDTO(contact);
        ServiceResponse<ContactSumDTO> noContactResponse = customerApiService.contactMemberSum(new BasePageInfo(), params, memberInfoListParamsDTO);
        if (noContactResponse.isSuccess() && noContactResponse.getResult() != null) {
            if (noContactResponse.getResult().getTotalCount() > 0) {
                return true;
            }
        }
        contact.setContactType(1);
        params.setContactParamDTO(contact);
        ServiceResponse<ContactSumDTO> contactResponse = customerApiService.contactMemberSum(new BasePageInfo(), params, memberInfoListParamsDTO);
        if (contactResponse.isSuccess() && contactResponse.getResult() != null) {
            if (contactResponse.getResult().getTotalCount() > 0) {
                return true;
            }
        }
        return false;
    }


    @Override
    public TabContactLog saveContactLog(ContactLogQDTO qdto) throws BusinessException {
        logger.info("保存建联记录:{}", JSON.toJSONString(qdto));
        String enterpriseId = qdto.getEnterpriseId();
        String storeId = qdto.getStoreId();
        String clerkId = qdto.getClerkId();
        String memberId = qdto.getMemberId();
        Integer contactAutoType = qdto.getContactAutoType();
        DateTime date = DateUtil.date();
        MemberStoreClerkDTO memberStoreClerk = memberService.getMemberStoreClerk(memberId);
        if (memberStoreClerk == null) {
            logger.info("无专属导购无法建联");
            throw new BusinessException("-1", "无专属导购无法建联");
        }
        String mainClerkId = memberStoreClerk.getClerkId();
        if (!Objects.equals(mainClerkId, clerkId)) {
            logger.info("非专属导购无法建联");
            throw new BusinessException("-1", "非专属导购无法建联");
        }
        ClerkDTO clerkDTO = clerkService.getClerkByClerkId(clerkId);
        // 自动建联校验
        if (contactAutoType != null) {
            boolean contactCheck = contactCheck(enterpriseId, memberId, clerkDTO);
            logger.info("非潜客未建联或建联未转化:{}",contactCheck);
            if (!contactCheck) {
                throw new BusinessException("-1", "非潜客未建联或建联未转化，无法建联");
            }
        }
        // 是否周期内首次建联 同周期内是否有记录
        Integer contactCycle = 1;
        // 建联周期 14天内同周期/14天以上周期+1
        Integer contactCycleFirst = Constant.FLAG_TRUE;
        TabContactLog lastContactLog = contactLogMapper.queryLastLog(memberId, clerkId,null,null);
        if (lastContactLog != null) {
            Date contactTime = lastContactLog.getContactTime();
            Integer contactOrderLimitDay = getContactOrderLimitDay(contactTime);
            if (DateUtil.between(date, contactTime, DateUnit.SECOND) > contactOrderLimitDay * 24 * 60 * 60) {
                contactCycle = lastContactLog.getContactCycle() + 1;
            }else {
                contactCycle = lastContactLog.getContactCycle();
                contactCycleFirst = Constant.FLAG_FALSE;
            }
        }
        logger.info("建联周期:{},是否周期内首次:{}", contactCycle, contactCycleFirst);

        TabContactLog contactLog = new TabContactLog();
        contactLog.setClerkId(clerkId);
        contactLog.setStoreId(storeId);
        if (clerkDTO != null) {
            storeId = clerkDTO.getStoreId();
            contactLog.setClerkCode(clerkDTO.getClerkCode());
            contactLog.setClerkName(clerkDTO.getClerkName());
            contactLog.setStoreId(storeId);
        }
        if (StringUtils.isNotBlank(storeId)) {
            StoreDTO store = storeService.getStore(storeId);
            if (store != null) {
                contactLog.setStoreCode(store.getStoreCode());
            }
        }
        contactLog.setLogId(UniqueIdUtils.uniqueLong());
        contactLog.setMemberId(memberId);
        contactLog.setContactStatus(Constant.FLAG_TRUE);
        contactLog.setContactTime(date);
        contactLog.setContactCycle(contactCycle);
        contactLog.setContactCycleFirst(contactCycleFirst);
        // 成为潜客时间 无用暂不写
        contactLog.setPotentialTime(null);
        contactLog.setEnterpriseId(enterpriseId);
        contactLogMapper.insert(contactLog);
        // 刷新es建联时间
        Long clerkContactTime = Long.parseLong(DateUtil.format(date, DatePattern.PURE_DATETIME_PATTERN));
        refreshContactTime(enterpriseId, memberId, clerkContactTime);
        return contactLog;
    }

    /**
     * 历史数据超过14天建联未转化的按14天周期
     * @param contactTime
     * @return
     */
    private Integer getContactOrderLimitDay(Date contactTime) {
        Integer contactOrderLimitDay = Manage3Constants.CONTACT_ORDER_LIMIT_DAY;
        if (DateUtil.compare(Manage3Constants.CONTACT_FIX_RELEASE_DATE, contactTime) > 0 && DateUtil.between(Manage3Constants.CONTACT_FIX_RELEASE_DATE, contactTime, DateUnit.SECOND) > 14 * 24 * 60 * 60) {
            contactOrderLimitDay = 14;
        }
        logger.info("建联未转化计算天数:{}",contactOrderLimitDay);
        return contactOrderLimitDay;
    }

    @Override
    public void autoContactLog(ContactLogQDTO qdto) {
        if (qdto == null) {
            return;
        }
        boolean hasRight = enterpriseAdaptor.checkEnterpriseHasRight(qdto.getEnterpriseId(), EnterpriseServiceEnum.POTENTIAL.getRightMenuCode());
        if (!hasRight) {
            return ;
        }
        String enterpriseId = qdto.getEnterpriseId();
        Integer contactAutoType = qdto.getContactAutoType();
        ContactConfigDTO contactConfig = contactConfigService.getContactConfig(enterpriseId);
        if (contactConfig == null) {
            return;
        }
        List<Integer> contactAutoList = contactConfig.getContactAutoList();
        if (CollectionUtils.isEmpty(contactAutoList) || !contactAutoList.contains(contactAutoType)) {
            logger.info("无法自动建联:{},{}", contactAutoType, contactAutoList);
            return;
        }
        logger.info("自动建联:{}", JSON.toJSONString(qdto));
        try {
            TabContactLog contactLog = saveContactLog(qdto);
            // 写入自动建联跟进记录
            ContactFollowQDTO followQDTO = new ContactFollowQDTO();
            followQDTO.setMemberId(contactLog.getMemberId());
            followQDTO.setClerkId(contactLog.getClerkId());
            followQDTO.setClerkCode(contactLog.getClerkCode());
            followQDTO.setFollowType(ContactFollowTypeEnum.AUTO_CONTACT.getCode());
            followQDTO.setFollowRemark("因" + ContactAutoTypeEnum.fromCode(contactAutoType).getDescription() + ",系统自动标记了建联");
            followQDTO.setFollowTime(DateUtil.date());
            followQDTO.setEnterpriseId(enterpriseId);
            contactFollowService.saveFollow(followQDTO);
        } catch (BusinessException e) {
            logger.info("自动建联异常:{}", e.getMessage());
            return;
        }
    }

    @Override
    public void clearContactLog(String memberId,Integer clearType,String clerkId) {
        logger.info("清除建联状态:{},clearType:{},clerkId:{}", memberId, clearType,clerkId);
        TabContactLog lastContactLog = contactLogMapper.queryLastLog(memberId, null,null,null);
        if (lastContactLog == null) {
            return;
        }
        // clearType 1 消费清除 2 换绑主导购（不清除表建联状态）
        if (Objects.equals(clearType, 1)) {
            TabContactLog update = new TabContactLog();
            update.setLogId(lastContactLog.getLogId());
            update.setContactStatus(Constant.FLAG_FALSE);
            contactLogMapper.update(update);
        }else if (Objects.equals(clearType, 2)) {
            String lastClerkId = lastContactLog.getClerkId();
            if (Objects.equals(lastClerkId, clerkId)) {
                logger.info("最后一次建联和换绑导购一致则不清除建联");
                return;
            }
        }
        // 清除es建联时间 -1
        refreshContactTime(lastContactLog.getEnterpriseId(), memberId, -1L);
    }

    private void refreshContactTime(String enterpriseId,String memberId, Long contactTime) {
        DynamicDocDTO dynamicDocDTO = new DynamicDocDTO();
        dynamicDocDTO.setEnterpriseId(enterpriseId);
        dynamicDocDTO.setColumnCategoryCode("member");
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("id", memberId);
        jsonObject.put("memberId", memberId);
        jsonObject.put("clerkContactTime", contactTime);
        dynamicDocDTO.setDocJson(jsonObject);
        dynamicDocDTO.setRefresh(Constant.FLAG_TRUE);
        ESResponse res = esDataDynamicOperationApiService.updateDataSingle(dynamicDocDTO, false);
        logger.info("刷新建联时间返回:{}", res.getErrCode());
    }

    @Override
    public TabContactLog getClerkContactTime(String memberId) {
        TabContactLog lastContactLog = contactLogMapper.queryLastLog(memberId, null,null,null);
        if (lastContactLog == null) {
            return null;
        }
        Integer contactStatus = lastContactLog.getContactStatus();
        if (Objects.equals(contactStatus, Constant.FLAG_FALSE)) {
            return null;
        }
        String clerkId = lastContactLog.getClerkId();
        Date contactTime = lastContactLog.getContactTime();
        MemberStoreClerkDTO memberStoreClerk = memberService.getMemberStoreClerk(memberId);
        if (memberStoreClerk == null) {
            return null;
        }
        logger.info("建联导购id:{},专属导购id:{}", clerkId, memberStoreClerk.getClerkId());
        if (!Objects.equals(clerkId, memberStoreClerk.getClerkId())) {
            return null;
        }
        Integer contactOrderLimitDay = getContactOrderLimitDay(contactTime);
        if (DateUtil.compare(contactTime, DateUtil.date().offset(DateField.DAY_OF_MONTH, -contactOrderLimitDay)) < 0) {
            return null;
        }
        return lastContactLog;
    }

    @Override
    public TabContactLog getLastByTime(String memberId, Date beginTime,Date endTime) {
        return contactLogMapper.queryLastLog(memberId, null,beginTime,endTime);
    }
}
