package com.liquidnet.service.adam.service.impl;

import com.github.pagehelper.PageInfo;
import com.liquidnet.common.mq.constant.MQConst;
import com.liquidnet.service.adam.dto.vo.AdamCollectBaseVo;
import com.liquidnet.service.adam.dto.vo.AdamCollectInfoVo;
import com.liquidnet.service.adam.dto.vo.AdamCollectVo;
import com.liquidnet.service.adam.service.IAdamCollectionService;
import com.liquidnet.service.adam.service.AdamRdmService;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.base.SqlMapping;
import com.liquidnet.service.feign.kylin.api.FeignKylinPerformanceClient;
import com.liquidnet.service.kylin.dto.vo.mongo.KylinPerformanceVo;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;
import lombok.extern.slf4j.Slf4j;
import org.bson.Document;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
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 org.springframework.util.CollectionUtils;

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

/**
 * <p>
 * 收藏 服务实现类
 * </p>
 *
 * @author liquidnet
 * @since 2021-05-10
 */
@Slf4j
@Service
public class AdamCollectionServiceImpl implements IAdamCollectionService {
    @Autowired
    MongoTemplate mongoTemplate;
    @Autowired
    RabbitTemplate rabbitTemplate;
    @Autowired
    AdamRdmService adamRdmService;

    /* ---------------- 外部服务API ---------------- */
    @Autowired
    FeignKylinPerformanceClient feignKylinPerformanceClient;

    @Override
    public void add(AdamCollectBaseVo vo) {
        LocalDateTime now = LocalDateTime.now();

        vo.setState(1);
        vo.setCreatedAt(now);

        mongoTemplate.insert(vo, AdamCollectBaseVo.class.getSimpleName());

        rabbitTemplate.convertAndSend(MQConst.EX_LNS_SQL_UCENTER, MQConst.RK_SQL_UCENTER,
                SqlMapping.get("adam_collection.add",
                        vo.getUid(), vo.getContentId(), vo.getType(), vo.getState(), now
                )
        );
    }

    @Override
    public boolean exists(String uid, String type, String contentId) {
        return mongoTemplate.exists(
                Query.query(Criteria.where("uid").is(uid).and("contentId").is(contentId).and("type").is(type).and("state").is(1)),
                AdamCollectBaseVo.class.getSimpleName()
        );
    }

    @Override
    public void del(String uid, String type, String... contentIds) {
        LocalDateTime now = LocalDateTime.now();

        DeleteResult deleteResult = mongoTemplate.remove(
                Query.query(Criteria.where("uid").is(uid).and("type").is(type).and("contentId").in(contentIds)),
                AdamCollectBaseVo.class.getSimpleName()
        );
        if (deleteResult.getDeletedCount() > 0) {
            LinkedList<Object[]> toMqObjs = new LinkedList<>();
            for (String c : contentIds) {
                toMqObjs.add(new Object[]{now, uid, c});
            }
            rabbitTemplate.convertAndSend(MQConst.EX_LNS_SQL_UCENTER, MQConst.RK_SQL_UCENTER,
                    SqlMapping.get("adam_collection.del", toMqObjs));
        }
    }

    @Override
    public boolean queryState(String uid, String type, String contentId) {
        return mongoTemplate.exists(
                Query.query(Criteria.where("uid").is(uid).and("contentId").is(contentId).and("type").is(type).and("state").is(1)),
                AdamCollectBaseVo.class.getSimpleName()
        );
    }

    @Override
    public PageInfo<AdamCollectVo> queryPage(String uid, String type, int pageNo, int pageSize) {
        Query query = Query.query(Criteria.where("uid").is(uid).and("type").is(type).and("state").is(1));

        long s = System.currentTimeMillis();
        long count = mongoTemplate.count(query, AdamCollectBaseVo.class.getSimpleName());
        log.debug("#MDB耗时:{}ms", System.currentTimeMillis() - s);

        PageInfo<AdamCollectVo> voPageInfo = null;
        if (count > 0) {
            Pageable pageable = PageRequest.of(pageNo - 1, pageSize, Sort.by(Sort.Direction.DESC, "createdAt"));

            query.with(pageable);

            s = System.currentTimeMillis();
            List<AdamCollectVo> collectVoList = mongoTemplate.find(query, AdamCollectVo.class, AdamCollectBaseVo.class.getSimpleName());
            log.debug("#MDB耗时:{}ms", System.currentTimeMillis() - s);

            if (!CollectionUtils.isEmpty(collectVoList)) {
//                try {
//                    String[] contentIds = collectVoList.stream().map(AdamCollectVo::getContentId).toArray(a -> new String[collectVoList.size()]);
//
//                    ResponseDto<List<KylinPerformanceVo>> performanceVoListDto = feignKylinPerformanceClient.performanceList(contentIds);
//
//                    if (performanceVoListDto.isSuccess()) {
//                        List<KylinPerformanceVo> kylinPerformanceVoList = performanceVoListDto.getData();
//
//                        collectVoList.forEach(v -> {
//                            kylinPerformanceVoList.forEach(vl -> {
//                                if (vl.getPerformancesId().equals(v.getContentId())) {
//                                    AdamCollectInfoVo collectInfoVo = AdamCollectInfoVo.getNew();
//                                    BeanUtils.copyProperties(vl, collectInfoVo);
//                                    v.setContentInfo(collectInfoVo);
//                                }
//                            });
//                        });
//                    } else {
//                        log.info("Failed:{}.API.performanceList(...) for AdamCollection:{}", feignKylinPerformanceClient.getClass().getSimpleName(), performanceVoListDto.toJson());
//                    }
//                } catch (Exception e) {
//                    log.error("Exception:{}.API.performanceList(...) for AdamCollection", feignKylinPerformanceClient.getClass().getSimpleName(), e);
//                }
                s = System.currentTimeMillis();
                collectVoList.forEach(r -> {
                    AdamCollectInfoVo vo = AdamCollectInfoVo.getNew();
                    KylinPerformanceVo performanceVo = adamRdmService.kylinPerformanceVo(r.getContentId());
                    if (null != performanceVo) {
//                        BeanUtils.copyProperties(performanceVo, vo);
                        vo.setPerformancesId(performanceVo.getPerformancesId());
                        vo.setTitle(performanceVo.getTitle());
                        vo.setImgPoster(performanceVo.getImgPoster());
                        vo.setType(performanceVo.getType());
                        vo.setTimeStart(performanceVo.getTimeStart());
                        vo.setPrice(performanceVo.getPrice());
                        vo.setCityName(performanceVo.getCityName());
                        vo.setFieldName(performanceVo.getFieldName());
                        vo.setIsMember(performanceVo.getIsMember());
                        vo.setIsExclusive(performanceVo.getIsExclusive());
                        vo.setIsDiscount(performanceVo.getIsDiscount());
                        vo.setIsAdvance(performanceVo.getIsAdvance());
                    }
                    r.setContentInfo(vo);
                });
                log.debug("#COL.RDS.K耗时:{}ms", System.currentTimeMillis() - s);
            }

            voPageInfo = PageInfo.of(collectVoList);
            voPageInfo.setTotal(count);
        } else {
            voPageInfo = new PageInfo<>();
        }

        return voPageInfo;
    }
}
