package com.liquidnet.client.admin.zhengzai.goblin.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.liquidnet.client.admin.zhengzai.goblin.service.IGoblinArtistAuthAdminService;
import com.liquidnet.service.goblin.constant.GoblinArtistConst;
import com.liquidnet.service.goblin.dto.vo.GoblinArtistAuthApplyVo;
import com.liquidnet.service.goblin.entity.GoblinArtistAuthApply;
import com.liquidnet.service.goblin.mapper.GoblinArtistAuthApplyMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
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.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class GoblinArtistAuthAdminServiceImpl
        extends ServiceImpl<GoblinArtistAuthApplyMapper, GoblinArtistAuthApply>
        implements IGoblinArtistAuthAdminService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Override
    @Transactional
    public boolean approve(String applyId, LocalDateTime expireAt, String remark,
                           String reviewerId, String reviewerName) {
        LocalDateTime now = LocalDateTime.now();

        LambdaUpdateWrapper<GoblinArtistAuthApply> applyWrapper = Wrappers.lambdaUpdate(GoblinArtistAuthApply.class);
        applyWrapper.eq(GoblinArtistAuthApply::getApplyId, applyId);
        applyWrapper.set(GoblinArtistAuthApply::getStatus, GoblinArtistConst.APPLY_APPROVED);
        applyWrapper.set(GoblinArtistAuthApply::getReviewerId, reviewerId);
        applyWrapper.set(GoblinArtistAuthApply::getReviewerName, reviewerName);
        applyWrapper.set(GoblinArtistAuthApply::getReviewTime, now);
        applyWrapper.set(GoblinArtistAuthApply::getReviewRemark, remark);
        applyWrapper.set(GoblinArtistAuthApply::getAuthExpireAt, expireAt);
        applyWrapper.set(GoblinArtistAuthApply::getUpdatedAt, now);
        if (!this.update(applyWrapper)) {
            return false;
        }

        syncMongoApprove(applyId, expireAt, reviewerId, reviewerName, remark, now);
        return true;
    }

    @Override
    @Transactional
    public boolean reject(String applyId, String reason, String reviewerId, String reviewerName) {
        LocalDateTime now = LocalDateTime.now();

        LambdaUpdateWrapper<GoblinArtistAuthApply> applyWrapper = Wrappers.lambdaUpdate(GoblinArtistAuthApply.class);
        applyWrapper.eq(GoblinArtistAuthApply::getApplyId, applyId);
        applyWrapper.set(GoblinArtistAuthApply::getStatus, GoblinArtistConst.APPLY_REJECTED);
        applyWrapper.set(GoblinArtistAuthApply::getReviewerId, reviewerId);
        applyWrapper.set(GoblinArtistAuthApply::getReviewerName, reviewerName);
        applyWrapper.set(GoblinArtistAuthApply::getReviewTime, now);
        applyWrapper.set(GoblinArtistAuthApply::getRejectReason, reason);
        applyWrapper.set(GoblinArtistAuthApply::getUpdatedAt, now);
        if (!this.update(applyWrapper)) {
            return false;
        }

        syncMongoReject(applyId, reason, reviewerId, reviewerName, now);
        return true;
    }

    @Override
    public List<Map<String, Object>> authList(int pageNum, int pageSize) {
        List<Map<String, Object>> result = new ArrayList<>();
        return result;
    }

    private void syncMongoApprove(String applyId, LocalDateTime expireAt,
                                  String reviewerId, String reviewerName,
                                  String remark, LocalDateTime now) {
        Query query = Query.query(Criteria.where("applyId").is(applyId));
        Update update = Update.update("status", GoblinArtistConst.APPLY_APPROVED)
                .set("reviewerId", reviewerId)
                .set("reviewerName", reviewerName)
                .set("reviewTime", now)
                .set("reviewRemark", remark)
                .set("authExpireAt", expireAt)
                .set("updatedAt", now);
        mongoTemplate.updateFirst(query, update, GoblinArtistAuthApplyVo.class.getSimpleName());
    }

    private void syncMongoReject(String applyId, String reason,
                                 String reviewerId, String reviewerName, LocalDateTime now) {
        Query query = Query.query(Criteria.where("applyId").is(applyId));
        Update update = Update.update("status", GoblinArtistConst.APPLY_REJECTED)
                .set("reviewerId", reviewerId)
                .set("reviewerName", reviewerName)
                .set("reviewTime", now)
                .set("rejectReason", reason)
                .set("updatedAt", now);
        mongoTemplate.updateFirst(query, update, GoblinArtistAuthApplyVo.class.getSimpleName());
    }
}
