package com.kiisoo.ic.employee.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.kiisoo.ic.department.entity.PrivilageCpUserDepartmentDO;
import com.kiisoo.ic.department.mapper.PrivilageCpUserDepartmentDOMapper;
import com.kiisoo.ic.employee.entity.EmployeeDO;
import com.kiisoo.ic.employee.entity.PrivilageCpUserDO;
import com.kiisoo.ic.employee.mapper.PrivilageCpUserDOMapper;
import com.kiisoo.ic.store.entity.PoiStore;
import com.kiisoo.ic.store.entity.PrivilageCpUserStoreDO;
import com.kiisoo.ic.store.mapper.PoiStoreDOMapper;
import com.kiisoo.ic.store.mapper.PrivilageCpUserStoreDOMapper;
import com.kiisoo.ic.wx.service.QWMailListManageService;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.cp.bean.WxCpUser;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.util.*;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import static com.kiisoo.ic.employee.constant.Constants.*;
import static java.util.regex.Pattern.*;

/**
 * @Description: 用户管理service
 * @Auther: yechenhao
 * @Date: 2020/4/7 0002 10:06
 * @Version: v1
 */
@Service
public class EmployeeService {

    @Autowired
    private QWMailListManageService qwMailListManageService;

    @Autowired
    private PrivilageCpUserDOMapper privilageCpUserDOMapper;

    @Autowired
    private PrivilageCpUserDepartmentDOMapper privilageCpUserDepartmentDOMapper;

    @Autowired
    private PrivilageCpUserStoreDOMapper privilageCpUserStoreDOMapper;

    @Autowired
    private PoiStoreDOMapper poiStoreDOMapper;

    /**
     * 查询成员
     *
     * @return
     * @throws WxErrorException
     */
    @Transactional(rollbackFor = Exception.class)
    public List<PrivilageCpUserDO> listUser() {
        QueryWrapper<PrivilageCpUserDO> params = new QueryWrapper<>();
        List<PrivilageCpUserDO> privilageCpUserDOS = privilageCpUserDOMapper.selectList(params);
        return privilageCpUserDOS;
    }


    /**
     * 新增成员
     *
     * @param employee 成员实体
     * @return
     * @throws WxErrorException
     */
    @Transactional(rollbackFor = Exception.class)
    public String addUser(EmployeeDO employee) throws Exception {
        //排重---根据企业微信账号查询是否存在用户
        QueryWrapper<PrivilageCpUserDO> cuUserIdParams = new QueryWrapper<>();
        cuUserIdParams.eq(DATABASE_CP_USER_ID_KEY, employee.getUserId());
        List<PrivilageCpUserDO> cuUserIdUser = privilageCpUserDOMapper.selectList(cuUserIdParams);

        //创建实体对象
        PrivilageCpUserDO privilageCpUserDO = new PrivilageCpUserDO();
        BeanUtils.copyProperties(employee, privilageCpUserDO);
        privilageCpUserDO.setCpUserId(employee.getUserId());

        //创建实体和店铺的关系对象
        PrivilageCpUserStoreDO cpUserStoreDO = new PrivilageCpUserStoreDO();
        PoiStore store = poiStoreDOMapper.selectShopByName(employee.getAlias());
        if (null == store) store = new PoiStore();
        cpUserStoreDO.setStoreId(store.getId());
        //是否存在账号
        if (CollectionUtils.isEmpty(cuUserIdUser)) {
            //不存在则创建账号
            privilageCpUserDO.setStatus(1);
            int insert = privilageCpUserDOMapper.insert(privilageCpUserDO);
            if (insert == 0) {
                throw new Exception("创建成员失败");
            }
            //绑定部门关系
            Long[] departIds = employee.getDepartIds();
/*
            Integer[] orders = employee.getOrders();
*/
            for (int i = 0; i < departIds.length; i++) {
                PrivilageCpUserDepartmentDO relation = new PrivilageCpUserDepartmentDO(privilageCpUserDO.getId(), departIds[i], null, null);
                privilageCpUserDepartmentDOMapper.insert(relation);
            }
            //插入账号-店铺关系
            cpUserStoreDO.setCpUserId(privilageCpUserDO.getId());
            privilageCpUserStoreDOMapper.insert(cpUserStoreDO);
            //成功则添加用户到企业微信
            qwMailListManageService.addUser(employee);

            //从企业微信通讯录反向更新（更新二维码信息）
            WxCpUser wxCpUser = qwMailListManageService.getUser(employee.getUserId());
            insertOrupdateUserFromNet(wxCpUser);

            return ADD_CP_CODE_SUCCESS;
        } else {
            Long cpUserId = cuUserIdUser.get(0).getId();
            //账号存在则查询是否已经绑定过店铺
            QueryWrapper<PrivilageCpUserStoreDO> cpStoreRationParams = new QueryWrapper<>();
            cpStoreRationParams.eq(DATABASE_CP_USER_ID_KEY, cpUserId);
            PrivilageCpUserStoreDO privilageCpUserStoreDO = privilageCpUserStoreDOMapper.selectOne(cpStoreRationParams);
            if (privilageCpUserStoreDO != null) {
                //绑定过店铺不做任何操作，返回已绑定码和绑定的店铺名，用&分割
                PoiStore poiStore = poiStoreDOMapper.selectById(privilageCpUserStoreDO.getStoreId());
                return ADD_CP_CODE_BINDED + "&" + poiStore.getName();
            }
            //账号未绑定店铺关系则绑定店铺关系
            cpUserStoreDO.setCpUserId(cuUserIdUser.get(0).getId());
            privilageCpUserStoreDOMapper.insert(cpUserStoreDO);
            return ADD_CP_CODE_BIND;
        }
    }

    /**
     * 从企业微信端获取的数据，插入或更新库中数据
     * @param wxCpUser 企业微信端用户对象
     * @throws Exception
     */
    @Transactional(rollbackFor = Exception.class)
    public void insertOrupdateUserFromNet(WxCpUser wxCpUser) throws Exception {
        QueryWrapper<PrivilageCpUserDO> cuUserIdParams = new QueryWrapper<>();
        cuUserIdParams.eq(DATABASE_CP_USER_ID_KEY, wxCpUser.getUserId());
        List<PrivilageCpUserDO> cuUserIdUser = privilageCpUserDOMapper.selectList(cuUserIdParams);

        PrivilageCpUserDO privilageCpUserDO = new PrivilageCpUserDO();
        BeanUtils.copyProperties(wxCpUser, privilageCpUserDO);
        privilageCpUserDO.setCpUserId(wxCpUser.getUserId());
        String alias = privilageCpUserDO.getAlias();
        alias = filterEmoji(alias);
        privilageCpUserDO.setAlias(alias);

        if (CollectionUtils.isEmpty(cuUserIdUser)) {
            //添加用户
            int insert = privilageCpUserDOMapper.insert(privilageCpUserDO);
        } else {
            privilageCpUserDO.setId(cuUserIdUser.get(0).getId());
            //修改用户
            int update = privilageCpUserDOMapper.updateById(privilageCpUserDO);
            //维护部门关系——删除原有部门关系
            QueryWrapper<PrivilageCpUserDepartmentDO> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq(DATABASE_CP_USER_ID_KEY, cuUserIdUser.get(0).getId());
            privilageCpUserDepartmentDOMapper.delete(queryWrapper);
        }
        Long[] departIds = wxCpUser.getDepartIds();
        Integer[] orders = wxCpUser.getOrders();
        Integer[] isLeaderInDept = wxCpUser.getIsLeaderInDept();

        for (int i = 0; i < departIds.length; i++) {
            PrivilageCpUserDepartmentDO relation = new PrivilageCpUserDepartmentDO(privilageCpUserDO.getId(), departIds[i], orders[i], isLeaderInDept[i]);
            privilageCpUserDepartmentDOMapper.insert(relation);
        }
    }

    /**
     * 同步成员
     *
     * @return
     * @throws WxErrorException
     */
    @Transactional(rollbackFor = Exception.class)
    public void syncUser() throws Exception {
        List<WxCpUser> wxCpUsers = qwMailListManageService.syncUser();
        if (CollectionUtils.isNotEmpty(wxCpUsers)) {
            wxCpUsers.forEach(wxCpUser -> {
                try {
                    insertOrupdateUserFromNet(wxCpUser);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
        }
    }

    public static String filterEmoji(String source) {
        if (source != null) {
            Pattern emoji = compile("[\ud83c\udc00-\ud83c\udfff]|[\ud83d\udc00-\ud83d\udfff]|[\u2600-\u27ff]", UNICODE_CASE | CASE_INSENSITIVE);
            Matcher emojiMatcher = emoji.matcher(source);
            if (emojiMatcher.find()) {
                source = emojiMatcher.replaceAll("*");
                return source;
            }
            return source;
        }
        return source;
    }

    /**
     * 修改成员
     *
     * @param employee 成员实体
     * @return
     * @throws WxErrorException
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateUser(EmployeeDO employee) throws Exception {
        PrivilageCpUserDO privilageCpUserDO = new PrivilageCpUserDO();
        BeanUtils.copyProperties(employee, privilageCpUserDO);
        privilageCpUserDO.setCpUserId(employee.getUserId());


        int update = privilageCpUserDOMapper.updateById(privilageCpUserDO);
        if (update == 0) {
            throw new Exception("修改成员失败");
        }

        //维护部门关系——删除原有部门关系
        QueryWrapper<PrivilageCpUserDepartmentDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(DATABASE_CP_USER_ID_KEY, privilageCpUserDO.getId());
        privilageCpUserDepartmentDOMapper.delete(queryWrapper);

        Long[] departIds = employee.getDepartIds();
        Integer[] orders = employee.getOrders();
        Integer[] isLeaderInDept = employee.getIsLeaderInDept();
        for (int i = 0; i < departIds.length; i++) {
            PrivilageCpUserDepartmentDO relation = new PrivilageCpUserDepartmentDO(privilageCpUserDO.getId(), departIds[i], orders[i], isLeaderInDept[i]);
            privilageCpUserDepartmentDOMapper.insert(relation);
        }

        //成功则添加用户到企业微信
        qwMailListManageService.updateUser(employee);
        return true;
    }

    /**
     * 删除成员
     *
     * @param cpUserId 成员id
     * @return
     * @throws WxErrorException
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteUser(Long cpUserId) throws Exception {
        PrivilageCpUserDO privilageCpUserDO = privilageCpUserDOMapper.selectById(cpUserId);
        if (privilageCpUserDO == null) {
            return false;
        }

        int delete = privilageCpUserDOMapper.deleteById(cpUserId);
        if (delete == 0) {
            throw new Exception("删除成员失败");
        }
        //维护部门关系——删除原有部门关系
        QueryWrapper<PrivilageCpUserDepartmentDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(DATABASE_CP_USER_ID_KEY, cpUserId);
        privilageCpUserDepartmentDOMapper.delete(queryWrapper);
        //删除用户和店铺的关系
        QueryWrapper<PrivilageCpUserStoreDO> storeDOQueryWrapper = new QueryWrapper<>();
        storeDOQueryWrapper.eq(DATABASE_CP_USER_ID_KEY, cpUserId);
        privilageCpUserStoreDOMapper.delete(storeDOQueryWrapper);
        //成功则添加用户到企业微信
        qwMailListManageService.deleteUser(privilageCpUserDO.getCpUserId());
        return true;
    }

    /**
     * 找到微信
     *
     * @param phone
     */
    public PrivilageCpUserDO getUserWX(String phone) {
        PrivilageCpUserDO privilageCpUserDO = new PrivilageCpUserDO();
        privilageCpUserDO.setMobile(phone);
        return privilageCpUserDOMapper.selectOne(new QueryWrapper<>(privilageCpUserDO));
    }

    /**
     * 下载员工二维码
     *
     * @param response
     * @throws WxErrorException
     * @throws IOException
     */
    public void downLoadQrCode(HttpServletResponse response) throws WxErrorException, IOException {
        List<WxCpUser> wxCpUsers = qwMailListManageService.syncUser();

        Map<String, String> stores = new HashMap<>();

        InputStreamReader br = new InputStreamReader(new FileInputStream(new File("G:\\kiisoo-ic\\src\\main\\resources\\store.txt")), "utf-8");

        BufferedReader reader = new BufferedReader(br);

        String str = null;

        //-----------------------------打印重复店铺---------------------start----------------------
        while ((str = reader.readLine()) != null) {
            String[] split = str.split(",");
            if (StringUtils.isNotBlank(split[1].trim()) && StringUtils.isNotBlank(split[0].trim())){
                if (stores.get(split[1].trim()) != null){
                    System.out.println(split[1].trim()+ "-"+ split[0].trim());
                    System.out.println(split[1].trim()+ "-" + stores.get(split[1].trim()));
                }else{
                    stores.put(split[1].trim(), split[0].trim());
                }

            }
        }
        //-----------------------------打印重复店铺--------------------end-----------------------


        byte[] buffer = new byte[1024];
        // 生成的ZIP文件名为Demo.zip
        String strZipName = "bsd_qr_code.zip";
        ZipOutputStream out = new ZipOutputStream(new FileOutputStream(strZipName));

        List<String> fileNames = new ArrayList<>();

        int count = wxCpUsers.size();
        //----------------------------打印绑定的店铺---------------------start-------------------
        for (int i = 0; i < count; i++) {
            WxCpUser wxCpUser = wxCpUsers.get(i);
            String url = wxCpUser.getQrCode();
            String code = wxCpUser.getAlias().trim();

            if (StringUtils.isBlank(code)) {
                continue;
            }
            String storeCode = stores.get(code);

            if (StringUtils.isBlank(storeCode)) {
                continue;
            }
            stores.remove(code);
            //下载图片
            BufferedInputStream in = new BufferedInputStream(getInputStream(url));
            //字节流转图片对象
            Image bi = ImageIO.read(in);
            //构建图片流
            BufferedImage tag = new BufferedImage(300, 300, BufferedImage.TYPE_INT_RGB);
            //绘制改变尺寸后的图
            tag.getGraphics().drawImage(bi, 0, 0, 300, 300, null);
            //输出流
            BufferedOutputStream Imgout = new BufferedOutputStream(new FileOutputStream(storeCode + ".png"));

            ImageIO.write(tag, "PNG", Imgout);

            FileInputStream newImgIn = new FileInputStream(new File(storeCode + ".png"));

            String fileName = storeCode + ".png";
            if (fileNames.contains(fileName)){
                fileName = storeCode + "-" + code + ".png";
            }
            fileNames.add(fileName);

            out.putNextEntry(new ZipEntry(fileName));
            int len;
            // 读入需要下载的文件的内容，打包到zip文件
            while ((len = newImgIn.read(buffer)) > 0) {
                out.write(buffer, 0, len);
            }
            out.closeEntry();
            in.close();
            Imgout.close();
            newImgIn.close();
        }
        //----------------------------打印绑定的店铺---------------------end-------------------
        out.flush();
        out.close();

        //----------------------------打印未绑定的店铺---------------------start-------------------
        Set<Map.Entry<String, String>> entries = stores.entrySet();
        for (Map.Entry<String, String> entry: entries){
            System.out.println(entry.getValue() + "-" + entry.getKey());
        }
        //----------------------------打印未绑定的店铺---------------------end-------------------

        //输入到response
        ServletOutputStream outputStream = response.getOutputStream();
        byte[] bufferNew = new byte[1024];
        FileInputStream inStream = new FileInputStream(new File(strZipName));
        int lenNew;
        while ((lenNew = inStream.read(bufferNew)) > 0) {
            outputStream.write(bufferNew, 0, lenNew);
        }

    }

    /**
     * 下载url文件
     *
     * @param fileUrl 文件url
     * @return
     */
    public InputStream getInputStream(String fileUrl) {

        URLConnection connection = null;
        try {
            connection = new URL(fileUrl).openConnection();
        } catch (IOException e) {
            e.printStackTrace();
        }
        InputStream inputStream = null;
        try {
            inputStream = connection.getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return inputStream;
    }

}
