package com.liquidnet.client.admin.zhengzai.merchant.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.liquidnet.client.admin.zhengzai.merchant.service.IMerchantCompaniesAdminService;
import com.liquidnet.client.admin.zhengzai.merchant.service.IMerchantSponsorAppliesAdminService;
import com.liquidnet.client.admin.zhengzai.merchant.service.IMerchantSponsorsAdminService;
import com.liquidnet.client.admin.zhengzai.merchant.utils.MerchantMongoUtil;
import com.liquidnet.client.admin.zhengzai.merchant.utils.MerchantRedisUtil;
import com.liquidnet.common.exception.LiquidnetServiceException;
import com.liquidnet.commons.lang.util.IDGenerator;
import com.liquidnet.service.merchant.dto.vo.MerchantCompaniesVo;
import com.liquidnet.service.merchant.dto.vo.MerchantSponsorAppliesVo;
import com.liquidnet.service.merchant.dto.vo.MerchantSponsorsVo;
import com.liquidnet.service.merchant.entity.MerchantCompanies;
import com.liquidnet.service.merchant.entity.MerchantSponsorApplies;
import com.liquidnet.service.merchant.entity.MerchantSponsors;
import com.liquidnet.service.merchant.mapper.MerchantSponsorAppliesMapper;
import lombok.extern.slf4j.Slf4j;
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.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;

@Slf4j
@Service
public class MerchantSponsorAppliesAdminServiceImpl extends ServiceImpl<MerchantSponsorAppliesMapper, MerchantSponsorApplies> implements IMerchantSponsorAppliesAdminService {

    @Autowired
    MerchantRedisUtil merchantRedisUtil;

    @Autowired
    MerchantMongoUtil merchantMongoUtil;

    @Autowired
    MongoTemplate mongoTemplate;

    @Autowired
    IMerchantSponsorsAdminService merchantSponsorsAdminService;

    @Autowired
    IMerchantCompaniesAdminService merchantCompaniesAdminService;

    @Override
    public boolean applyApprove(String sponsorApplyId, String auditUid, String auditName) {
        LocalDateTime now = LocalDateTime.now();

        // 主办申请 entity
        LambdaQueryWrapper<MerchantSponsorApplies> sponsorAppliesLambdaQueryWrapper = Wrappers.lambdaQuery(MerchantSponsorApplies.class);
        sponsorAppliesLambdaQueryWrapper.eq(MerchantSponsorApplies::getSponsorApplyId, sponsorApplyId);
        MerchantSponsorApplies sponsorAppliesEntity = getOne(sponsorAppliesLambdaQueryWrapper);
        if (0 != sponsorAppliesEntity.getApplyStatus()) {
            // todo error
            throw new LiquidnetServiceException();
        }

        // 创建逻辑

        // 公司 entity mysql
        MerchantCompanies companiesEntity = null;
        if (!sponsorAppliesEntity.getCompanyName().isEmpty()) {
            companiesEntity = new MerchantCompanies();
            companiesEntity.setCompanyId(IDGenerator.nextSnowId());
            companiesEntity.setName(sponsorAppliesEntity.getCompanyName());
            companiesEntity.setLicenseCode(sponsorAppliesEntity.getLicenseCode());
            companiesEntity.setLicenseImg(sponsorAppliesEntity.getLicenseImg());
            companiesEntity.setLegalName(sponsorAppliesEntity.getLegalName());
            companiesEntity.setLegalIdentity(sponsorAppliesEntity.getLegalIdentity());
            companiesEntity.setLegalIdentityObverse(sponsorAppliesEntity.getLegalIdentityObverse());
            companiesEntity.setLegalIdentityReverse(sponsorAppliesEntity.getLegalIdentityReverse());
            companiesEntity.setCreatedAt(now);
            boolean success = merchantCompaniesAdminService.save(companiesEntity);
            if (!success) {
                // todo error
                throw new LiquidnetServiceException();
            }
        }

        // 主办 entity mysql
        MerchantSponsors sponsorsEntity = new MerchantSponsors();
        sponsorsEntity.setSponsorId(IDGenerator.nextSnowId());
        sponsorsEntity.setIsOnline(1);
        sponsorsEntity.setUid(sponsorAppliesEntity.getUid());
        sponsorsEntity.setName(sponsorAppliesEntity.getName());
        sponsorsEntity.setLogo(sponsorAppliesEntity.getLogo());
        sponsorsEntity.setBackground(sponsorAppliesEntity.getBackground());
        sponsorsEntity.setDescription(sponsorAppliesEntity.getDescription());
        sponsorsEntity.setContactName(sponsorAppliesEntity.getContactName());
        sponsorsEntity.setContactIdentity(sponsorAppliesEntity.getContactIdentity());
        sponsorsEntity.setContactIdentityObverse(sponsorAppliesEntity.getContactIdentityObverse());
        sponsorsEntity.setContactIdentityReverse(sponsorAppliesEntity.getContactIdentityReverse());
        sponsorsEntity.setContactEmail(sponsorAppliesEntity.getContactEmail());
        if (null != companiesEntity) {
            sponsorsEntity.setCompanyId(companiesEntity.getCompanyId());
        } else {
            sponsorsEntity.setCompanyId("");
        }
        sponsorsEntity.setCreatedAt(now);
        boolean success = merchantSponsorsAdminService.save(sponsorsEntity);
        if (!success) {
            // todo error
            throw new LiquidnetServiceException();
        }

        // 主办申请 entity mysql
        sponsorAppliesEntity.setApplyStatus(1);
        sponsorAppliesEntity.setReject("");
        sponsorAppliesEntity.setAuditUid(auditUid);
        sponsorAppliesEntity.setAuditName(auditName);
        sponsorAppliesEntity.setAuditedAt(now);
        sponsorAppliesEntity.setUpdatedAt(now);
        sponsorAppliesEntity.setSponsorId(sponsorsEntity.getSponsorId());
        LambdaUpdateWrapper<MerchantSponsorApplies> sponsorAppliesLambdaUpdateWrapper = Wrappers.lambdaUpdate(MerchantSponsorApplies.class);
        sponsorAppliesLambdaUpdateWrapper.eq(MerchantSponsorApplies::getSponsorApplyId, sponsorAppliesEntity.getSponsorApplyId());
        sponsorAppliesLambdaUpdateWrapper.set(MerchantSponsorApplies::getApplyStatus, sponsorAppliesEntity.getApplyStatus());
        sponsorAppliesLambdaUpdateWrapper.set(MerchantSponsorApplies::getReject, sponsorAppliesEntity.getReject());
        sponsorAppliesLambdaUpdateWrapper.set(MerchantSponsorApplies::getAuditUid, sponsorAppliesEntity.getAuditUid());
        sponsorAppliesLambdaUpdateWrapper.set(MerchantSponsorApplies::getAuditName, sponsorAppliesEntity.getAuditName());
        sponsorAppliesLambdaUpdateWrapper.set(MerchantSponsorApplies::getAuditedAt, sponsorAppliesEntity.getAuditedAt());
        sponsorAppliesLambdaUpdateWrapper.set(MerchantSponsorApplies::getUpdatedAt, sponsorAppliesEntity.getUpdatedAt());
        sponsorAppliesLambdaUpdateWrapper.set(MerchantSponsorApplies::getSponsorId, sponsorAppliesEntity.getSponsorId());
        success = update(sponsorAppliesLambdaUpdateWrapper);
        if (!success) {
            // todo error
            throw new LiquidnetServiceException();
        }

        // 主办 vo
        MerchantSponsorsVo sponsorsVo = MerchantSponsorsVo.getNew();
        sponsorsVo.copy(sponsorsEntity);
        if (null != companiesEntity) {
            // 公司 vo
            MerchantCompaniesVo companiesVo = MerchantCompaniesVo.getNew();
            companiesVo.copy(companiesEntity);

            sponsorsVo.setCompaniesVo(companiesVo);
        }

        // 主办申请 vo
        MerchantSponsorAppliesVo sponsorAppliesVo = MerchantSponsorAppliesVo.getNew();
        sponsorAppliesVo.copy(sponsorAppliesEntity);

        // 主办 sync mongo
        merchantMongoUtil.setSponsorsVoBySponsorId(sponsorsVo.getSponsorId(), sponsorsVo);

        // 主办 sync redis
        merchantRedisUtil.setSponsorsVoBySponsorId(sponsorsVo.getSponsorId(), sponsorsVo);

        // 主办申请 sync mongo
        Query query = Query.query(Criteria.where("sponsorApplyId").is(sponsorAppliesVo.getSponsorApplyId()));
        Update update = Update.update("applyStatus", sponsorAppliesVo.getApplyStatus());
        update.set("reject", sponsorAppliesVo.getReject());
        update.set("auditUid", sponsorAppliesVo.getAuditUid());
        update.set("auditName", sponsorAppliesVo.getAuditName());
        update.set("auditedAt", sponsorAppliesVo.getAuditedAt());
        update.set("updatedAt", sponsorAppliesVo.getUpdatedAt());
        update.set("sponsorId", sponsorAppliesVo.getSponsorId());
        mongoTemplate.updateFirst(query, update, MerchantSponsorAppliesVo.class, MerchantSponsorAppliesVo.class.getSimpleName());

        // 主办申请 sync redis
        List<MerchantSponsorAppliesVo> sponsorAppliesVos = merchantRedisUtil.getSponsorAppliesVosByUid(sponsorAppliesVo.getUid());
        merchantRedisUtil.setSponsorAppliesVoByUid(sponsorAppliesVo.getUid(), sponsorAppliesVos, sponsorAppliesVo);
        
        return true;
    }

    @Override
    public boolean applyReject(String sponsorApplyId, String auditUid, String auditName, String reject) {
        LocalDateTime now = LocalDateTime.now();

        // 主办申请 entity
        LambdaQueryWrapper<MerchantSponsorApplies> sponsorAppliesLambdaQueryWrapper = Wrappers.lambdaQuery(MerchantSponsorApplies.class);
        sponsorAppliesLambdaQueryWrapper.eq(MerchantSponsorApplies::getSponsorApplyId, sponsorApplyId);
        MerchantSponsorApplies sponsorAppliesEntity = getOne(sponsorAppliesLambdaQueryWrapper);
        if (0 != sponsorAppliesEntity.getApplyStatus()) {
            // todo error
            throw new LiquidnetServiceException();
        }

        // 驳回逻辑

        // 主办申请 entity mysql
        sponsorAppliesEntity.setApplyStatus(2);
        sponsorAppliesEntity.setReject(reject);
        sponsorAppliesEntity.setAuditUid(auditUid);
        sponsorAppliesEntity.setAuditName(auditName);
        sponsorAppliesEntity.setAuditedAt(now);
        sponsorAppliesEntity.setUpdatedAt(now);
        LambdaUpdateWrapper<MerchantSponsorApplies> sponsorAppliesLambdaUpdateWrapper = Wrappers.lambdaUpdate(MerchantSponsorApplies.class);
        sponsorAppliesLambdaUpdateWrapper.eq(MerchantSponsorApplies::getSponsorApplyId, sponsorAppliesEntity.getSponsorApplyId());
        sponsorAppliesLambdaUpdateWrapper.set(MerchantSponsorApplies::getApplyStatus, sponsorAppliesEntity.getApplyStatus());
        sponsorAppliesLambdaUpdateWrapper.set(MerchantSponsorApplies::getReject, sponsorAppliesEntity.getReject());
        sponsorAppliesLambdaUpdateWrapper.set(MerchantSponsorApplies::getAuditUid, sponsorAppliesEntity.getAuditUid());
        sponsorAppliesLambdaUpdateWrapper.set(MerchantSponsorApplies::getAuditName, sponsorAppliesEntity.getAuditName());
        sponsorAppliesLambdaUpdateWrapper.set(MerchantSponsorApplies::getAuditedAt, sponsorAppliesEntity.getAuditedAt());
        sponsorAppliesLambdaUpdateWrapper.set(MerchantSponsorApplies::getUpdatedAt, sponsorAppliesEntity.getUpdatedAt());
        boolean success = update(sponsorAppliesLambdaUpdateWrapper);
        if (!success) {
            // todo error
            throw new LiquidnetServiceException();
        }

        // 主办申请 vo
        MerchantSponsorAppliesVo sponsorAppliesVo = MerchantSponsorAppliesVo.getNew();
        sponsorAppliesVo.copy(sponsorAppliesEntity);

        // 主办申请 sync mongo
        Query query = Query.query(Criteria.where("sponsorApplyId").is(sponsorAppliesVo.getSponsorApplyId()));
        Update update = Update.update("applyStatus", sponsorAppliesVo.getApplyStatus());
        update.set("reject", sponsorAppliesVo.getReject());
        update.set("auditUid", sponsorAppliesVo.getAuditUid());
        update.set("auditName", sponsorAppliesVo.getAuditName());
        update.set("auditedAt", sponsorAppliesVo.getAuditedAt());
        update.set("updatedAt", sponsorAppliesVo.getUpdatedAt());
        update.set("sponsorId", sponsorAppliesVo.getSponsorId());
        mongoTemplate.updateFirst(query, update, MerchantSponsorAppliesVo.class, MerchantSponsorAppliesVo.class.getSimpleName());

        // 主办申请 sync redis
        List<MerchantSponsorAppliesVo> sponsorAppliesVos = merchantRedisUtil.getSponsorAppliesVosByUid(sponsorAppliesVo.getUid());
        merchantRedisUtil.setSponsorAppliesVoByUid(sponsorAppliesVo.getUid(), sponsorAppliesVos, sponsorAppliesVo);

        return true;
    }
}
