package com.liquidnet.service.merchant.service.impl;

import com.liquidnet.common.exception.LiquidnetServiceException;
import com.liquidnet.commons.lang.util.CollectionUtil;
import com.liquidnet.service.base.ErrorMapping;
import com.liquidnet.service.base.PagedResult;
import com.liquidnet.service.base.SqlMapping;
import com.liquidnet.service.base.constant.MQConst;
import com.liquidnet.service.merchant.dto.param.MerchantSponsorEditParam;
import com.liquidnet.service.merchant.dto.vo.MerchantSponsorsVo;
import com.liquidnet.service.merchant.service.IMerchantSponsorsService;
import com.liquidnet.service.merchant.service.MerchantMongoService;
import com.liquidnet.service.merchant.service.MerchantRdmService;
import com.liquidnet.service.merchant.util.ObjectUtil;
import com.liquidnet.service.merchant.util.QueueUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Pattern;

@Slf4j
@Service
public class MerchantSponsorsServiceImpl implements IMerchantSponsorsService {

    @Autowired
    MerchantRdmService merchantRdmService;

    @Autowired
    MerchantMongoService merchantMongoService;

    @Autowired
    MongoTemplate mongoTemplate;

    @Autowired
    QueueUtil queueUtils;

    @Override
    public PagedResult<MerchantSponsorsVo> search(String name, int page, int size) {
        // 查询条件
        Query query = new Query();
        String regex = String.format("%s%s%s", "^.*", name, ".*$");
        Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
        query.addCriteria(Criteria.where("name").regex(pattern));
        query.addCriteria(Criteria.where("isOnline").is(1));

        // 总数
        long count = mongoTemplate.count(query, MerchantSponsorsVo.class, MerchantSponsorsVo.class.getSimpleName());

        // 分页
        PagedResult<MerchantSponsorsVo> pagedResult = ObjectUtil.getMerchantSponsorsVoPagedResult();
        if (count > 0) {
            query.fields()
                    .include("sponsorId")
                    .include("isOnline")
                    .include("uid")
                    .include("name")
                    .include("logo")
                    .include("background");

            // 查询分页
            Pageable pageable = PageRequest.of(page - 1, size, Sort.by(Sort.Direction.DESC, "createdAt"));
            query.with(pageable);
            List<MerchantSponsorsVo> sponsorsVoList = mongoTemplate.find(query, MerchantSponsorsVo.class, MerchantSponsorsVo.class.getSimpleName());

            pagedResult.setList(sponsorsVoList).setTotal(count, size);
        }

        return pagedResult;
    }

    @Override
    public MerchantSponsorsVo sponsorInfo(String uid, String sponsorId) {
        // 当前用户是否管理该主办
        MerchantSponsorsVo sponsorsVo = this.checkSponsorAccount(uid, sponsorId);

        return sponsorsVo;
    }

    @Override
    public void editBaseInfo(String uid, MerchantSponsorEditParam parameter) {
        // 当前用户是否管理该主办
        MerchantSponsorsVo sponsorsVo = this.checkSponsorAccount(uid, parameter.getSponsorId());

        LocalDateTime now = LocalDateTime.now();
        BeanUtils.copyProperties(parameter, sponsorsVo);
        sponsorsVo.setUpdatedAt(now);

        // 主办 redis
        long s = System.currentTimeMillis();
        merchantRdmService.setSponsorsVoBySponsorId(sponsorsVo.getSponsorId(), sponsorsVo);
        log.debug("#RDS耗时:{}ms", System.currentTimeMillis() - s);

        // 主办 mongo
        s = System.currentTimeMillis();
        merchantMongoService.setSponsorsVoBySponsorId(sponsorsVo.getSponsorId(), sponsorsVo);
        log.debug("#MONGO耗时:{}ms", System.currentTimeMillis() - s);

        LinkedList<String> toMqSqls = CollectionUtil.linkedListString();
        LinkedList<Object[]> sponsorUpdateObjs = CollectionUtil.linkedListObjectArr();
        // 主办 sql
        toMqSqls.add(SqlMapping.get("merchant_sponsors.update_base_info"));
        sponsorUpdateObjs.add(new Object[]{
                sponsorsVo.getName(), sponsorsVo.getLogo(), sponsorsVo.getBackground(), sponsorsVo.getDescription(),
                sponsorsVo.getContactEmail(),
                sponsorsVo.getUpdatedAt(), sponsorsVo.getSponsorId()
        });

        // mq
        s = System.currentTimeMillis();
        queueUtils.sendMsgByRedis(
                MQConst.MerchantQueue.SQL_MERCHANT_SPONSOR.getKey(),
                SqlMapping.gets(toMqSqls, sponsorUpdateObjs)
        );
        log.debug("#MQ耗时:{}ms", System.currentTimeMillis() - s);
    }

    private MerchantSponsorsVo checkSponsorAccount(String uid, String sponsorId) {
        // 当前用户是否管理该主办
        MerchantSponsorsVo sponsorsVo = merchantRdmService.getSponsorsVoBySponsorId(sponsorId);
        if (null == sponsorsVo || !uid.equals(sponsorsVo.getUid())) {
            ErrorMapping.ErrorMessage errorMessage = ErrorMapping.get("13201");
            throw new LiquidnetServiceException(errorMessage.getCode(), errorMessage.getMessage());
        }
        return sponsorsVo;
    }
}
