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

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.liquidnet.common.cache.redis.util.RedisUtil;
import com.liquidnet.commons.lang.util.IDGenerator;
import com.liquidnet.commons.lang.util.JsonUtils;
import com.liquidnet.service.kylin.constant.KylinRedisConst;
import com.liquidnet.service.kylin.dto.param.CreateTicketTimesParam;
import com.liquidnet.service.kylin.dto.vo.TicketTimesVo;
import com.liquidnet.service.kylin.dto.vo.TicketVo;
import com.liquidnet.service.kylin.entity.KylinTicketTimeRelation;
import com.liquidnet.service.kylin.entity.KylinTicketTimes;
import com.liquidnet.service.kylin.mapper.KylinTicketTimeRelationMapper;
import com.liquidnet.service.kylin.mapper.KylinTicketTimesMapper;
import com.liquidnet.service.kylin.service.partner.IKylinTicketTimesPartnerService;
import com.mongodb.BasicDBObject;
import com.mongodb.client.model.FindOneAndUpdateOptions;
import com.mongodb.client.model.ReturnDocument;
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
public class KylinTicketTimesPartnerServiceImpl extends ServiceImpl<KylinTicketTimesMapper, KylinTicketTimes> implements IKylinTicketTimesPartnerService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private KylinTicketTimesMapper ticketTimesMapper;

    @Autowired
    private KylinTicketTimeRelationMapper ticketTimeRelationMapper;

    @Autowired
    private MongoConverter mongoConverter;

    @Override
    public TicketTimesVo createTimes(CreateTicketTimesParam createTicketTimesParam) {

        // 获取 主键id
        String ticketTimesId = IDGenerator.nextSnowId().toString();
        // 获取 当前时间 -> 创建时间
        LocalDateTime createdAt = LocalDateTime.now();
        // 标题
        String title = "";
        if (createTicketTimesParam.getType() == 1) {
            title = createTicketTimesParam.getTimeStart().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
        } else {
            title = createTicketTimesParam.getTimeStart().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")) + "-" + createTicketTimesParam.getTimeEnd().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
        }

        // mysql 操作
        KylinTicketTimes ticketTimes = new KylinTicketTimes();
        BeanUtils.copyProperties(createTicketTimesParam, ticketTimes);
        ticketTimes.setTicketTimesId(ticketTimesId);
        ticketTimes.setCreatedAt(createdAt);
        ticketTimes.setStatus(1);
        ticketTimes.setTitle(title);
        ticketTimesMapper.insert(ticketTimes);

        KylinTicketTimeRelation ticketTimeRelation = new KylinTicketTimeRelation();
        ticketTimeRelation.setTicketTimeRelationId(IDGenerator.nextSnowId().toString());
        ticketTimeRelation.setTimesId(ticketTimesId);
        ticketTimeRelation.setPerformanceId(createTicketTimesParam.getPerformancesId());
        ticketTimeRelation.setCreatedAt(createdAt);
        ticketTimeRelationMapper.insert(ticketTimeRelation);

        // mongo 操作
        TicketTimesVo ticketTimesVo = new TicketTimesVo();
        ticketTimesVo.setTicketTimesId(ticketTimesId);
        ticketTimesVo.setTimeStart(createTicketTimesParam.getTimeStart().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        ticketTimesVo.setTimeEnd(createTicketTimesParam.getTimeStart().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        ticketTimesVo.setStatus(1);
        ticketTimesVo.setTitle(title);
        ticketTimesVo.setPerformancesId(createTicketTimesParam.getPerformancesId());
        ticketTimesVo.setType(createTicketTimesParam.getType());
        ticketTimesVo.setCreatedAt(createdAt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        TicketTimesVo data = mongoTemplate.insert(
                ticketTimesVo, TicketTimesVo.class.getSimpleName()
        );

        // redis 操作
        redisUtil.hset(KylinRedisConst.TIMES, ticketTimesId, ticketTimesVo);

        return ticketTimesVo;
    }

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

            KylinTicketTimes ticketTimes = new KylinTicketTimes();
            ticketTimes.setUpdatedAt(updatedAt);
            ticketTimes.setStatus(0);
            ticketTimesMapper.update(ticketTimes
                    , new UpdateWrapper<KylinTicketTimes>().eq("ticket_times_id", ticketTimesId));

            // mongo 操作
            HashMap<String, Object> map = new HashMap<>();
            map.put("updatedAt", updatedAt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            map.put("status", 0);

            BasicDBObject object = new BasicDBObject("$set", mongoConverter.convertToMongoType(map));
            Document doc = mongoTemplate.getCollection(TicketTimesVo.class.getSimpleName()).findOneAndUpdate(
                    Query.query(Criteria.where("ticketTimesId").is(ticketTimesId)).getQueryObject(),
                    object,
                    new FindOneAndUpdateOptions().returnDocument(ReturnDocument.AFTER)
            );

            // redis 操作
            redisUtil.hset(KylinRedisConst.TIMES, ticketTimesId, JsonUtils.fromJson(doc.toJson(), TicketTimesVo.class));

            return true;
        } catch (Exception e) {
            return false;
        }
    }

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

            // mysql 操作
            KylinTicketTimes ticketTimes = new KylinTicketTimes();
            BeanUtils.copyProperties(createTicketTimesParam, ticketTimes);
            ticketTimes.setUpdatedAt(updatedAt);
            ticketTimes.setStatus(1);
            ticketTimesMapper.update(ticketTimes, new UpdateWrapper<KylinTicketTimes>().eq("ticket_times_id", createTicketTimesParam.getTicketTimesId()));


            // mongo 操作
            TicketTimesVo ticketTimesVo = new TicketTimesVo();
            BeanUtils.copyProperties(createTicketTimesParam, ticketTimesVo);
            ticketTimesVo.setTicketTimesId(createTicketTimesParam.getTicketTimesId());
            ticketTimesVo.setUpdatedAt(updatedAt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            ticketTimesVo.setTimeStart(createTicketTimesParam.getTimeStart().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            ticketTimesVo.setTimeEnd(createTicketTimesParam.getTimeStart().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            ticketTimesVo.setStatus(1);

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

            // redis 操作
            redisUtil.hset(KylinRedisConst.TIMES, createTicketTimesParam.getTicketTimesId(), JsonUtils.fromJson(doc.toJson(), TicketTimesVo.class));
            return JsonUtils.fromJson(doc.toJson(), TicketTimesVo.class);

        }catch (Exception e){
            return null;
        }
    }

    @Override
    public List<TicketTimesVo> getTimesMongo(String performancesId) {
        return mongoTemplate.find(Query.query(Criteria.where("performancesId").is(performancesId)), TicketTimesVo.class, TicketTimesVo.class.getSimpleName());
    }
}
