package com.hfkj.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.google.zxing.WriterException;
import com.hfkj.common.QRCodeGenerator;
import com.hfkj.common.exception.ErrorCode;
import com.hfkj.common.exception.ErrorHelp;
import com.hfkj.common.exception.SysCode;
import com.hfkj.common.security.UserCenter;
import com.hfkj.common.utils.HttpUtils;
import com.hfkj.common.utils.HttpsUtils;
import com.hfkj.config.CommonSysConst;
import com.hfkj.config.WeChatQrcodeUtils;
import com.hfkj.dao.BsPayQrCodeMapper;
import com.hfkj.entity.*;
import com.hfkj.model.UserInfoModel;
import com.hfkj.service.*;
import com.hfkj.sysenum.PayQrCodeStatusEnum;
import com.hfkj.sysenum.WeChatQrCodeActionNameEnum;
import com.hfkj.sysenum.WeChatQrCodeTypeEnum;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service("payQrCodeService")
public class BsPayQrCodeServiceImpl implements BsPayQrCodeService {

    @Resource
    private BsPayQrCodeMapper payQrCodeMapper;

    @Resource
    private BsAgentService agentService;

    @Resource
    private BsSalesmanService salesmanService;

    @Resource
    private BsCompanyService companyService;

    @Resource
    private BsStoreService storeService;

    @Resource
    private BsMerService merService;

    @Resource
    private WeChatQrcodeUtils weChatQrcodeUtils;

    @Resource
    private UserCenter userCenter;

    @Override
    public void editData(BsPayQrCode payQrCode, String wxToken) {
        UserInfoModel userModel = userCenter.getSessionModel(UserInfoModel.class);
        if (userModel == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.SEC_USER_EXPIRED, "");
        }
        // 微信token 请求生成微信的二维码
        if (StringUtils.isBlank(wxToken)) {
            JSONObject response = HttpsUtils.doGet(CommonSysConst.getSysConfig().getHsg_domain_name() + "/v1/wxMsg/getWxToken");
            if (StringUtils.isBlank(response.getString("return_data"))) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "获取token失败");
            }
            wxToken = response.getString("return_data");
        }
        try {
            if (payQrCode.getId() == null) {
                payQrCode.setCreateTime(new Date());
                payQrCode.setUpdateTime(new Date());
                payQrCode.setStatus(PayQrCodeStatusEnum.status1.getNumber());
                payQrCode.setOpUserId(userModel.getSecUser().getId());
                payQrCode.setOpUserName(userModel.getSecUser().getUserName());
                payQrCodeMapper.insert(payQrCode);

                // 生成序列号
                Long serialNumber = 1000000000 + payQrCode.getId();
                payQrCode.setSerialNumber(serialNumber.toString());
                payQrCode.setQrCodeData(CommonSysConst.getSysConfig().getQr_code_data_url() + "?sn=" + payQrCode.getSerialNumber());
                payQrCode.setQrCodeUrl(CommonSysConst.getSysConfig().getQr_code_url() + payQrCode.getSerialNumber() + ".png");

                // 生成支付二维码
                QRCodeGenerator.generateQRCodeImage(
                        payQrCode.getQrCodeData(),
                        350,
                        350,
                        CommonSysConst.getSysConfig().getFilesystem() + "/payQrCode/" + payQrCode.getSerialNumber() + ".png"
                );
                // 生成公众号二维码
                payQrCode.setWechatQrCodeUrl(weChatQrcodeUtils.generateQrCodeImgUrl(wxToken, WeChatQrCodeTypeEnum.PAYMENT_CODE, payQrCode.getSerialNumber(), WeChatQrCodeActionNameEnum.actionName3));
                payQrCodeMapper.updateByPrimaryKey(payQrCode);

            } else {
                payQrCode.setUpdateTime(new Date());
                payQrCodeMapper.updateByPrimaryKey(payQrCode);
            }
        } catch (WriterException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    @Transactional(propagation= Propagation.REQUIRES_NEW,rollbackFor= {RuntimeException.class})
    public void generatePayQrCode(Integer generateNum) {
        JSONObject response = HttpsUtils.doGet(CommonSysConst.getSysConfig().getHsg_domain_name() + "/v1/wxMsg/getWxToken");
        if (StringUtils.isBlank(response.getString("return_data"))) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "获取token失败");
        }
        String token = response.getString("return_data");
        BsPayQrCode payQrCode;
        for (int i = 0; i < generateNum;i++) {
            payQrCode = new BsPayQrCode();
            editData(payQrCode, token);
        }
    }

    @Override
    public void batchAssignCompany(Long companyId, List<Long> qrCodeIdList) {
        for (Long qrCodeId : qrCodeIdList) {
            assignCompany(companyId, qrCodeId);
        }
    }

    @Override
    @Transactional(propagation= Propagation.REQUIRES_NEW,rollbackFor= {RuntimeException.class})
    public void batchAssignAgent(Long agentId, List<Long> qrCodeIdList) {
        for (Long qrCodeId : qrCodeIdList) {
            assignAgent(agentId, qrCodeId);
        }
    }

    @Override
    public void assignCompany(Long companyId, Long qrCodeId) {
        // 二维码
        BsPayQrCode qrCode = getDetailById(qrCodeId);
        if (qrCode == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到二维码信息");
        }
        if (!qrCode.getStatus().equals(PayQrCodeStatusEnum.status1.getNumber())) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "二维码已被停用");
        }
        if (qrCode.getCompanyId() != null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "二维码序列号为：" + qrCode.getSerialNumber() + "的二维码,无法分配，二维码已分配给其他公司");
        }
        // 公司
        BsCompany company = companyService.getCompanyById(companyId);
        if (company == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到公司信息");
        }
        qrCode.setCompanyId(company.getId());
        qrCode.setCompanyName(company.getName());
        editData(qrCode, null);
    }

    @Override
    public void assignAgent(Long agentId, Long qrCodeId) {
        // 二维码
        BsPayQrCode qrCode = getDetailById(qrCodeId);
        if (qrCode == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到二维码信息");
        }
        if (!qrCode.getStatus().equals(PayQrCodeStatusEnum.status1.getNumber())) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "二维码已被停用");
        }
        if (qrCode.getAgentId() != null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "二维码序列号为：" + qrCode.getSerialNumber() + "的二维码,无法分配，二维码已分配给其他代理商");
        }
        // 代理商
        BsAgent agent = agentService.getAgent(agentId);
        if (agent == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到代理商信息");
        }
        qrCode.setAgentId(agent.getId());
        qrCode.setAgentName(agent.getName());
        editData(qrCode, null);
    }

    @Override
    @Transactional(propagation= Propagation.REQUIRES_NEW,rollbackFor= {RuntimeException.class})
    public void batchAssignSalesman(Long salesmanId, List<Long> qrCodeIdList) {
        for (Long qrCodeId : qrCodeIdList) {
            assignSalesman(salesmanId, qrCodeId);
        }
    }

    @Override
    public void assignSalesman(Long salesmanId, Long qrCodeId) {
        // 二维码
        BsPayQrCode qrCode = getDetailById(qrCodeId);
        if (qrCode == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到二维码信息");
        }
        if (!qrCode.getStatus().equals(PayQrCodeStatusEnum.status1.getNumber())) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "二维码已被停用");
        }
        if (qrCode.getSalesmanId() != null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "二维码序列号为：" + qrCode.getSerialNumber() + "的二维码,无法分配，二维码已分配给其他业务员");
        }
        // 代理商
        BsSalesman salesman = salesmanService.getSalesman(salesmanId);
        if (salesman == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到业务员信息");
        }
        qrCode.setSalesmanId(salesman.getId());
        qrCode.setSalesmanName(salesman.getName());
        editData(qrCode, null);
    }

    @Override
    public void bindStore(Long storeId, Long qrCodeId) {
        // 二维码
        BsPayQrCode qrCode = getDetailById(qrCodeId);
        if (qrCode == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到二维码信息");
        }
        if (!qrCode.getStatus().equals(PayQrCodeStatusEnum.status1.getNumber())) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "二维码已被停用");
        }
        if (qrCode.getStoreId() != null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "二维码序列号为：" + qrCode.getSerialNumber() + "的二维码,无法分配，二维码已分配给其他门店");
        }

        // 查询门店
        BsStore store = storeService.getStoreById(storeId);
        if (store == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到门店信息");
        }

        // 查询商户
        BsMer mer = merService.getMer(store.getMerId());
        if (mer == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到商户信息");
        }

        qrCode.setSalesmanId(store.getSalesmanId());
        qrCode.setSalesmanName(store.getSalesmanName());
        qrCode.setStoreId(store.getId());
        qrCode.setStoreName(store.getName());
        qrCode.setStoreBindTime(new Date());
        qrCode.setMerId(mer.getId());
        qrCode.setMerName(mer.getMerName());
        editData(qrCode, null);
    }

    @Override
    public void unbindStore(Long qrCodeId) {
        // 二维码
        BsPayQrCode qrCode = getDetailById(qrCodeId);
        if (qrCode == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到二维码信息");
        }
        if (qrCode.getStoreId() == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "二维码序未绑定门店");
        }

        qrCode.setSalesmanId(null);
        qrCode.setSalesmanName(null);
        qrCode.setStoreId(null);
        qrCode.setStoreName(null);
        qrCode.setStoreBindTime(null);
        qrCode.setMerId(null);
        qrCode.setMerName(null);
        editData(qrCode, null);
    }

    @Override
    public void disabled(Long qrCodeId) {
        // 二维码
        BsPayQrCode qrCode = getDetailById(qrCodeId);
        if (qrCode == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到二维码信息");
        }
        if (!qrCode.getStatus().equals(PayQrCodeStatusEnum.status1.getNumber())) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "状态错误");
        }
        qrCode.setStatus(PayQrCodeStatusEnum.status2.getNumber());
        editData(qrCode, null);
    }

    @Override
    public void enable(Long qrCodeId) {
        // 二维码
        BsPayQrCode qrCode = getDetailById(qrCodeId);
        if (qrCode == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到二维码信息");
        }
        if (!qrCode.getStatus().equals(PayQrCodeStatusEnum.status2.getNumber())) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "状态错误");
        }
        qrCode.setStatus(PayQrCodeStatusEnum.status1.getNumber());
        editData(qrCode, null);
    }

    @Override
    public BsPayQrCode getDetailBySN(String serialNumber) {
        BsPayQrCodeExample example = new BsPayQrCodeExample();
        example.createCriteria().andSerialNumberEqualTo(serialNumber);
        List<BsPayQrCode> list = payQrCodeMapper.selectByExample(example);
        if (list.size() > 0) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public BsPayQrCode getDetailById(Long id) {
        return payQrCodeMapper.selectByPrimaryKey(id);
    }

    @Override
    public List<BsPayQrCode> getQrCodeList(Map<String, Object> param) {
        BsPayQrCodeExample example = new BsPayQrCodeExample();
        BsPayQrCodeExample.Criteria criteria = example.createCriteria()
                .andStatusNotEqualTo(PayQrCodeStatusEnum.status0.getNumber());

        if (MapUtils.getLong(param, "agentId") != null) {
            criteria.andAgentIdEqualTo(MapUtils.getLong(param, "agentId"));
        }

        if (MapUtils.getLong(param, "companyId") != null) {
            criteria.andCompanyIdEqualTo(MapUtils.getLong(param, "companyId"));
        }

        if (StringUtils.isNotBlank(MapUtils.getString(param, "agentName"))) {
            criteria.andAgentNameLike("%" + MapUtils.getString(param, "agentName") + "%");
        }

        if (MapUtils.getLong(param, "salesmanId") != null) {
            criteria.andSalesmanIdEqualTo(MapUtils.getLong(param, "salesmanId"));
        }

        if (StringUtils.isNotBlank(MapUtils.getString(param, "salesmanName"))) {
            criteria.andSalesmanNameLike("%" + MapUtils.getString(param, "salesmanName") + "%");
        }

        if (MapUtils.getLong(param, "merId") != null) {
            criteria.andMerIdEqualTo(MapUtils.getLong(param, "merId"));
        }

        if (StringUtils.isNotBlank(MapUtils.getString(param, "merName"))) {
            criteria.andMerNameLike("%" + MapUtils.getString(param, "merName") + "%");
        }

        if (MapUtils.getLong(param, "storeId") != null) {
            criteria.andStoreIdEqualTo(MapUtils.getLong(param, "storeId"));
        }

        if (StringUtils.isNotBlank(MapUtils.getString(param, "storeName"))) {
            criteria.andStoreNameLike("%" + MapUtils.getString(param, "storeName") + "%");
        }

        if (MapUtils.getInteger(param, "status") != null) {
            criteria.andStatusEqualTo(MapUtils.getInteger(param, "status"));
        }

        if (StringUtils.isNotBlank(MapUtils.getString(param, "serialNumber"))) {
            criteria.andSerialNumberLike("%" + MapUtils.getString(param, "serialNumber") + "%");
        }

        if (MapUtils.getBoolean(param, "isAssignCompany") != null) {
            // 是否已分配给门店
            if (MapUtils.getBoolean(param, "isAssignCompany") == true) {
                criteria.andCompanyIdIsNotNull();
            } else {
                criteria.andCompanyIdIsNull();
            }
        }

        if (MapUtils.getBoolean(param, "isAssignAgent") != null) {
            // 是否已分配给门店
            if (MapUtils.getBoolean(param, "isAssignAgent") == true) {
                criteria.andAgentIdIsNotNull();
            } else {
                criteria.andAgentIdIsNull();
            }
        }

        if (MapUtils.getBoolean(param, "isAssignSalesman") != null) {
            // 是否已分配给门店
            if (MapUtils.getBoolean(param, "isAssignSalesman") == true) {
                criteria.andSalesmanIdIsNotNull();
            } else {
                criteria.andSalesmanIdIsNull();
            }
        }

        if (MapUtils.getBoolean(param, "isAssignStore") != null) {
            // 是否已分配给门店
            if (MapUtils.getBoolean(param, "isAssignStore") == true) {
                criteria.andStoreIdIsNotNull();
            } else {
                criteria.andStoreIdIsNull();
            }
        }

        example.setOrderByClause("serial_number desc");
        return payQrCodeMapper.selectByExample(example);
    }
}
