package com.liquidnet.service.platform.service.impl.partner;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.liquidnet.commons.lang.util.IDGenerator;
import com.liquidnet.commons.lang.util.JsonUtils;
import com.liquidnet.service.base.ErrorMapping;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.base.UserPathDto;
import com.liquidnet.service.kylin.dto.param.CreateTicketTimesParam;
import com.liquidnet.service.kylin.dto.vo.partner.KylinTicketPartnerVo;
import com.liquidnet.service.kylin.dto.vo.partner.KylinTicketTimesPartnerVo;
import com.liquidnet.service.kylin.entity.KylinPerformanceStatus;
import com.liquidnet.service.kylin.entity.KylinTicketTimeRelation;
import com.liquidnet.service.kylin.entity.KylinTicketTimes;
import com.liquidnet.service.kylin.mapper.KylinPerformanceStatusMapper;
import com.liquidnet.service.kylin.mapper.KylinTicketTimeRelationMapper;
import com.liquidnet.service.kylin.mapper.KylinTicketTimesMapper;
import com.liquidnet.service.kylin.service.partner.IKylinTicketTimesPartnerService;
import com.liquidnet.service.platform.utils.ObjectUtil;
import com.mongodb.BasicDBObject;
import com.mongodb.client.model.FindOneAndUpdateOptions;
import com.mongodb.client.model.ReturnDocument;
import lombok.extern.slf4j.Slf4j;
import org.bson.Document;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.convert.MongoConverter;
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.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;

/**
 * <p>
 * 场次 服务实现类
 * </p>
 *
 * @author liquidnet
 * @since 2021-05-06
 */
@Service
@Slf4j
public class KylinTicketTimesPartnerServiceImpl extends ServiceImpl<KylinTicketTimesMapper, KylinTicketTimes> implements IKylinTicketTimesPartnerService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private MongoConverter mongoConverter;

    @Autowired
    private KylinTicketTimeRelationMapper ticketTimeRelationMapper;

    @Autowired
    private KylinPerformanceStatusMapper performanceStatusMapper;

    @Override
    public ResponseDto<KylinTicketTimesPartnerVo> createTimesSummary(CreateTicketTimesParam createTicketTimesParam) {
        ResponseDto<KylinTicketTimesPartnerVo> ticketTimesPartnerVo = null;
        //获取演出状态
        KylinPerformanceStatus performanceStatus = performanceStatusMapper.selectOne(
                Wrappers.lambdaQuery(KylinPerformanceStatus.class).eq(KylinPerformanceStatus::getPerformanceId, createTicketTimesParam.getPerformancesId()));
        if (null == performanceStatus) {
            ticketTimesPartnerVo = createTimes(createTicketTimesParam);
            log.info(UserPathDto.setPartnerData("0","createTimes", createTicketTimesParam,ticketTimesPartnerVo));
        } else if(performanceStatus.getAuditStatus()==0){
            return ResponseDto.failure(ErrorMapping.get(20101));
        }else if (performanceStatus.getStatus() >= 3 && performanceStatus.getStatus() != 4) {//未被拒绝 且 通过审核的演出
            ticketTimesPartnerVo = addNewTimes(createTicketTimesParam);
            log.info(UserPathDto.setPartnerData("0","addNewTimes", createTicketTimesParam,ticketTimesPartnerVo));
        } else {
            ticketTimesPartnerVo = createTimes(createTicketTimesParam);
            log.info(UserPathDto.setPartnerData("0","createTimes", createTicketTimesParam,ticketTimesPartnerVo));
        }
        return ticketTimesPartnerVo;
    }

    @Override
    public ResponseDto<KylinTicketTimesPartnerVo> createTimes(CreateTicketTimesParam createTicketTimesParam) {
        try {
            // 获取 主键id
            String ticketTimesId = IDGenerator.nextSnowId();
            // 获取 当前时间 -> 创建时间
            LocalDateTime createdAt = LocalDateTime.now();
            // 标题
            String title = "";
            String useStart;
            String useEnd;
            if (createTicketTimesParam.getType() == 1) {
                useStart = createTicketTimesParam.getUseStart().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
                useEnd = createTicketTimesParam.getUseStart().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
                title = useStart;
            } else {
                useStart = createTicketTimesParam.getUseStart().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
                useEnd = createTicketTimesParam.getUseEnd().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
                title = useStart + "-" + useEnd;
            }
            // mongo 操作
            KylinTicketTimesPartnerVo kylinTicketTimesPartnerVo = KylinTicketTimesPartnerVo.getNew();
            kylinTicketTimesPartnerVo.setTicketTimesId(ticketTimesId);
            kylinTicketTimesPartnerVo.setUseStart(createTicketTimesParam.getUseStart().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            if(createTicketTimesParam.getType() == 2) {
                kylinTicketTimesPartnerVo.setUseEnd(createTicketTimesParam.getUseEnd().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            }else{
                kylinTicketTimesPartnerVo.setUseEnd(createTicketTimesParam.getUseStart().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            }
            kylinTicketTimesPartnerVo.setStatus(1);
            kylinTicketTimesPartnerVo.setTitle(title);
            kylinTicketTimesPartnerVo.setPerformancesId(createTicketTimesParam.getPerformancesId());
            kylinTicketTimesPartnerVo.setType(createTicketTimesParam.getType());
            kylinTicketTimesPartnerVo.setCreatedAt(createdAt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            mongoTemplate.insert(
                    kylinTicketTimesPartnerVo, KylinTicketTimesPartnerVo.class.getSimpleName()
            );

            return ResponseDto.success(kylinTicketTimesPartnerVo);
        } catch (Exception e) {
            return ResponseDto.failure(ErrorMapping.get(20105));
        }
    }

    @Override
    public ResponseDto<KylinTicketTimesPartnerVo> addNewTimes(CreateTicketTimesParam createTicketTimesParam) {
        try {
            // 获取 主键id
            String ticketTimesId = IDGenerator.nextSnowId().toString();
            // 获取 当前时间 -> 创建时间
            LocalDateTime createdAt = LocalDateTime.now();
            // 标题
            String title = "";
            String useStart = createTicketTimesParam.getUseStart().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
            String useEnd = createTicketTimesParam.getUseEnd().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
            if (createTicketTimesParam.getType() == 1) {
                if(!useStart.split(" ")[0].equals(useEnd.split(" ")[0])){
                    return ResponseDto.failure(ErrorMapping.get(20118));
                }
                title = useStart;
            } else {
                title = useStart + "-" + useEnd;
            }

            // mongo 操作
            KylinTicketTimesPartnerVo kylinTicketTimesPartnerVo = KylinTicketTimesPartnerVo.getNew();
            kylinTicketTimesPartnerVo.setTicketTimesId(ticketTimesId);
            kylinTicketTimesPartnerVo.setUseStart(createTicketTimesParam.getUseStart().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            kylinTicketTimesPartnerVo.setUseEnd(createTicketTimesParam.getUseEnd().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            kylinTicketTimesPartnerVo.setStatus(-1);
            kylinTicketTimesPartnerVo.setTitle(title);
            kylinTicketTimesPartnerVo.setPerformancesId(createTicketTimesParam.getPerformancesId());
            kylinTicketTimesPartnerVo.setType(createTicketTimesParam.getType());
            kylinTicketTimesPartnerVo.setCreatedAt(createdAt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            mongoTemplate.insert(
                    kylinTicketTimesPartnerVo, KylinTicketTimesPartnerVo.class.getSimpleName()
            );
            return ResponseDto.success(kylinTicketTimesPartnerVo);
        } catch (Exception e) {
            return ResponseDto.failure(ErrorMapping.get(20101));
        }
    }

    @Override
    public ResponseDto<String> deleteTimes(String ticketTimesId) {
        try {
            LocalDateTime updatedAt = LocalDateTime.now();

            KylinTicketTimesPartnerVo data = mongoTemplate.findOne(Query.query(Criteria.where("ticketTimesId").is(ticketTimesId)), KylinTicketTimesPartnerVo.class, KylinTicketTimesPartnerVo.class.getSimpleName());
            if (data.getStatus() == 0) {
                return ResponseDto.failure(ErrorMapping.get(20106));
            }
            KylinTicketTimeRelation ticketTimeRelation = ticketTimeRelationMapper.selectOne(
                    Wrappers.lambdaQuery(KylinTicketTimeRelation.class).eq(KylinTicketTimeRelation::getTimesId, ticketTimesId));
            if (ticketTimeRelation != null) {
                KylinPerformanceStatus performanceStatus = performanceStatusMapper.selectOne(
                        Wrappers.lambdaQuery(KylinPerformanceStatus.class).eq(KylinPerformanceStatus::getPerformanceId, ticketTimeRelation.getPerformanceId()));
                if(performanceStatus.getAuditStatus()==0){
                    return ResponseDto.failure(ErrorMapping.get(20101));
                }

                if (performanceStatus.getStatus() == 0 || performanceStatus.getStatus() == 4) {//未提审||被拒绝
                    HashMap<String, Object> map = ObjectUtil.cloneHashMapStringAndObject();
                    map.put("updatedAt", updatedAt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                    map.put("status", 0);

                    BasicDBObject object = ObjectUtil.cloneBasicDBObject().append("$set", mongoConverter.convertToMongoType(map));
                    mongoTemplate.getCollection(KylinTicketTimesPartnerVo.class.getSimpleName()).updateOne(
                            Query.query(Criteria.where("ticketTimesId").is(ticketTimesId)).getQueryObject(),
                            object
                    );
                    log.info(UserPathDto.setPartnerData("0","deleteTimes", "ticketTimesId="+ticketTimesId,"删除成功"));
                    return ResponseDto.success("删除成功");
                } else {
                    return ResponseDto.failure(ErrorMapping.get(20106));
                }
            } else {
                mongoTemplate.remove(Query.query(Criteria.where("ticketTimesId").is(ticketTimesId)), KylinTicketTimesPartnerVo.class, KylinTicketTimesPartnerVo.class.getSimpleName());
                return ResponseDto.success();
            }
        } catch (Exception e) {
            return ResponseDto.failure(ErrorMapping.get(20102));
        }
    }

    @Override
    public ResponseDto<KylinTicketTimesPartnerVo> changeTimes(CreateTicketTimesParam createTicketTimesParam) {
        try {
            LocalDateTime updatedAt = LocalDateTime.now();
            String title = "";
            if (createTicketTimesParam.getType() == 1) {
                title = createTicketTimesParam.getUseStart().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
            } else {
                title = createTicketTimesParam.getUseStart().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")) + "-" + createTicketTimesParam.getUseEnd().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
            }
            createTicketTimesParam.setTitle(title);

            // mongo 操作
            KylinTicketTimesPartnerVo kylinTicketTimesPartnerVo = KylinTicketTimesPartnerVo.getNew();
            BeanUtils.copyProperties(createTicketTimesParam, kylinTicketTimesPartnerVo);
            kylinTicketTimesPartnerVo.setTicketTimesId(createTicketTimesParam.getTicketTimesId());
            kylinTicketTimesPartnerVo.setUpdatedAt(updatedAt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            kylinTicketTimesPartnerVo.setUseStart(createTicketTimesParam.getUseStart().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            kylinTicketTimesPartnerVo.setUseEnd(createTicketTimesParam.getUseEnd().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            kylinTicketTimesPartnerVo.setStatus(null);

            BasicDBObject object = ObjectUtil.cloneBasicDBObject().append("$set", JSON.parse(JsonUtils.toJson(kylinTicketTimesPartnerVo)));
            Document doc = mongoTemplate.getCollection(KylinTicketTimesPartnerVo.class.getSimpleName()).findOneAndUpdate(
                    Query.query(Criteria.where("ticketTimesId").is(createTicketTimesParam.getTicketTimesId())).getQueryObject(),
                    object,
                    new FindOneAndUpdateOptions().returnDocument(ReturnDocument.AFTER)
            );

            HashMap<String,Object> ticketMap = new HashMap<>();
            ticketMap.put("useEnd",kylinTicketTimesPartnerVo.getUseEnd());
            ticketMap.put("useStart",kylinTicketTimesPartnerVo.getUseStart());
            BasicDBObject ticketObject = ObjectUtil.cloneBasicDBObject().append("$set", ticketMap);
            mongoTemplate.getCollection(KylinTicketPartnerVo.class.getSimpleName()).updateMany(
                    Query.query(Criteria.where("timesId").is(createTicketTimesParam.getTicketTimesId())).getQueryObject(),
                    ticketObject
            );

            log.info(UserPathDto.setPartnerData("0","changeTimes", createTicketTimesParam,JsonUtils.fromJson(doc.toJson(), KylinTicketTimesPartnerVo.class)));
            return ResponseDto.success(JsonUtils.fromJson(doc.toJson(), KylinTicketTimesPartnerVo.class));
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseDto.failure(ErrorMapping.get(20103));
        }
    }

    @Override
    public List<KylinTicketTimesPartnerVo> getTimesMongoList(String performancesId) {
        return mongoTemplate.find(Query.query(Criteria.where("performancesId").is(performancesId).and("status").ne(0)), KylinTicketTimesPartnerVo.class, KylinTicketTimesPartnerVo.class.getSimpleName());
    }

    @Override
    public KylinTicketTimesPartnerVo getTimesMongo(String timesId) {
        return mongoTemplate.findOne(Query.query(Criteria.where("ticketTimesId").is(timesId).and("status")), KylinTicketTimesPartnerVo.class, KylinTicketTimesPartnerVo.class.getSimpleName());
    }
}
