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

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

import org.apache.commons.collections.CollectionUtils;
import org.apache.logging.log4j.LogManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.gic.api.base.commons.BasePageInfo;
import com.gic.api.base.commons.Page;
import com.gic.commons.util.EntityUtil;
import com.gic.commons.util.PageHelperUtils;
import com.gic.commons.util.ToolUtil;
import com.gic.commons.util.UniqueIdUtils;
import com.gic.haoban.manage.api.dto.hm.HmLinkChatDTO;
import com.gic.haoban.manage.api.dto.hm.HmLinkDTO;
import com.gic.haoban.manage.api.dto.hm.HmLinkStoreDTO;
import com.gic.haoban.manage.api.dto.qdto.hm.HmLinkSearchQDTO;
import com.gic.haoban.manage.api.enums.hm.HmLinkTypeEnum;
import com.gic.haoban.manage.api.enums.hm.HmWelcomeReferType;
import com.gic.haoban.manage.service.dao.mapper.hm.HmLinkMapper;
import com.gic.haoban.manage.service.entity.hm.TabHmLink;
import com.gic.haoban.manage.service.pojo.bo.hm.HmLinkBO;
import com.gic.haoban.manage.service.pojo.bo.hm.HmWelcomeRelationBO;
import com.gic.haoban.manage.service.service.chat.GroupChatHmService;
import com.gic.haoban.manage.service.service.hm.HmLinkChatService;
import com.gic.haoban.manage.service.service.hm.HmLinkService;
import com.gic.haoban.manage.service.service.hm.HmLinkStoreService;
import com.gic.haoban.manage.service.service.hm.WelcomeRelationService;
import com.gic.redis.data.util.RedisUtil;
import com.github.pagehelper.PageHelper;

@Service("hmLikService")
public class HmLinkServiceImpl implements HmLinkService {

    private static org.apache.logging.log4j.Logger log = LogManager.getLogger(HmLinkService.class);

    public static String[] PADDING = new String[] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C",
            "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X",
            "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s",
            "t", "u", "v", "w", "x", "y", "z" };

    @Autowired
    private HmLinkMapper linkMapper;
    @Autowired
    private HmLinkStoreService hmLinkStoreService;
    @Autowired
    private WelcomeRelationService welcomeRelationService;
    @Autowired
    private HmLinkChatService hmLinkChatService;
    @Autowired
    private GroupChatHmService groupChatHmService;

    @Override
    public HmLinkBO getByLinkId(String wxEnterpriseId, String enterprieId, Long linkId) {
        TabHmLink link = this.linkMapper.selectById(linkId);
        if (null == link) {
            return null;
        }
        HmLinkBO bo = EntityUtil.changeEntityByJSON(HmLinkBO.class, link);
        return bo;
    }

    @Override
    public HmLinkBO getByLinkShortCode(String shortCode) {
        TabHmLink link = this.linkMapper.selectByShortCode(shortCode);
        if (null == link) {
            return null;
        }
        HmLinkBO bo = EntityUtil.changeEntityByJSON(HmLinkBO.class, link);
        return bo;
    }

    @Override
    public HmLinkBO getByLinkShortCodeCache(String shortCode) {
        String key = "hm:link:" + shortCode;
        HmLinkBO link = RedisUtil.getCache(key, HmLinkBO.class);
        if (link == null) {
            link = this.getByLinkShortCode(shortCode);
            if (link != null) {
                RedisUtil.setCache(key, link, 20 * 60L);
            }
        }
        return link;
    }

    @Override
    public HmLinkBO getByLinkIdFormCache(String wxEnterpriseId, String enterprieId, Long linkId) {
        String key = "hm:link:" + linkId;
        HmLinkBO link = RedisUtil.getCache(key, HmLinkBO.class);
        if (link == null) {
            link = this.getByLinkId(wxEnterpriseId, enterprieId, linkId);
            if (link != null) {
                RedisUtil.setCache(key, link, 20 * 60L);
            }
        }
        return link;
    }

    private void delCache(Long linkId, String shortCode) {
        String key1 = "hm:link:" + shortCode;
        RedisUtil.delCache(key1);
        String key2 = "hm:link:" + linkId;
        RedisUtil.delCache(key2);
    }

    @Override
    public List<HmLinkBO> listForSms(String wxEnterpriseId, String enterpriseId, String linkName, Integer linkType,
            List<String> creatorIdList) {
        List<TabHmLink> list = this.linkMapper.listForSms(wxEnterpriseId, enterpriseId, linkName, linkType,
                creatorIdList);
        return EntityUtil.changeEntityListByJSON(HmLinkBO.class, list);
    }

    @Override
    @Transactional
    public String saveLink(HmLinkDTO dto, List<HmLinkStoreDTO> storeList) {
        // 新增
        Long linkId = dto.getLinkId();
        String oldWelcomeId = null;
        TabHmLink oldLink = null;
        if (null == linkId) {
            linkId = UniqueIdUtils.uniqueLong();
            StringBuilder sb = new StringBuilder("LJ");
            if (dto.getLinkType() < HmLinkTypeEnum.CHAT_HM_LINK_TYPE.getLinkType()) {
                sb.append("0");
            }
            sb.append(dto.getLinkType()).append(linkId);
            dto.setLinkId(linkId);
            dto.setLinkCode(sb.toString());
            String shortCode = this.shortCode(dto.getEnterpriseId());
            dto.setShortCode(shortCode);
            dto.setStatusFlag(1);
            TabHmLink entity = EntityUtil.changeEntityByJSON(TabHmLink.class, dto);
            this.linkMapper.insert(entity);
        } else {
            oldLink = this.linkMapper.selectById(linkId);
            this.delCache(oldLink.getLinkId(), oldLink.getShortCode());
            oldWelcomeId = oldLink.getWelcomeId();
            TabHmLink entity = EntityUtil.changeEntityByJSON(TabHmLink.class, dto);

            this.linkMapper.update(entity);
        }
        // 单人活码
        if (dto.getLinkType() == HmLinkTypeEnum.HM_LINK_TYPE_1.getLinkType()
                || dto.getLinkType() == HmLinkTypeEnum.HM_LINK_TYPE_2.getLinkType()) {
            if (CollectionUtils.isNotEmpty(storeList)) {
                storeList.forEach(item -> {
                    item.setWxEnterpriseId(dto.getWxEnterpriseId());
                    item.setEnterpriseId(dto.getEnterpriseId());
                });
            }
            String newWelcomeId = dto.getWelcomeId();
            this.saveWelcomeRelation(oldWelcomeId, newWelcomeId, dto);
            this.hmLinkStoreService.saveStore(linkId, storeList);
        }
        // 群活码
        if (dto.getLinkType() == HmLinkTypeEnum.CHAT_HM_LINK_TYPE.getLinkType()) {
            int index = 0;
            for (HmLinkChatDTO item : dto.getLinkChatList()) {
                item.setWxEnterpriseId(dto.getWxEnterpriseId());
                item.setEnterpriseId(dto.getEnterpriseId());
                item.setSortNum(index++);
            }
            this.hmLinkChatService.save(linkId, dto.getLinkChatList() , dto.getOtherChatHmId() , oldLink);
        }
        return dto.getLinkCode();
    }

    private void saveWelcomeRelation(String oldWelcomeId, String newWelcomeId, HmLinkDTO dto) {
        // 如果一样就返回
        if ((null == oldWelcomeId && null == newWelcomeId)
                || (null != oldWelcomeId && null != newWelcomeId && oldWelcomeId.equals(newWelcomeId))) {
            return;
        }
        HmWelcomeRelationBO welcome = new HmWelcomeRelationBO();
        welcome.setWxEnterpriseId(dto.getWxEnterpriseId());
        welcome.setEnterpriseId(dto.getEnterpriseId());
        welcome.setReferName(dto.getName());
        welcome.setRelationId(dto.getLinkId());
        welcome.setReferId(dto.getLinkId() + "");
        welcome.setReferCode(dto.getLinkCode());
        welcome.setType(HmWelcomeReferType.LINK.getCode());
        // 新增
        if (!(null != oldWelcomeId && newWelcomeId == null)) {
            welcome.setWelcomeId(newWelcomeId);
        }
        this.welcomeRelationService.updateWelcomeRelation(welcome);
    }

    @Override
    public Page<HmLinkBO> queryPageRelationList(Long pageId, String enterpriseId, String searchText,
            BasePageInfo basePageInfo) {
        PageHelper.startPage(basePageInfo);
        List<TabHmLink> list = this.linkMapper.queryPageRelationList(pageId, enterpriseId, searchText);
        Page<HmLinkBO> retPage = PageHelperUtils.changePageHelperToCurrentPage(list, HmLinkBO.class);
        return retPage;
    }

    public String shortCode(String enterpriseId) {
        StringBuilder sb = new StringBuilder();
        String uuid = ToolUtil.randomUUID();
        int length = 5;
        int totalLength = 62;
        int interval = (int) (uuid.length() / length);
        String str;
        for (int i = 0; i < length; i++) {
            if (i == length - 1) {
                str = uuid.substring(length * interval);
            } else {
                str = uuid.substring(i * interval, i * interval + interval);
            }
            int x = Integer.parseInt(str, 16);
            sb.append(PADDING[x % totalLength]);
        }
        sb.append(PADDING[(int) (Math.random() * totalLength)]);
        String code = sb.toString();
        TabHmLink link = this.linkMapper.selectByShortCode(code);
        if (null == link) {
            return code;
        }
        log.info("code重复={}", code);
        return shortCode(enterpriseId);
    }

}
