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


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.liquidnet.common.cache.redis.util.RedisUtil;
import com.liquidnet.commons.lang.util.BeanUtil;
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.dao.FieldMisDetailsDao;
import com.liquidnet.service.kylin.dao.FieldMisListDao;
import com.liquidnet.service.kylin.dto.param.FieldsAuditParam;
import com.liquidnet.service.kylin.dto.param.FieldsParam;
import com.liquidnet.service.kylin.dto.param.FieldsSearchParam;
import com.liquidnet.service.kylin.dto.param.FieldsStatusParam;
import com.liquidnet.service.kylin.dto.vo.FieldsVo;
import com.liquidnet.service.kylin.entity.KylinFieldStatus;
import com.liquidnet.service.kylin.entity.KylinFields;
import com.liquidnet.service.kylin.mapper.KylinFieldRelationMapper;
import com.liquidnet.service.kylin.mapper.KylinFieldStatusMapper;
import com.liquidnet.service.kylin.mapper.KylinFieldsMapper;
import com.liquidnet.service.kylin.service.admin.KylinFieldsAdminService;
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.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

@Service
public class FieldsAdminServiceImpl implements KylinFieldsAdminService {

    @Autowired
    MongoTemplate mongoTemplate;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private KylinFieldsMapper fieldsMapper;

    @Autowired
    private KylinFieldStatusMapper kylinFieldStatusMapper;

    @Autowired
    private KylinFieldRelationMapper fieldRelationsMapper;

    /**
     * 创建场地
     *
     * @param fieldsParam
     * @return boolean
     */
    @Override
    @Transactional
    public boolean fieldCreate(FieldsParam fieldsParam) {
        try {
            // 获取 主键id
            String fieldsId = IDGenerator.nextSnowId().toString();
            // 获取 当前时间 -> 创建时间
            LocalDateTime createdAt = LocalDateTime.now();

            // mysql 操作
            fieldsMapper.insert(fieldsParam.getFields(fieldsId, createdAt));
            kylinFieldStatusMapper.insert(fieldsParam.getFieldStatus(fieldsId, createdAt, 1, 1, 1, 1));
            fieldRelationsMapper.insert(fieldsParam.getFieldRelations(fieldsId, createdAt));

            // mongo 操作
            FieldsVo fieldsVo = new FieldsVo();
            BeanUtils.copyProperties(fieldsParam, fieldsVo);
            fieldsVo.setFieldsId(fieldsId);
            fieldsVo.setCreatedAt(createdAt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            fieldsVo.setUpdatedAt(createdAt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            FieldsVo data = mongoTemplate.insert(
                    fieldsVo, FieldsVo.class.getSimpleName()
            );

            // redis 操作
            redisUtil.hset(KylinRedisConst.FIELDS, fieldsId, fieldsVo);

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


    /**
     * mis修改场地全部数据
     *
     * @param fieldsParam
     * @return
     */
    @Override
    public boolean fieldUpdateMessage(FieldsParam fieldsParam) {
        try {
            String fieldsId = fieldsParam.getFieldsId();
            LocalDateTime updatedAt = LocalDateTime.now();
            // mysql 操作
            KylinFields fields = fieldsParam.getFields(null, null);
            fields.setUpdatedAt(updatedAt);
            fieldsMapper.update(fields
                    , new UpdateWrapper<KylinFields>().eq("fields_id", fieldsId));

            // mongo 操作
            FieldsVo fieldsVoData = new FieldsVo();
            BeanUtils.copyProperties(fieldsParam, fieldsVoData);
            fieldsVoData.setFieldsId(fieldsId);
            fieldsVoData.setUpdatedAt(updatedAt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

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

            // redis 操作
            redisUtil.hset(KylinRedisConst.FIELDS, fieldsId, JsonUtils.fromJson(doc.toJson(), FieldsVo.class));
            return true;

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


    /**
     * 场地列表 - 条件查询
     *
     * @param fieldsSearchParam
     * @return
     */
    @Override
    public List<FieldMisListDao> fieldList(FieldsSearchParam fieldsSearchParam) {
        try {
            fieldsSearchParam.setCityId(0);
            fieldsSearchParam.setDistrictId(0);
            fieldsSearchParam.setProvinceId(0);
            fieldsSearchParam.setPage((fieldsSearchParam.getPage() - 1) * fieldsSearchParam.getSize());

            List<FieldMisListDao> data = fieldsMapper.misSearchFields(BeanUtil.convertBeanToMap(fieldsSearchParam));
            return data;
        } catch (Exception e) {
            return new ArrayList<>();
        }
    }

    @Override
    public Long fieldListCount(FieldsSearchParam fieldsSearchParam) {
        try {
            fieldsSearchParam.setCityId(0);
            fieldsSearchParam.setDistrictId(0);
            fieldsSearchParam.setProvinceId(0);
            Long count = fieldsMapper.misSearchFieldsCount(BeanUtil.convertBeanToMap(fieldsSearchParam));
            return count;
        } catch (Exception e) {
            return 0L;
        }
    }

    /**
     * 场地详情
     *
     * @param fieldsId
     * @return
     */
    @Override
    public FieldMisDetailsDao fieldDetails(String fieldsId) {
        FieldMisDetailsDao data = fieldsMapper.misFieldsDetails(fieldsId);
        return data;
    }

    /**
     * 场地审核
     *
     * @param fieldsAuditParam
     * @return
     */
    @Override
    public boolean fieldAudit(FieldsAuditParam fieldsAuditParam) {
        try {
            String fieldsId = fieldsAuditParam.getFieldsId();
            LocalDateTime updatedAt = LocalDateTime.now();
            fieldsAuditParam.setChangeStatus(1);
            fieldsAuditParam.setUpdatedAt(updatedAt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

            // mysql 操作
            KylinFields fields = fieldsAuditParam.getFields();
            fields.setUpdatedAt(updatedAt);
            fieldsMapper.update(fields, new UpdateWrapper<KylinFields>().eq("fields_id", fieldsId));

            KylinFieldStatus fieldStatus = fieldsAuditParam.getFieldStatus();
            fieldStatus.setUpdatedAt(updatedAt);
            kylinFieldStatusMapper.update(fieldStatus, new UpdateWrapper<KylinFieldStatus>().eq("field_id", fieldsId));

            // mongo 操作
            Object obj = JSON.parse(JsonUtils.toJson(fieldsAuditParam));
            BasicDBObject object = new BasicDBObject("$set", obj);
            Document doc = mongoTemplate.getCollection(FieldsVo.class.getSimpleName()).findOneAndUpdate(
                    Query.query(Criteria.where("fieldsId").is(fieldsId)).getQueryObject(),
                    object,
                    new FindOneAndUpdateOptions().returnDocument(ReturnDocument.AFTER)
            );

            // redis 操作
            redisUtil.hset(KylinRedisConst.FIELDS, fieldsId, JsonUtils.fromJson(doc.toJson(), FieldsVo.class));
            return true;

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

    /**
     * 修改场地状态
     *
     * @param fieldsStatusParam
     * @return
     */
    @Override
    public boolean fieldStatus(FieldsStatusParam fieldsStatusParam) {
        try {
            String fieldsId = fieldsStatusParam.getFieldsId();
            LocalDateTime updatedAt = LocalDateTime.now();
            fieldsStatusParam.setUpdatedAt(updatedAt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

            KylinFieldStatus fieldStatus = fieldsStatusParam.getFieldStatus();
            fieldStatus.setUpdatedAt(updatedAt);
            kylinFieldStatusMapper.update(fieldStatus, new UpdateWrapper<KylinFieldStatus>().eq("field_id", fieldsId));

            Object obj = JSON.parse(JsonUtils.toJson(fieldsStatusParam));
            BasicDBObject object = new BasicDBObject("$set", obj);
            Document doc = mongoTemplate.getCollection(FieldsVo.class.getSimpleName()).findOneAndUpdate(
                    Query.query(Criteria.where("fieldsId").is(fieldsId)).getQueryObject(),
                    object,
                    new FindOneAndUpdateOptions().returnDocument(ReturnDocument.AFTER)
            );

            redisUtil.hset(KylinRedisConst.FIELDS, fieldsId, JsonUtils.fromJson(doc.toJson(), FieldsVo.class));
            return true;
        }catch (Exception e){
            return false;
        }
    }
}
