package cn.quantgroup.xyqb.service.user.impl;

import cn.quantgroup.user.enums.BizType;
import cn.quantgroup.user.enums.Relation;
import cn.quantgroup.xyqb.entity.Contact;
import cn.quantgroup.xyqb.repository.IContactRepository;
import cn.quantgroup.xyqb.service.user.IContactService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.sql.Timestamp;
import java.util.List;
import java.util.Objects;

/**
 * Created by Miraculous on 2017/1/3.
 */
@Slf4j
@Service
public class ContactServiceImpl implements IContactService {
    @Autowired
    private IContactRepository contactRepository;

    public List<Contact> findByUserIdAndBizType(Long userId, BizType bizType, boolean trim) {
        List<Contact> contacts = contactRepository.findByUserIdAndBizType(userId, bizType);
        if (trim) {
            trim(contacts);
        }
        return contacts;
    }

    /**
     * 过滤掉非法联系人记录
     *
     * @param contacts - 包含待清除记录的联系人列表
     */
    private void trim(List<Contact> contacts) {
        if (CollectionUtils.isEmpty(contacts)) {
            return;
        }
        contacts.removeIf(contact -> !contact.valid());
    }

    @Override
    public Contact findById(Long id) {
        return contactRepository.findOne(id);
    }

    @Override
    @Caching(evict = {
            @CacheEvict(value = "contact", key = "'contact:true' + #userId", cacheManager = "cacheManager"),
            @CacheEvict(value = "contact", key = "'contact:false' + #userId", cacheManager = "cacheManager")})
    public List<Contact> save(Long userId, List<Contact> contacts) {
        if (userId == null) {
            return null;
        }
        // 合并当前用户列表到更新列表
        mergeContacts(userId, contacts);
        return contactRepository.save(contacts);
    }

    @Override
    @Caching(evict = {
            @CacheEvict(value = "contact", key = "'contact:true' + #contact.userId", cacheManager = "cacheManager"),
            @CacheEvict(value = "contact", key = "'contact:false' + #contact.userId", cacheManager = "cacheManager")})
    public Contact save(Contact contact) {
        return contactRepository.save(contact);
    }

    @Override
    public Contact saveContact(String name, String phoneNo, Relation relation, Contact contact) {
        if (StringUtils.isNotBlank(name)) {
            contact.setName(name);
        }
        if (StringUtils.isNotBlank(phoneNo)) {
            contact.setPhoneNo(phoneNo);
        }
        if (null != relation) {
            contact.setRelation(relation);
        }
        log.info("修改前联系人信息:{}", contact);
        contact = save(contact);
        return contact;
    }

    @Override
    public void update(String name, String phoneNo, Relation relation, Long id) {
        contactRepository.update(name, phoneNo, relation.ordinal(), id);
    }

    @Override
    public void save(List<Contact> contactList) {
        contactRepository.save(contactList);
    }

    @Override
    public List<Contact> findContactForUserId(Long userId) {
        return contactRepository.findContactForUserId(userId);
    }

    /**
     * 合并当前用户列表到更新列表
     *
     * @param userId   - 用户主键
     * @param contacts - 新联系人列表
     */
    private void mergeContacts(Long userId, List<Contact> contacts) {
        // 当前联系人列表
        List<Contact> userContact = contactRepository.findByUserId(userId);
        for (int i = 0; i < contacts.size(); i++) {
            Contact c = contacts.get(i);
            c.setId(null);
            c.setUserId(userId);
            if(Objects.isNull(c.getRelation())){
                c.setRelation(Relation.OTHER);
            }
            if (CollectionUtils.isEmpty(userContact) || userContact.size() <= i) {
                continue;
            }
            Contact old = userContact.get(i);
            if(Objects.isNull(old)){
                continue;
            }
            c.setId(old.getId());
            if(Objects.nonNull(old.getCreatedAt())){
                c.setCreatedAt(old.getCreatedAt());
            }
        }
    }
}
