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

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.TicketCreateParam;
import com.liquidnet.service.kylin.dto.vo.partner.TicketTimesCreatePartnerVo;
import com.liquidnet.service.kylin.dto.vo.partner.TicketCreatePartnerVo;
import com.liquidnet.service.kylin.entity.*;
import com.liquidnet.service.kylin.mapper.KylinTicketRelationsMapper;
import com.liquidnet.service.kylin.mapper.KylinTicketStatusMapper;
import com.liquidnet.service.kylin.mapper.KylinTicketsMapper;
import com.liquidnet.service.kylin.service.partner.IKylinTicketsPartnerService;
import com.mongodb.BasicDBObject;
import com.mongodb.client.model.FindOneAndUpdateOptions;
import com.mongodb.client.model.ReturnDocument;
import com.mongodb.client.result.UpdateResult;
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 KylinTicketsPartnerServiceImpl extends ServiceImpl<KylinTicketsMapper, KylinTickets> implements IKylinTicketsPartnerService {

    @Autowired
    MongoTemplate mongoTemplate;

    @Autowired
    private MongoConverter mongoConverter;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private KylinTicketsMapper ticketsMapper;

    @Autowired
    private KylinTicketStatusMapper ticketStatusMapper;

    @Autowired
    private KylinTicketRelationsMapper ticketRelationsMapper;

    @Override
    public TicketCreatePartnerVo createTicket(TicketCreateParam ticketCreateParam) {
        // 获取 主键id
        String ticketsId = IDGenerator.nextSnowId().toString();
        // 获取 当前时间 -> 创建时间
        LocalDateTime createdAt = LocalDateTime.now();

        ticketCreateParam.setTicketsId(ticketsId);

        // mysql 操作
//        ticketsMapper.insert(ticketCreateParam.kylinTickets(ticketsId, createdAt, null));
//        ticketStatusMapper.insert(ticketCreateParam.kylinTicketStatus(ticketsId, createdAt, null));
//        ticketRelationsMapper.insert(ticketCreateParam.kylinTicketRelations(ticketsId, createdAt, null));

        // mongo 操作
        TicketCreatePartnerVo ticketCreatePartnerVo = new TicketCreatePartnerVo();
        BeanUtils.copyProperties(ticketCreateParam, ticketCreatePartnerVo);
        ticketCreatePartnerVo.setTicketsId(ticketsId);
        ticketCreatePartnerVo.setCreatedAt(createdAt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        ticketCreatePartnerVo.setTimeEndExpress(ticketCreateParam.getTimeEndExpress().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        ticketCreatePartnerVo.setTimeStart(ticketCreateParam.getTimeStart().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        ticketCreatePartnerVo.setTimeEnd(ticketCreateParam.getTimeEnd().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

        TicketTimesCreatePartnerVo ticketTimesCreatePartnerVo = mongoTemplate.findOne(Query.query(Criteria.where("ticketTimesId").is(ticketCreateParam.getTimesId())), TicketTimesCreatePartnerVo.class, TicketTimesCreatePartnerVo.class.getSimpleName());
        ticketCreatePartnerVo.setUseStart(ticketTimesCreatePartnerVo.getUseStart());
        ticketCreatePartnerVo.setUseEnd(ticketTimesCreatePartnerVo.getUseEnd());
        ticketCreatePartnerVo.setType(ticketTimesCreatePartnerVo.getType());

        ticketCreatePartnerVo.setDefault();

        ticketCreatePartnerVo.setQrCodeShowTime(ticketCreateParam.getQrCodeShowTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        TicketCreatePartnerVo data = mongoTemplate.insert(
                ticketCreatePartnerVo, TicketCreatePartnerVo.class.getSimpleName()
        );

        // redis 操作
        redisUtil.hset(KylinRedisConst.TICKET, ticketsId, ticketCreatePartnerVo);
        return ticketCreatePartnerVo;
    }

    @Override
    public TicketCreatePartnerVo updateTicket(TicketCreateParam ticketCreateParam) {
        try {
            String ticketId = ticketCreateParam.getTicketsId();
            LocalDateTime updatedAt = LocalDateTime.now();
            // mysql 操作
//            KylinTickets tickets = ticketCreateParam.kylinTickets(ticketId, null, updatedAt);
//            tickets.setUpdatedAt(updatedAt);
//            ticketsMapper.update(tickets
//                    , new UpdateWrapper<KylinTickets>().eq("tickets_id", ticketId));

            // mongo 操作
            TicketCreatePartnerVo ticketCreatePartnerVo = new TicketCreatePartnerVo();
            BeanUtils.copyProperties(ticketCreateParam, ticketCreatePartnerVo);
            ticketCreatePartnerVo.setUpdatedAt(updatedAt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            ticketCreatePartnerVo.setTimeEndExpress(ticketCreateParam.getTimeEndExpress().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            ticketCreatePartnerVo.setTimeStart(ticketCreateParam.getTimeStart().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            ticketCreatePartnerVo.setTimeEnd(ticketCreateParam.getTimeEnd().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            ticketCreatePartnerVo.setQrCodeShowTime(ticketCreateParam.getQrCodeShowTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            ticketCreatePartnerVo.setTimesId(null);
            ticketCreatePartnerVo.setDefault();

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

            // redis 操作
            TicketCreatePartnerVo ticketCreatePartnerVoData = JsonUtils.fromJson(doc.toJson(), TicketCreatePartnerVo.class);
            redisUtil.hset(KylinRedisConst.TICKET, ticketId, ticketCreatePartnerVoData);
            return ticketCreatePartnerVoData;
        } catch (Exception e) {
            return null;
        }
    }

    @Override
    public boolean deleteTicket(String ticketsId) {
        try {
            LocalDateTime updatedAt = LocalDateTime.now();

//            KylinTicketStatus ticketStatus = new KylinTicketStatus();
//            ticketStatus.setUpdatedAt(updatedAt);
//            ticketStatus.setStatus(-1);
//            ticketStatusMapper.update(ticketStatus
//                    , new UpdateWrapper<KylinTicketStatus>().eq("ticket_id", ticketsId));

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

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

            // redis 操作
            redisUtil.hset(KylinRedisConst.TICKET, ticketsId, JsonUtils.fromJson(doc.toJson(), TicketCreatePartnerVo.class));

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

    @Override
    public TicketCreatePartnerVo copyTicket(String ticketsId) {

        // 获取 当前时间 -> 创建时间
        LocalDateTime createdAt = LocalDateTime.now();

//        KylinTickets tickets = ticketsMapper.selectOne(new UpdateWrapper<KylinTickets>().eq("tickets_id", ticketsId));
//        tickets.setCreatedAt(createdAt);
//        KylinTicketStatus ticketStatus = ticketStatusMapper.selectOne(new UpdateWrapper<KylinTicketStatus>().eq("ticket_id", ticketsId));
//        ticketStatus.setCreatedAt(createdAt);
//        KylinTicketRelations ticketRelations = ticketRelationsMapper.selectOne(new UpdateWrapper<KylinTicketRelations>().eq("ticket_id", ticketsId));
//        ticketRelations.setCreatedAt(createdAt);
//        String ticketsCopyId = IDGenerator.nextSnowId().toString();
//        tickets.setTicketsId(ticketsCopyId);
//        ticketStatus.setTicketId(ticketsCopyId);
//        ticketStatus.setTicketStatusId(IDGenerator.nextSnowId().toString());
//        ticketRelations.setTicketId(ticketsCopyId);
//        ticketRelations.setTicketRelationsId(IDGenerator.nextSnowId().toString());
//        ticketsMapper.insert(tickets);
//        ticketStatusMapper.insert(ticketStatus);
//        ticketRelationsMapper.insert(ticketRelations);

        TicketCreatePartnerVo ticketCreatePartnerVo = mongoTemplate.findOne(Query.query(Criteria.where("ticketsId").is(ticketsId)), TicketCreatePartnerVo.class, TicketCreatePartnerVo.class.getSimpleName());
        ticketCreatePartnerVo.setCreatedAt(createdAt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        ticketCreatePartnerVo.setTicketsId(IDGenerator.nextSnowId().toString());

        TicketCreatePartnerVo data = mongoTemplate.insert(
                ticketCreatePartnerVo, TicketCreatePartnerVo.class.getSimpleName()
        );

        redisUtil.hset(KylinRedisConst.TICKET, ticketsId, ticketCreatePartnerVo);
        return ticketCreatePartnerVo;
    }

    @Override
    public boolean submitTicketByTimes(String timesId) {
        LocalDateTime updatedAt = LocalDateTime.now();
//        KylinTicketStatus ticketStatus = new KylinTicketStatus();
//        ticketStatus.setUpdatedAt(updatedAt);
//        ticketStatus.setStatus(1);
//        ticketStatusMapper.update(ticketStatus
//                , new UpdateWrapper<KylinTicketStatus>().eq("time_id", timesId));

        HashMap<String, Object> map = new HashMap<>();
        map.put("status", 1);
        map.put("updatedAt", updatedAt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        BasicDBObject object = new BasicDBObject("$set", mongoConverter.convertToMongoType(map));
        UpdateResult updateResult = mongoTemplate.getCollection(TicketCreatePartnerVo.class.getSimpleName()).updateMany(
                Query.query(Criteria.where("timesId").is(timesId)).getQueryObject(),
                object
        );
        return updateResult.getModifiedCount()<=0;
    }

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

    @Override
    public TicketCreatePartnerVo getTicketsMongo(String ticketsId) {
        return mongoTemplate.findOne(Query.query(Criteria.where("ticketsId").is(ticketsId)), TicketCreatePartnerVo.class, TicketCreatePartnerVo.class.getSimpleName());
    }

}
