package com.uas.platform.b2b.publicapi.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.uas.platform.b2b.core.util.ThreadUtils;
import com.uas.platform.b2b.dao.CommonDao;
import com.uas.platform.b2b.dao.InvitationRecordDao;
import com.uas.platform.b2b.dao.UserDao;
import com.uas.platform.b2b.model.Enterprise;
import com.uas.platform.b2b.model.EnterpriseBaseInfo;
import com.uas.platform.b2b.model.InvitationRecord;
import com.uas.platform.b2b.model.User;
import com.uas.platform.b2b.service.EnterpriseService;
import com.uas.platform.b2b.service.InvitationRecordService;
import com.uas.platform.b2b.service.UserService;
import com.uas.platform.b2b.support.MessageConf;
import com.uas.platform.b2b.support.SendMsgUtils;
import com.uas.platform.b2b.publicapi.model.Invitation;
import com.uas.platform.b2b.publicapi.service.InviteRecordService;
import com.uas.platform.core.exception.IllegalOperatorException;
import com.uas.platform.core.exception.NotFoundException;
import com.uas.platform.core.model.Constant;
import com.uas.search.b2b.model.PageParams;
import com.uas.search.b2b.model.SPage;
import com.uas.sso.entity.PartnershipRecordView;
import com.uas.sso.util.AccountUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.ui.ModelMap;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

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

/**
 * Created by hejq on 2018-03-22.
 */
@Service
public class InviteRecordServiceImpl implements InviteRecordService {

    @Autowired
    private EnterpriseService enterpriseService;

    @Autowired
    private InvitationRecordService invitationRecordService;

    @Autowired
    private CommonDao commonDao;

    @Autowired
    private UserService userService;

    @Autowired
    private InvitationRecordDao invitationRecordDao;

    @Autowired
    private MessageConf messageConf;

    @Autowired
    private UserDao userDao;

    /**
     * 通过填写的名称检验企业是否已注册
     *
     * @param name 输入的企业名称
     * @return
     */
    @Override
    public List<EnterpriseBaseInfo> checkByName(String name) {
        List<EnterpriseBaseInfo> baseInfoList = new ArrayList<EnterpriseBaseInfo>();
        List<Enterprise> enterprises = enterpriseService.findByEnName(name);
        if (!CollectionUtils.isEmpty(enterprises)) {
            for (Enterprise e : enterprises) {
                EnterpriseBaseInfo baseInfo = new EnterpriseBaseInfo(e);
                User user = userService.findUserByUserUU(e.getEnAdminuu());
                if (null != user) {
                    baseInfo.setAdminName(user.getUserName());
                    baseInfo.setEnTel(user.getUserTel());
                }
                if (null != e.getInviteUU()) {
                    Enterprise enterprise = enterpriseService.findByEnUU(e.getInviteUU());
                    String enName = enterprise != null ? enterprise.getEnName() : null;
                    baseInfo.setInviteEnName(enName);
                }
                if (null != e.getInviteUserUU()) {
                    User u = userDao.findOne(e.getInviteUserUU());
                    baseInfo.setInviteUserName(u.getUserName());
                }
                baseInfoList.add(baseInfo);
            }
        }
        return baseInfoList;
    }

    /**
     * 获取邀请记录
     *
     * @param params 分页参数
     * @param keyword 搜索关键词
     * @param enUU 企业UU
     * @param userUU 用户UU
     * @return
     */
    @Override
    public SPage<InvitationRecord> getInviteRecords(Long enUU, Long userUU, PageParams params, String keyword) {
        return invitationRecordService.getRecords(params, keyword);
    }

    /**
     * 分类获取邀请数量
     *
     * @param userUU 用户UU
     * @param enUU   企业UU
     * @return
     */
    @Override
    public ModelMap getInvationCount(Long userUU, Long enUU) {
        ModelMap map = new ModelMap();
        String allSql = "select COALESCE(sum(count), 0) from v$invitation where useruu = " + userUU;
        String todoSql = "select COALESCE(sum(count), 0) from v$invitation where active = 0 and useruu = " + userUU;
        String doneSql = "select COALESCE(sum(count), 0) from v$invitation where active = 1 and useruu = " + userUU;
        Integer allNum = commonDao.queryForObject(allSql, Integer.class);
        Integer todoNum = commonDao.queryForObject(todoSql, Integer.class);
        Integer doneNum = commonDao.queryForObject(doneSql, Integer.class);
        map.put("all", allNum);
        map.put("todo", todoNum);
        map.put("done", doneNum);
        return map;
    }

    /**
     * 分月获取邀请数量
     *
     * @param userUU 用户UU
     * @param enUU   企业UU
     * @param year   年份
     * @return
     */
    @Override
    public List<Invitation> getCountGroupByDate(Long userUU, Long enUU, String year) {
        String sql = "select substr(time, -2) month, time, in_enuu enUU,count(1) count from(" +
                "select to_char(in_date, 'yyyy-mm') time,COALESCE(in_active,0),in_enuu from invitationrecords where in_enuu = " + enUU + ")" +
                "where time like '%" + year + "%' group by time,in_enuu order by time";
        List<Invitation> all = commonDao.query(sql, Invitation.class);
        String sql1 = "select substr(time, -2) month, time ,in_enuu enUU,count(1) doneCount from(" +
                "select to_char(in_date, 'yyyy-mm') time,COALESCE(in_active,0),in_enuu from invitationrecords where in_enuu = " + enUU + " and COALESCE(in_active,0) = 1)" +
                "where time like '%" + year + "%' group by time,in_enuu order by time";
        List<Invitation> done = commonDao.query(sql1, Invitation.class);
        if (!CollectionUtils.isEmpty(all) && !CollectionUtils.isEmpty(done)) {
            for (Invitation a : all) {
                for (Invitation d : done) {
                    if (a.getTime().equals(d.getTime())) {
                        a.setDoneCount(d.getDoneCount());
                    }
                }
            }
        }
        return all;
    }

    /**
     * 添加合作伙伴
     *
     * @param userUU         用户UU
     * @param enUU           企业UU
     * @param inviteEnUU     邀请企业的UU
     * @param inviteUserName 邀请的用户的姓名
     * @param inviteUserTel  邀请的用户的联系方式
     * @param app            应用
     * @return
     */
    @Override
    public ModelMap addPartner(Long userUU, Long enUU, Long inviteEnUU, String inviteUserName, String inviteUserTel, String app) throws Exception {
        ModelMap map = new ModelMap();
        PartnershipRecordView record = new PartnershipRecordView();
        Enterprise c = enterpriseService.findByEnUU(inviteEnUU);
        if (null == c) {
            throw new IllegalOperatorException("添加合作伙伴的企业未注册");
        }
        record.setCustName(c.getEnName());
        record.setCustUID(c.getEnBussinessCode());
        String adnimTel = null;
        User user = new User();
        if (null != c.getEnAdminuu()) {
            user = userService.findUserByUserUU(c.getEnAdminuu());
            if (null != user) {
                record.setCustUserCode(user.getUserUU());
                record.setCustUserEmail(user.getUserEmail());
                record.setCustUserName(user.getUserName());
                record.setCustUserTel(user.getUserTel());
                adnimTel = user.getUserTel();
            }
        }
        Enterprise v = enterpriseService.findByEnUU(enUU);
        if (null == v) {
            throw new NotFoundException(enUU + "对应企业未注册");
        }
        record.setVendName(v.getEnName());
        record.setVendUID(v.getEnBussinessCode());
        record.setAppId(app);
        record.setVendUserCode(userUU);
        User vu = userService.findUserByUserUU(userUU);
        if (null != vu) {
            record.setVendUserEmail(vu.getUserEmail());
            record.setVendUserName(vu.getUserName());
            record.setVendUserTel(vu.getUserTel());
        }
        String contactTel = null;
        User cu = new User();
        if (!StringUtils.isEmpty(inviteUserTel)) {
            List<User> users = userDao.findUserByUserTel(inviteUserTel);
            if (!CollectionUtils.isEmpty(users)) {
                cu = users.get(0);
                String userName = StringUtils.isEmpty(inviteUserName) ? cu.getUserName() : inviteUserName;
                record.setCustUserCode(cu.getUserUU());
                record.setCustUserEmail(cu.getUserEmail());
                record.setCustUserName(userName);
                record.setCustUserTel(cu.getUserTel());
                contactTel = cu.getUserTel();
            }
        }
        final String enName = v.getEnName();
        final String contactTel1 = contactTel;
        final String adminTel1 = adnimTel;
        // 发送短信通知
        if (adnimTel.equals(contactTel)) {// 相同的人调用通知接口
            ThreadUtils.task(new Runnable() {
                @Override
                public void run() {
                    try {
                        // 发送给管理员
                        sendMsgToManager(enName, adminTel1);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }).run();

        } else { // 针对不同的人调用不同的接口
            ThreadUtils.task(new Runnable() {
                @Override
                public void run() {
                    try {
                        // 发送给管理员
                        sendMsgToManager(enName, adminTel1);

                        // 发送给联系人
                        sendMsgToManager(enName, contactTel1);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }).run();
        }
        String result = AccountUtils.addNewRecord(record);
        JSONObject object = JSON.parseObject(result);
        String errorMsg = object.getString("error");
        if (!StringUtils.isEmpty(errorMsg)) {
            throw new IllegalOperatorException(errorMsg);
        } else {
            map.put("success", object.getString("success"));
        }
        return map;
    }

    /**
     * 发送短信通知管理员
     *
     * @param enName 邀请企业
     * @param adnimTel 管理员联系方式
     */
    private void sendMsgToManager(final String enName, final String adnimTel) {
        String[] args = {enName};
        SendMsgUtils.sendMsg(adnimTel, messageConf.getMsgInvitationForB2B(), args);
    }

    /**
     * 增加注册记录
     *
     * @param record 注册记录
     * @return
     */
    @Override
    public ModelMap invite(InvitationRecord record) {
        if (StringUtils.isEmpty(record.getUseruu()) || StringUtils.isEmpty(record.getEnuu())) {
            throw new IllegalOperatorException("邀请人或企业不能为空");
        }
        User custUser = userService.findUserByUserUU(record.getUseruu());
        if (StringUtils.isEmpty(custUser)) {
            throw new IllegalOperatorException(record.getUseruu() + ",不存在邀请人信息");
        }
        final Enterprise custEn = enterpriseService.findByEnUU(record.getEnuu());
        if (StringUtils.isEmpty(custEn)) {
            throw new IllegalOperatorException(record.getEnuu() + ",不存在邀请企业信息");
        }
        ModelMap map = new ModelMap();
        List<Enterprise> enterprises = enterpriseService.findByEnName(record.getVendname());
        if (!CollectionUtils.isEmpty(enterprises)) {
           throw new IllegalOperatorException(record.getVendname() + "已注册!");
        }
        // 先判断记录
        InvitationRecord oldrecord = invitationRecordDao.findByUseruuAndVendname(record.getUseruu(), record.getVendname());
        if (record.getId() != null) { // 如果是已存在的，直接替换
            oldrecord = invitationRecordDao.findOne(record.getId());
        }
        if (oldrecord != null) {
            oldrecord.setCount(oldrecord.getCount() + 1);
            oldrecord.setDate(new Date());
            if (record.getVendname() != null) {
                oldrecord.setVendname(record.getVendname());
            }
            if (record.getVendusername() != null) {
                oldrecord.setVendusername(record.getVendusername());
            }
            if (record.getVendusertel() != null) {
                oldrecord.setVendusertel(record.getVendusertel().trim());
            }
            if (record.getVenduseremail() != null) {
                oldrecord.setVenduseremail(record.getVenduseremail().trim());
            }
            record = invitationRecordDao.save(oldrecord);
            if (oldrecord.getVendusertel() != null) {
                sendMsg(record, custUser, custEn);
            }
            map.put("success", "邀请已发送");
        } else {
            record.setCount(1);
            record.setDate(new Date(System.currentTimeMillis()));
            record.setActive(Constant.NO);
            record = invitationRecordDao.save(record);
            if (record.getVendusertel() != null) {
                sendMsg(record, custUser, custEn);
            }
            if (record.getId() != null) {
                map.put("success", "邀请已发送");
            } else {
                throw new IllegalOperatorException("邀请发送失败");
            }
        }
        invitationRecordService.syncToAccount(record, custEn.getEnBussinessCode());
        return map;
    }

    /**
     * 发送短信
     * @param record 邀请记录
     * @param custUser 当前用户
     * @param custEn 当前企业
     */
    private void sendMsg(final InvitationRecord record, final User custUser, final Enterprise custEn) {
        String[] args = {record.getVendusername(), record.getVendname(), custUser.getUserName() + "(" + custEn.getEnName() + ")"};
        SendMsgUtils.sendMsg(record.getVendusertel(), messageConf.getMsgInvitationForB2B(), args);
    }

    /**
     * 批量邀请注册
     *
     * @param enUU    企业UU
     * @param userUU  用户UU
     * @param records 邀请记录
     * @param source 数据来源
     * @return
     */
    @Override
    public ModelMap inviteByBatch(Long enUU, Long userUU, List<InvitationRecord> records, String source) {
        ModelMap map = new ModelMap();
        Enterprise ve = enterpriseService.findByEnUU(enUU);
        int size = 0;
        int fsize = 0;
        StringBuffer successStr = new StringBuffer();
        StringBuffer failStr = new StringBuffer();
        if (null == ve) {
            throw new IllegalOperatorException(enUU + "对应的企业不存在！");
        }
        User vu = userDao.findOne(userUU);
        if (null == vu) {
            throw new IllegalOperatorException(userUU + "对应的用户不存在！");
        }
        for (InvitationRecord record : records) {
            List<Enterprise> enterprises = enterpriseService.findByEnName(record.getVendname());
            if (!CollectionUtils.isEmpty(enterprises)) {
                throw new IllegalOperatorException(record.getVendname() + "已注册！");
            }
            record.setDate(new Date(System.currentTimeMillis()));
            record.setBussinesscode(ve.getEnBussinessCode());
            record.setUseruu(userUU);
            record.setActive(Constant.NO);
            record.setSource(source);
            record.setEnuu(enUU);
            try {
                invite(record);
                // 发送邮件
                if (null != record.getVenduseremail() && record.getVenduseremail().contains("@")) {
                    invitationRecordService.sendEmail(record);
                }
                size++;
                if (successStr.length() > 0) {
                    successStr.append(";");
                }
                successStr.append(record.getVendname());
            } catch (Exception e) {
                fsize++;
                if (failStr.length() > 0) {
                    failStr.append(";");
                }
                failStr.append(record.getVendname());
            }
        }
        if (size > 0) {
            map.put("success", "发送成" + size + "条，" + successStr + "发送成功");
        }
        if (fsize > 0) {
            map.put("error", "发送失败" + fsize + "条，" + failStr + "发送失败");
        }
        return map;
    }

    /**
     * 更新邀请注册记录企业信息
     *
     * @param e 企业信息
     */
    @Override
    public void updateVendName(EnterpriseBaseInfo e) {
        List<InvitationRecord> recordList = invitationRecordService.findByVendUU(e.getUu());
        if (!CollectionUtils.isEmpty(recordList)) {
            for (InvitationRecord record : recordList) {
                record.setVendname(e.getEnName());
            }
            invitationRecordDao.save(recordList);
        }
    }
}
