package com.liquidnet.service.merchant.service.impl;

import com.liquidnet.common.exception.LiquidnetServiceException;
import com.liquidnet.commons.lang.util.CollectionUtil;
import com.liquidnet.commons.lang.util.CurrentUtil;
import com.liquidnet.commons.lang.util.IDGenerator;
import com.liquidnet.service.base.ErrorMapping;
import com.liquidnet.service.base.PagedResult;
import com.liquidnet.service.base.SqlMapping;
import com.liquidnet.service.base.constant.MQConst;
import com.liquidnet.service.merchant.dto.param.MerchantFieldsApplyParam;
import com.liquidnet.service.merchant.dto.vo.MerchantFieldsAppliesVo;
import com.liquidnet.service.merchant.dto.vo.MerchantFieldsVo;
import com.liquidnet.service.merchant.service.IMerchantFieldsAppliesService;
import com.liquidnet.service.merchant.service.MerchantRdmService;
import com.liquidnet.service.merchant.util.QueueUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

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

@Slf4j
@Service
public class MerchantFieldsAppliesServiceImpl implements IMerchantFieldsAppliesService {

    @Autowired
    MerchantRdmService merchantRdmService;

    @Autowired
    QueueUtil queueUtils;

    @Override
    public PagedResult<MerchantFieldsVo> search(String name) {
        return null;
    }

    @Override
    public String apply(MerchantFieldsApplyParam parameter) {
        String currentUid = CurrentUtil.getCurrentUid();
        LocalDateTime now = LocalDateTime.now();

        LinkedList<String> toMqSqls = CollectionUtil.linkedListString();
        LinkedList<Object[]> fieldUpdateObjs = CollectionUtil.linkedListObjectArr();
        LinkedList<Object[]> fieldApplyInsertObjs = CollectionUtil.linkedListObjectArr();

        long s = System.currentTimeMillis();

        // 若认领，查询验证场地
        MerchantFieldsVo fieldsVo = null;
        if (!parameter.getFieldId().isEmpty()) {
            fieldsVo = merchantRdmService.getFieldsVoByFieldId(parameter.getFieldId());
            if (null == fieldsVo) {
                ErrorMapping.ErrorMessage errorMessage = ErrorMapping.get("13001");
                throw new LiquidnetServiceException(errorMessage.getCode(), errorMessage.getMessage());
            }
            if (0 != fieldsVo.getClaimStatus()) {
                ErrorMapping.ErrorMessage errorMessage = ErrorMapping.get("13002");
                throw new LiquidnetServiceException(errorMessage.getCode(), errorMessage.getMessage());
            }

            // vo 更改场地状态
            fieldsVo.setClaimStatus(2);
            fieldsVo.setUpdatedAt(now);

            // redis
            merchantRdmService.setFieldsVoByFieldId(fieldsVo.getFieldId(), fieldsVo);
            log.debug("#RDS耗时:{}ms", System.currentTimeMillis() - s);
        }

        // vos 申请场地 上限
        List<MerchantFieldsAppliesVo> fieldsAppliesVos = merchantRdmService.getFieldsAppliesVosByUid(currentUid);
        if (!CollectionUtils.isEmpty(fieldsAppliesVos)) {
            if (fieldsAppliesVos.size() >= 10) {
                ErrorMapping.ErrorMessage errorMessage = ErrorMapping.get("13003");
                throw new LiquidnetServiceException(errorMessage.getCode(), errorMessage.getMessage());
            }
        }

        // 申请场地vo
        MerchantFieldsAppliesVo fieldsAppliesVo = MerchantFieldsAppliesVo.getNew();
        BeanUtils.copyProperties(parameter, fieldsAppliesVo);
        fieldsAppliesVo.setFieldApplyId(IDGenerator.nextSnowId());
        fieldsAppliesVo.setApplyStatus(0);
        if (!fieldsAppliesVo.getFieldId().isEmpty()) {
            fieldsAppliesVo.setApplyType("claim");
        } else {
            fieldsAppliesVo.setApplyType("create");
        }
        fieldsAppliesVo.setReject("");
        fieldsAppliesVo.setUid(currentUid);
        fieldsAppliesVo.setCreatedAt(now);

        // redis
        s = System.currentTimeMillis();
        merchantRdmService.addFieldsAppliesVoByUid(currentUid, fieldsAppliesVos, fieldsAppliesVo);
        log.debug("#RDS耗时:{}ms", System.currentTimeMillis() - s);

        // sql mapping
        if (null != fieldsVo) {
            toMqSqls.add(SqlMapping.get("merchant_fields.update_claim_status"));
            fieldUpdateObjs.add(new Object[]{
                    fieldsVo.getClaimStatus(), fieldsVo.getUpdatedAt(), fieldsVo.getFieldId()
            });
        }
        toMqSqls.add(SqlMapping.get("merchant_field_applies.insert"));
        fieldApplyInsertObjs.add(new Object[]{
                fieldsAppliesVo.getFieldApplyId(), fieldsAppliesVo.getApplyStatus(), fieldsAppliesVo.getApplyType(), fieldsAppliesVo.getReject(), fieldsAppliesVo.getUid(), fieldsAppliesVo.getFieldId(),
                fieldsAppliesVo.getName(), fieldsAppliesVo.getLogo(), fieldsAppliesVo.getBackground(), fieldsAppliesVo.getDescription(), fieldsAppliesVo.getBuiltDate(),
                fieldsAppliesVo.getProvinceId(), fieldsAppliesVo.getProvinceName(), fieldsAppliesVo.getCityId(), fieldsAppliesVo.getCityName(), fieldsAppliesVo.getDistrictId(), fieldsAppliesVo.getDistrictName(), fieldsAppliesVo.getAddress(), fieldsAppliesVo.getLongitude(), fieldsAppliesVo.getLatitude(),
                fieldsAppliesVo.getContactName(), fieldsAppliesVo.getContactEmail(), fieldsAppliesVo.getCompanyName(), fieldsAppliesVo.getLicenseCode(), fieldsAppliesVo.getLicenseImg(),
                fieldsAppliesVo.getLegalName(), fieldsAppliesVo.getLegalIdentity(), fieldsAppliesVo.getLegalIdentityObverse(), fieldsAppliesVo.getLegalIdentityReverse(), fieldsAppliesVo.getCreatedAt()
        });

        s = System.currentTimeMillis();
        if (null != fieldsVo) {
            queueUtils.sendMsgByRedis(
                    MQConst.MerchantQueue.SQL_MERCHANT_FIELD.getKey(),
                    SqlMapping.gets(toMqSqls, fieldUpdateObjs, fieldApplyInsertObjs)
            );
        } else {
            queueUtils.sendMsgByRedis(
                    MQConst.MerchantQueue.SQL_MERCHANT_FIELD.getKey(),
                    SqlMapping.gets(toMqSqls, fieldApplyInsertObjs)
            );
        }
        log.debug("#MQ耗时:{}ms", System.currentTimeMillis() - s);


        return fieldsAppliesVo.getFieldId();
    }
}
