package com.cftech.consultsheet.service.impl;


import com.alibaba.fastjson.JSONObject;
import com.cftech.accounts.model.MpAccountsEntity;
import com.cftech.accounts.service.MpAccountsService;
import com.cftech.base.codingrule.utils.CodingruleUtils;
import com.cftech.base.org.api.QyMediaUtil;
import com.cftech.base.org.api.QyMsgUtil;
import com.cftech.base.org.model.Qyuser;
import com.cftech.base.org.service.QyuserService;
import com.cftech.consultsheet.dao.ConsultSheetMapper;
import com.cftech.consultsheet.model.ConsultSheet;
import com.cftech.consultsheet.model.ConsultSheetDto;
import com.cftech.consultsheet.service.ConsultSheetService;
import com.cftech.core.generic.GenericDao;
import com.cftech.core.generic.GenericServiceImpl;
import com.cftech.core.scope.OrderType;
import com.cftech.core.sql.Conds;
import com.cftech.core.sql.Sort;
import com.cftech.core.util.Constants;
import com.cftech.core.util.MpTokenUtil;
import com.cftech.core.util.StringUtils;
import com.cftech.core.util.SystemConfig;
import com.cftech.member.service.MemberService;
import com.cftech.order.model.Order;
import com.cftech.order.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 咨询单ServiceImpl
 *
 * @author Licc
 * @date: 2020-09-22 12:06
 */
@Slf4j
@Service("consultSheetService")
public class ConsultSheetServiceImpl extends GenericServiceImpl<ConsultSheet> implements ConsultSheetService {

    @Autowired
    @Qualifier("consultSheetMapper")
    private ConsultSheetMapper consultSheetMapper;

    @Autowired
    private MpAccountsService mpAccountsService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private MemberService memberService;

    @Autowired
    private QyuserService qyuserService;

    @Autowired
    private CodingruleUtils codingruleUtils;

    @Autowired
    private MpTokenUtil mpTokenUtil;

    @Autowired
    private QyMediaUtil mediaUtil;

    @Autowired
    private QyMsgUtil qyMsgUtil;

    static final String[] arr = new String[]{"1", "2"};

    @Override
    public GenericDao<ConsultSheet> getGenericMapper() {
        return consultSheetMapper;
    }


    @Override
    public Integer updateDate(Long consultId, String status, String description) {
        return consultSheetMapper.updateDate(consultId, status, description);
    }

    @Override
    public Integer updateStatus(Long consultId, String status, String des) {
       return consultSheetMapper.updateStatus(consultId, status, des);
    }

    @Override
    public Integer fetchSearchByCount(Conds conds, Long id) {
        Map<String, Object> params = new HashMap<>();
        params.put("conds", conds);
        if (id != null && id != 1) {
            params.put("id", id);
        }
        return consultSheetMapper.fetchSearchByCount(params);
    }

    @Override
    public List<ConsultSheet> fetchSearchBy(Conds conds, Sort sort, int page, int pageSize, Long id) {
        Map<String, Object> params = new HashMap<>();
        params.put("conds", conds);
        params.put("offset", page > 0 ? page : 0);
        params.put("limit", pageSize > 0 ? pageSize : 0);
        params.put("sort", sort);
        if (id != null && id != 1) {
            params.put("id", id);
        }
        return consultSheetMapper.fetchSearchByPage(params);
    }

    @Override
    public JSONObject pollingConsultSheet(ConsultSheet consultSheet) {
        JSONObject retObj = new JSONObject();
        try {
            MpAccountsEntity mpAccountsEntity = mpAccountsService.getMpAccountsAppid(consultSheet.getAppId());
            consultSheet.setConsultId(codingruleUtils.getNumber(consultSheet.getAccountsId(), ConsultSheet.class.getName()));

            //处理处方单图片
            if (StringUtils.isNoneBlank(consultSheet.getPrescription())) {
                if (!consultSheet.getPrescription().contains("http")) {
                    String fileName = mediaUtil.downloadMpMediaToDisk(mpAccountsEntity.getId(), "consultSheet", consultSheet.getPrescription());
                    String url = SystemConfig.p.getProperty("QY_DOMAIN") + SystemConfig.p.getProperty("IMAGEURL").replace("{PICFILENAME}", fileName);
                    consultSheet.setPrescription(url);
                }
            }
            consultSheet.setAccountsId(mpAccountsEntity.getId());

            if (consultSheetMapper.save(consultSheet) > 0) {
                memberProcess(consultSheet.getOpenId(), consultSheet);

                //展示客服二维码
                Qyuser serviceCus = qyuserService.fetchById(consultSheet.getServiceId());
                retObj.put("errorNo", 0);
                retObj.put("data", serviceCus.getDescription());
                retObj.put("errorMsg", "咨询单提交成功，请等待药师审核");
            } else {
                retObj.put("errorNo", 1);
                retObj.put("errorMsg", "咨询单保存失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            retObj.put("errorNo", 1);
            retObj.put("errorMsg", "提交咨询单" + e.getMessage());
        }
        return retObj;
    }

    @Override
    public JSONObject consultSheetList(ConsultSheetDto consultSheetDto) {
        JSONObject rtnJson = new JSONObject();
        try {
            MpAccountsEntity mpAccountsAppid = mpAccountsService.getMpAccountsAppid(consultSheetDto.getAppId());
            List<ConsultSheet> consultSheets = consultSheetMapper.consultSheetList(consultSheetDto);
            if (consultSheets != null) {
                rtnJson.put("errorNo", 0);
                rtnJson.put("data", consultSheets);
            } else {
                rtnJson.put("errorNo", 1);
                rtnJson.put("errorMsg", "搜索失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            rtnJson.put("errorNo", 1);
            rtnJson.put("errorMsg", "咨询单列表" + e.getMessage());
        }
        return rtnJson;
    }

    /**
     * 咨询单分配流程
     * 复购/首次分配
     *
     * @return
     */
    private boolean memberProcess(String openid, ConsultSheet consultSheet) {
        //1、查询用户是否复购
        Conds conds = new Conds();
        conds.equal("o.del_flag", Constants.DEL_FLAG_0);
        conds.equal("o.openid", openid);
        conds.in("o.status", new String[]{"4"});// 4:已成交
        Sort sort = new Sort("o.create_time", OrderType.DESC);
        List<Order> orders = orderService.fetchSearchBy(conds, sort, 0, 0, null);
        if (orders != null && orders.size() > 0 && orders.get(0) != null) { //复购
            Order order = orders.get(0);

            Conds userConds = new Conds();
            userConds.equal("t.del_flag", Constants.DEL_FLAG_0);
            userConds.equal("t.id", order.getServiceId());
            Qyuser user = qyuserService.fetchSearchByConds(userConds);
            if (user.getPeakVal() > 0) {//客服峰值大于0
                consultSheet.setServiceId(user.getId());
                //推送消息
            } else {//普通轮询
                firstCustomerProcess(consultSheet);
                return true;
            }

            Conds docConds = new Conds();
            docConds.equal("t.del_flag", Constants.DEL_FLAG_0);
            docConds.equal("t.id", order.getDoctorId());
            user = qyuserService.fetchSearchByConds(docConds);
            if (user.getPeakVal() > 0) {//药师峰值大于0
                consultSheet.setDoctorId(user.getId());
            } else {//普通轮询
                firstCustomerProcess(consultSheet);
                return true;
            }
        } else {//首次购买
            firstCustomerProcess(consultSheet);
            return true;
        }

        if (consultSheetMapper.update(consultSheet) > 0) {
            //推送客服,药师
            sendQyWechatMassage(consultSheet);
            return true;
        }
        return false;
    }

    /**
     * 咨询单首次购买流程
     *
     * @return
     */
    private boolean firstCustomerProcess(ConsultSheet consultSheet) {
        first:
        for (int i = 0, y = arr.length; i < y; i++) {

            Conds conds = new Conds();
            conds.equal("t.del_flag", Constants.DEL_FLAG_0);
            conds.equal("t.user_type", arr[i]);//1:药师; 2:客服
            conds.greatThan("t.peak_val", 0);
            Sort sort = new Sort("t.assigned", OrderType.ASC);//峰值未满
            List<Qyuser> users = qyuserService.fetchSearchByPage(conds, sort, 0, 0);
            if (users.size() == 1) {
                if (arr[i].equals("2")) {
                    consultSheet.setServiceId(users.get(0).getId());
                } else {
                    consultSheet.setDoctorId(users.get(0).getId());
                }

                if (users.get(0).getPeakVal() > users.get(0).getAssigned()) {//峰值未满
                    users.get(0).setAssigned(users.get(0).getAssigned() + 1);
                    qyuserService.updateAssigned(users.get(0));
                } else {//峰值已满
                    users.get(0).setUnAssigned(users.get(0).getAssigned() + 1);
                    qyuserService.updateAssigned(users.get(0));
                }
            } else if (users.size() > 1) {
                //当前分配
                second:
                for (Qyuser user : users) {
                    if (user.getPeakVal() > user.getAssigned()) {//峰值未满

                        if (arr[i].equals("2")) {
                            consultSheet.setServiceId(user.getId());
                        } else {
                            consultSheet.setDoctorId(user.getId());
                        }

                        //增加分配人数
                        user.setAssigned(user.getAssigned() + 1);
                        qyuserService.updateAssigned(user);
                        break first;
                    }
                }

                //峰值已满
                if (consultSheet.getServiceId() == null) {
                    Conds unconds = new Conds();
                    unconds.equal("t.del_flag", Constants.DEL_FLAG_0);
                    unconds.equal("t.user_type", arr[i]);
                    Sort unsort = new Sort("t.un_assigned", OrderType.ASC);
                    users = qyuserService.fetchSearchByPage(conds, unsort, 0, 0);
                    if (users.size() > 0) {
                        Qyuser user = users.get(0);

                        if (arr[i].equals("2")) {
                            consultSheet.setServiceId(user.getId());
                        } else {
                            consultSheet.setDoctorId(user.getId());
                        }

                        //增加分配人数
                        user.setUnAssigned(user.getAssigned() + 1);
                        qyuserService.updateAssigned(user);
                    } else {
                        consultSheet.setIllness((arr[i].equals("1") ? "客服" : "药师") + "未有对应的咨询单处理人员");
                    }
                }
            } else {
                consultSheet.setIllness((arr[i].equals("1") ? "客服" : "药师") + "未有对应的咨询单处理人员");
            }
        }
        if (consultSheetMapper.update(consultSheet) > 0) {
            //推送客服,药师
            sendQyWechatMassage(consultSheet);
            return true;
        }
        return true;
    }

    /**
     * 推送企业微信消息
     */
    public void sendQyWechatMassage(ConsultSheet consultSheet) {
        Long accounts = Long.parseLong(SystemConfig.p.getProperty("QY_SEND_APPID"));
        MpAccountsEntity accountsEntity = mpAccountsService.getDetail(accounts);
        Long agenId = Long.parseLong(accountsEntity.getAgentId());

        //推送客服消息
        String msg = null;
        Qyuser service = qyuserService.fetchById(consultSheet.getServiceId());
        msg = SystemConfig.p.getProperty("QY_SEND_CUSTOMERSERVICE_MSG") + consultSheet.getConsultId();
        List<Qyuser> serviceUsers = new ArrayList();
        serviceUsers.add(service);
        JSONObject result = qyMsgUtil.sendText(accounts, false, serviceUsers, null, null,
                agenId, msg, false);
        log.info("客服，消息发送日志 {}", result.toString());

        Qyuser doctor = qyuserService.fetchById(consultSheet.getDoctorId());
        msg = SystemConfig.p.getProperty("QY_SEND_DOCTOR_MSG") + consultSheet.getConsultId();
        List<Qyuser> doctorUsers = new ArrayList();
        doctorUsers.add(doctor);
        qyMsgUtil.sendText(accounts, false, doctorUsers, null, null,
                agenId, msg, false);
        log.info("医生，消息发送日志 {}", result.toString());
    }

}