package com.gic.haoban.manage.service.task;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.gic.binlog.base.entity.GicField;
import com.gic.binlog.base.entity.GicRecord;
import com.gic.binlog.base.entity.enums.GicRecordType;
import com.gic.commons.util.EntityUtil;
import com.gic.commons.util.GICMQClientUtil;
import com.gic.dubbo.entity.ProviderLocalTag;
import com.gic.haoban.manage.api.dto.FlushStoreMqDTO;
import com.gic.haoban.manage.api.enums.ChannelCodeEnum;
import com.gic.haoban.manage.api.service.WxEnterpriseRelatedApiService;
import com.gic.haoban.manage.api.service.content.task.QywxGroupMsgTaskApiService;
import com.gic.haoban.manage.service.pojo.BinlogBasePojo;
import com.gic.haoban.manage.service.pojo.ClerkSyncPojo;
import com.gic.haoban.manage.service.pojo.GroupSyncPojo;
import com.gic.haoban.manage.service.pojo.bo.content.binlog.MaterialMemberEOrderPojo;
import com.gic.haoban.manage.service.pojo.StoreSyncPojo;
import com.gic.haoban.manage.service.pojo.bo.content.binlog.MaterialMemberGicOrderPojo;
import com.gic.haoban.manage.service.pojo.bo.content.binlog.MaterialMemberUnionIdPoJo;
import com.gic.haoban.manage.service.pojo.bo.content.binlog.MemberOrderBo;
import com.gic.haoban.manage.service.service.StoreRangeService;
import com.gic.haoban.manage.service.service.content.InteractRecordService;
import com.gic.haoban.manage.service.service.content.PotentialCustomerService;
import com.gic.haoban.manage.service.service.hm.HmQrcodeService;
import org.apache.commons.lang3.StringUtils;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.listener.MessageListener;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * Created 2019/4/10.
 *
 * @author hua
 */
public class KafkaMessageServiceImpl implements MessageListener<String, GicRecord> {

    private final static Logger logger = LoggerFactory.getLogger(KafkaMessageServiceImpl.class);

    private final String STORE = "tab_gic_store";

    private final String CLERK = "tab_gic_clerk";

    private final String GROUP = "tab_gic_store_group";

    public static final String tab_gic_eorder = "tab_gic_eorder";
    public static final String tab_gic_order = "tab_gic_order";

    private final String tab_gic_member = "tab_gic_member";

    @Autowired
    private StoreRangeService storeRangeService;

    @Autowired
    private WxEnterpriseRelatedApiService wxEnterpriseRelatedApiService;

    @Autowired
    private HmQrcodeService hmQrcodeService;
    @Autowired
    PotentialCustomerService potentialCustomerService;
    @Autowired
    private InteractRecordService interactRecordService;

    @Override
    public void onMessage(ConsumerRecord<String, GicRecord> record) {
        ProviderLocalTag providerLocalTag = ProviderLocalTag.tag.get();
        providerLocalTag.traceId = UUID.randomUUID().toString();

        logger.info("message：{}", JSONObject.toJSONString(record.value()));
        if (record.value() == null) {
            logger.info("数据为空");
            return;
        }

        BinlogBasePojo pojo = binlogChange(record.value());
        logger.info("binlog数据接收：{}", JSONObject.toJSONString(pojo));
        if (pojo == null) {
            logger.error("binlog数据为空");
            return;
        }
        if (record.value().getTableName().equals(GROUP)) {
            //分组
            dealStoreGroup((GroupSyncPojo) pojo);
        }
        else if (record.value().getTableName().equals(STORE)) {
            //门店
            dealStore((StoreSyncPojo) pojo);
        }
        else if (record.value().getTableName().equals(CLERK)) {
           logger.info("导购binlog无需监听");
        }
        else if (StringUtils.startsWith(record.value().getTableName(), tab_gic_eorder)) {
            // 处理线上单微盟订单
            MemberOrderBo memberOrderBo = new MemberOrderBo();
            BeanUtils.copyProperties((MaterialMemberEOrderPojo)pojo, memberOrderBo);
            this.dealMemberOrder(memberOrderBo);
            // 处理会员订单新增事件
            dealMemberEOrder((MaterialMemberEOrderPojo) pojo);
        }
        else if (StringUtils.startsWith(record.value().getTableName(), tab_gic_order)) {

            MemberOrderBo memberOrderBo = new MemberOrderBo();
            BeanUtils.copyProperties((MaterialMemberGicOrderPojo)pojo, memberOrderBo);
            this.dealMemberOrder(memberOrderBo);
            // 处理会员订单新增事件
            dealMemberGicOrder((MaterialMemberGicOrderPojo) pojo);

        }else if (StringUtils.startsWith(record.value().getTableName(), tab_gic_member)) {
            // 会员unionId新增事件
            dealMemberUnionIdChange((MaterialMemberUnionIdPoJo) pojo);
        }
    }

    private BinlogBasePojo binlogChange(GicRecord record) {
        ClerkSyncPojo pojo = new ClerkSyncPojo();
        pojo.setRecordType(record.getRecordType().value());
        if (record.getTableName().equals(CLERK)) {
            return binlogMap(record.getFieldList(), record.getRecordType(), ClerkSyncPojo.class);
        } else if (record.getTableName().equals(STORE)) {
            return binlogMap(record.getFieldList(), record.getRecordType(), StoreSyncPojo.class);
        } else if (record.getTableName().equals(GROUP)) {
            return binlogMap(record.getFieldList(), record.getRecordType(), GroupSyncPojo.class);
        }else if (StringUtils.startsWith(record.getTableName(), tab_gic_eorder)) {
            if (GicRecordType.INSERT.equals(record.getRecordType())) {
                Map<String, String> mid = new HashMap<>();
                for (GicField gicField : record.getFieldList()) {
                    mid.put(gicField.getName(), gicField.getValue());
                }
                MaterialMemberEOrderPojo materialMemberEOrderPojo = JSON.parseObject(JSON.toJSONString(mid), MaterialMemberEOrderPojo.class);
                materialMemberEOrderPojo.setTableName(tab_gic_eorder);
                return materialMemberEOrderPojo;
            }
        }else if (StringUtils.startsWith(record.getTableName(), tab_gic_order)) {
            if (GicRecordType.INSERT.equals(record.getRecordType())) {
                Map<String, String> mid = new HashMap<>();
                for (GicField gicField : record.getFieldList()) {
                    mid.put(gicField.getName(), gicField.getValue());
                }
                MaterialMemberGicOrderPojo materialMemberGicOrderPojo = JSON.parseObject(JSON.toJSONString(mid), MaterialMemberGicOrderPojo.class);
                materialMemberGicOrderPojo.setTableName(tab_gic_order);
                return materialMemberGicOrderPojo;
            }
        } else if (StringUtils.startsWith(record.getTableName(), tab_gic_member)) {

            GicRecordType recordType = record.getRecordType();
            if (GicRecordType.INSERT.equals(recordType)) {
                Map<String, String> mid = new HashMap<>();
                for (GicField gicField : record.getFieldList()) {
                    mid.put(gicField.getName(), gicField.getValue());
                }
                return JSON.parseObject(JSON.toJSONString(mid), MaterialMemberUnionIdPoJo.class);
            }
            if (GicRecordType.UPDATE.equals(recordType)) {
                Map<String, String> old = new HashMap<>();
                Map<String, String> newMap = new HashMap<>();
                for (int i = 0; i < record.getFieldList().size(); i++) {
                    GicField gicField = record.getFieldList().get(i);
                    if (i % 2 == 0){
                        old.put(gicField.getName(), gicField.getValue());
                    }else {
                        newMap.put(gicField.getName(), gicField.getValue());
                    }
                }
                MaterialMemberUnionIdPoJo oldMember = JSON.parseObject(JSON.toJSONString(old), MaterialMemberUnionIdPoJo.class);
                MaterialMemberUnionIdPoJo newMemberInfo = JSON.parseObject(JSON.toJSONString(newMap), MaterialMemberUnionIdPoJo.class);
                if (oldMember == null || StringUtils.isNotBlank(oldMember.getUnionId())) {
                    logger.info("会员原本存在unionId， old:{}, new:{}", JSON.toJSONString(oldMember), JSON.toJSONString(newMemberInfo));
                    return null;
                }
                return newMemberInfo;
            }
            return null;
        }
        return null;
    }

    private BinlogBasePojo binlogMap(List<GicField> list, GicRecordType recordType, Class<? extends BinlogBasePojo> aclass) {
        Map<String, String> mid = new HashMap<>();
        for (GicField gicField : list) {
            if (gicField.getName().equals("status")
                    && recordType.equals(GicRecordType.UPDATE)
                    && !mid.containsKey("oldStatus")) {
                mid.put("oldStatus", gicField.getValue());
            } else if (gicField.getName().equals("store_group_id")
                    && recordType.equals(GicRecordType.UPDATE)
                    && !mid.containsKey("oldStoreGroupId")) {
                mid.put("oldStoreGroupId", gicField.getValue());
            } else if (gicField.getName().equals("store_name")
                    && recordType.equals(GicRecordType.UPDATE)
                    && !mid.containsKey("oldStoreName")) {
                mid.put("oldStoreName", gicField.getValue());
            } else {
                mid.put(gicField.getName(), gicField.getValue());
            }
        }
        BinlogBasePojo pojo = EntityUtil.changeEntityByJSON(aclass, mid);
        pojo.setRecordType(recordType.value());
        return pojo;

    }

    /**
     * 门店的处理
     *
     * @param syncPojo
     */
    private void dealStore(StoreSyncPojo syncPojo) {
        if (syncPojo == null) {
            logger.error("门店处理为空");
            return;
        }
        logger.info("门店binlog监听:{}", JSONObject.toJSONString(syncPojo));
        if (syncPojo.getRecordType() == GicRecordType.UPDATE.value()
                && (!syncPojo.getStoreName().equals(syncPojo.getOldStoreName()))) {
            logger.info("门店名称变更:{}", JSONObject.toJSONString(syncPojo));
            storeRangeService.updatwStoreName(syncPojo.getEnterpriseId(), syncPojo.getStoreId(), syncPojo.getStoreName());
            hmQrcodeService.updateStoreNameByStoreId(syncPojo.getEnterpriseId(), syncPojo.getStoreId(), syncPojo.getStoreName(),syncPojo.getStoreCode());
        }

        //门店状态变更 包括删除
        if (syncPojo.getRecordType() == GicRecordType.UPDATE.value()
                && (!syncPojo.getStatus().equals(syncPojo.getOldStatus()))) {
            logger.info("门店状态变更:{}", JSONObject.toJSONString(syncPojo));
            bindStoreToMq(syncPojo.getEnterpriseId());
            //新增门店
        } else if (syncPojo.getRecordType() == GicRecordType.INSERT.value()) {
            logger.info("新增门店:{}", JSONObject.toJSONString(syncPojo));
            bindStoreToMq(syncPojo.getEnterpriseId());
        } else if (!syncPojo.getStoreGroupId().equals(syncPojo.getOldStoreGroupId())) {
            logger.info("门店分组变更:{}", JSONObject.toJSONString(syncPojo));
            bindStoreToMq(syncPojo.getEnterpriseId());
        } else {
            logger.info("门店变更，无需操作同步：{}", JSONObject.toJSONString(syncPojo));
        }
    }

    private void bindStoreToMq(String enterrpriseId) {
        //放入延时队列刷新
        FlushStoreMqDTO mqDTO = new FlushStoreMqDTO();
        mqDTO.setEnterpriseId(enterrpriseId);
        mqDTO.setWxEnterpriseId("-1");
        mqDTO.setChannalCode(ChannelCodeEnum.STORE_CHANGE_UNBIND.getCode());
        mqDTO.setOptStaffId("-1");
        wxEnterpriseRelatedApiService.flushBindStoreToDelayMq(enterrpriseId, mqDTO);
    }

    /**
     * 门店分组的处理
     *
     * @param syncPojo
     */
    private void dealStoreGroup(GroupSyncPojo syncPojo) {
        logger.info("门店分组变更binlog监听:{}", JSONObject.toJSONString(syncPojo));
        if(null != syncPojo && (null == syncPojo.getOldStatus() || null == syncPojo.getStatus())) {
            return ;
        }
        //删除 同步绑定门店
        if (syncPojo!= null && syncPojo.getOldStatus() == 1 && syncPojo.getStatus() == 0) {
            logger.info("门店分组变更，同步绑定门店：{}", JSONObject.toJSONString(syncPojo));
            this.bindStoreToMq(syncPojo.getEnterpriseId());
        }
    }


    private void dealMemberEOrder(MaterialMemberEOrderPojo memberOrderPojo) {
        if (memberOrderPojo == null || memberOrderPojo.getOrderStatus() == null) {
            logger.info("会员订单状态异常");
            return;
        }
        if (memberOrderPojo.getOrderStatus() != 1) {
            logger.info("会员订单 非购买事件 {}", JSON.toJSONString(memberOrderPojo));
            return;
        }
        potentialCustomerService.updateMemberDealFlag(memberOrderPojo.getEnterpriseId(), memberOrderPojo.getMemberId());
    }

    private void dealMemberGicOrder(MaterialMemberGicOrderPojo memberOrderPojo) {
        if (memberOrderPojo == null || memberOrderPojo.getOrderStatus() == null) {
            logger.info("会员订单状态异常");
            return;
        }
        if (memberOrderPojo.getOrderStatus() != 1) {
            logger.info("会员订单 非购买事件 {}", JSON.toJSONString(memberOrderPojo));
            return;
        }
        potentialCustomerService.updateMemberDealFlag(memberOrderPojo.getEnterpriseId(), memberOrderPojo.getMemberId());
    }

    /**
     *
     * @param materialMemberUnionIdPoJo
     */
    private void dealMemberUnionIdChange(MaterialMemberUnionIdPoJo materialMemberUnionIdPoJo) {
        logger.info("处理会员unionId新增事件 >> {}", JSON.toJSONString(materialMemberUnionIdPoJo));
        if (StringUtils.isBlank(materialMemberUnionIdPoJo.getUnionId()) || StringUtils.equalsIgnoreCase("null", materialMemberUnionIdPoJo.getUnionId())) {
            logger.info("处理会员unionId事件异常,会员unionId为空 {}", JSON.toJSONString(materialMemberUnionIdPoJo));
            return;
        }
        interactRecordService.memberAuthorized(materialMemberUnionIdPoJo.getMemberId(), materialMemberUnionIdPoJo.getUnionId());
    }

    
    private void dealMemberOrder(MemberOrderBo memberOrderBo) {
        logger.info("销售线索处理会员订单数据 {}", JSON.toJSONString(memberOrderBo));
        if (!StringUtils.equalsIgnoreCase(memberOrderBo.getChannelCode(), MemberOrderBo.weimo)) {
            return;
        }
        if (memberOrderBo.getOrderStatus() == null || memberOrderBo.getOrderStatus() != 1) {
            logger.info("会员订单 非购买事件 {}", JSON.toJSONString(memberOrderBo));
            return;
        }
        try {
            logger.info("发送微盟订单处理消息 dealWeimoOrderForInteractRecord {}", JSON.toJSONString(memberOrderBo));
            /**
             * @see com.gic.haoban.manage.api.service.content.MallOrderStatusChangeApiService#dealWeimoOrder(String) 
             */
            GICMQClientUtil.getClientInstance().sendMessage("dealWeimoOrderForInteractRecord", JSON.toJSONString(memberOrderBo));
        }catch (Exception ex) {
            logger.info("处理会员订单异常 ", ex);
        }

        try {
            logger.info("发送微盟订单处理消息 recordMemberOrderForData");
            /**
             * @see QywxGroupMsgTaskApiService#recordMemberOrderForData(String)
             */
            GICMQClientUtil.getClientInstance().sendMessage("recordMemberOrderForData", JSON.toJSONString(memberOrderBo));
        }catch (Exception ex) {
            logger.info("处理会员订单异常 ", ex);
        }
    }
}
