package com.liquidnet.service.merchant.service;

import com.liquidnet.service.merchant.constant.MerchantAuthorizationConst;
import com.liquidnet.service.merchant.dto.vo.*;
import org.bson.Document;
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.data.mongodb.core.query.Update;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

@Component
public class MerchantMongoService {
    @Autowired
    MongoTemplate mongoTemplate;

    @Autowired
    MongoConverter mongoConverter;


    // 【场地相关】
    public MerchantFieldsVo getFieldsVoByFieldId(String fieldId) {
        Query query = Query.query(Criteria.where("fieldId").is(fieldId));
        return mongoTemplate.findOne(query, MerchantFieldsVo.class, MerchantFieldsVo.class.getSimpleName());
    }

    public void setFieldsVoByFieldId(String fieldId, MerchantFieldsVo vo) {
        Query query = Query.query(Criteria.where("fieldId").is(fieldId));
        Document document = (Document)mongoConverter.convertToMongoType(vo);
        Update update = Update.fromDocument(document);
        mongoTemplate.upsert(query, update, MerchantFieldsVo.class, MerchantFieldsVo.class.getSimpleName());
    }

    // 【场地申请相关】
    public List<MerchantFieldAppliesVo> getFieldAppliesVosByUid(String uid) {
        Query query = Query.query(Criteria.where("uid").is(uid).and("deletedAt").is(null));
        return mongoTemplate.find(query, MerchantFieldAppliesVo.class, MerchantFieldAppliesVo.class.getSimpleName());
    }

    public MerchantFieldAppliesVo addFieldAppliesVo(MerchantFieldAppliesVo vo) {
        return mongoTemplate.insert(vo, MerchantFieldAppliesVo.class.getSimpleName());
    }

    public void delFieldAppliesVoByFieldApplyId(String fieldApplyId) {
        Query query = Query.query(Criteria.where("fieldApplyId").is(fieldApplyId));
        mongoTemplate.remove(query, MerchantFieldAppliesVo.class.getSimpleName());
    }

    // 【默认验票员相关】
    public List<MerchantFieldCheckersVo> getFieldCheckersVosByFieldId(String fieldId) {
        Query query = Query.query(Criteria.where("fieldId").is(fieldId).and("deletedAt").is(null));
        return mongoTemplate.find(query, MerchantFieldCheckersVo.class, MerchantFieldCheckersVo.class.getSimpleName());
    }

    public MerchantFieldCheckersVo addFieldCheckersVo(MerchantFieldCheckersVo vo) {
        return mongoTemplate.insert(vo, MerchantFieldCheckersVo.class.getSimpleName());
    }

    public void delFieldCheckersVoByFieldCheckerId(String fieldCheckerId) {
        Query query = Query.query(Criteria.where("fieldCheckerId").is(fieldCheckerId));
        mongoTemplate.remove(query, MerchantFieldCheckersVo.class.getSimpleName());
    }


    // 【主办相关】
    public MerchantSponsorsVo getSponsorsVoBySponsorId(String sponsorId) {
        Query query = Query.query(Criteria.where("sponsorId").is(sponsorId));
        return mongoTemplate.findOne(query, MerchantSponsorsVo.class, MerchantSponsorsVo.class.getSimpleName());
    }

    public void setSponsorsVoBySponsorId(String sponsorId, MerchantSponsorsVo vo) {
        Query query = Query.query(Criteria.where("sponsorId").is(sponsorId));
        Document document = (Document)mongoConverter.convertToMongoType(vo);
        Update update = Update.fromDocument(document);
        mongoTemplate.upsert(query, update, MerchantSponsorsVo.class, MerchantSponsorsVo.class.getSimpleName());
    }

    // 【主办申请相关】
    public List<MerchantSponsorAppliesVo> getSponsorAppliesVosByUid(String uid) {
        Query query = Query.query(Criteria.where("uid").is(uid).and("deletedAt").is(null));
        return mongoTemplate.find(query, MerchantSponsorAppliesVo.class, MerchantSponsorAppliesVo.class.getSimpleName());
    }

    public MerchantSponsorAppliesVo addSponsorAppliesVo(MerchantSponsorAppliesVo vo) {
        return mongoTemplate.insert(vo, MerchantSponsorAppliesVo.class.getSimpleName());
    }

    public void delSponsorAppliesVoBySponsorApplyId(String sponsorApplyId) {
        Query query = Query.query(Criteria.where("sponsorApplyId").is(sponsorApplyId));
        mongoTemplate.remove(query, MerchantSponsorAppliesVo.class.getSimpleName());
    }


    // 【演出权限相关】
    public MerchantAuthorizationPerformanceVo getAuthorizationPerformanceVo(String performanceId, String uid) {
        Query query = Query.query(Criteria.where("performanceId").is(performanceId).and("uid").is(uid));
        return mongoTemplate.findOne(query, MerchantAuthorizationPerformanceVo.class, MerchantAuthorizationPerformanceVo.class.getSimpleName());
    }

    public MerchantAuthorizationPerformanceVo getAndSyncAuthorizationPerformanceVo(String performanceId, String uid) {
        // 聚合角色及权限
        Query recordsQuery = Query.query(Criteria.where("performanceId").is(performanceId).and("uid").is(uid).and("deletedAt").is(null));
        List<MerchantAuthorizationRecordsVo> authorizationRecordsVos = mongoTemplate.find(recordsQuery, MerchantAuthorizationRecordsVo.class, MerchantAuthorizationRecordsVo.class.getSimpleName());
        List<String> uidRoles = new ArrayList<>();
        List<String> permissionIds = new ArrayList<>();
        for (MerchantAuthorizationRecordsVo authorizationRecordsVo: authorizationRecordsVos) {
            if (!uidRoles.contains(authorizationRecordsVo.getUidRole())) {
                uidRoles.add(authorizationRecordsVo.getUidRole());
            }
            for (MerchantAuthorizationPermissionsVo authorizationPermissionsVo: authorizationRecordsVo.getPermissionsVos()) {
                if (!permissionIds.contains(authorizationPermissionsVo.getPermissionId())) {
                    permissionIds.add(authorizationPermissionsVo.getPermissionId());
                }
            }
        }
        MerchantAuthorizationPerformanceVo vo = MerchantAuthorizationPerformanceVo.getNew();
        vo.setUid(uid);
        vo.setPerformanceId(performanceId);
        vo.setUidRoles(uidRoles);
        vo.setPermissionIds(permissionIds);
        Query query = Query.query(Criteria.where("performanceId").is(performanceId).and("uid").is(uid));
        Document document = (Document)mongoConverter.convertToMongoType(vo);
        Update update = Update.fromDocument(document);
        mongoTemplate.upsert(query, update, MerchantAuthorizationPerformanceVo.class, MerchantAuthorizationPerformanceVo.class.getSimpleName());
        return vo;
    }


    // 【授权记录相关】
    public MerchantAuthorizationRecordsVo getAuthorizationRecordsVoByAuthorizationRecordId(String authorizationRecordId) {
        Query query = Query.query(Criteria.where("authorizationRecordId").is(authorizationRecordId).and("deletedAt").is(null));
        return mongoTemplate.findOne(query, MerchantAuthorizationRecordsVo.class, MerchantAuthorizationRecordsVo.class.getSimpleName());
    }

    public List<MerchantAuthorizationRecordsVo> getAuthorizationRecordsVosByUid(String uid, String performanceId) {
        Query query = Query.query(Criteria.where("uid").is(uid).and("performanceId").is(performanceId).and("deletedAt").is(null));
        return mongoTemplate.find(query, MerchantAuthorizationRecordsVo.class, MerchantAuthorizationRecordsVo.class.getSimpleName());
    }

    public List<MerchantAuthorizationRecordsVo> getAuthorizationRecordsCheckersVosByCuid(String cuid, String performanceId) {
        Query query = Query.query(Criteria.where("uidRole").is(MerchantAuthorizationConst.PerformanceRole.CHECKER.getRole()).and("cuid").is(cuid).and("performanceId").is(performanceId).and("deletedAt").is(null));
        return mongoTemplate.find(query, MerchantAuthorizationRecordsVo.class, MerchantAuthorizationRecordsVo.class.getSimpleName());
    }
}
