package com.zcloud.service.bus.impl;

import com.alibaba.fastjson.JSONObject;
import com.zcloud.entity.PageData;
import com.zcloud.mapper.dsno2.corp.CorpPlsInfoMapper;
import com.zcloud.service.bus.CorpPlsInfoService;
import com.zcloud.service.system.DepartmentService;
import com.zcloud.service.system.OfficeService;
import com.zcloud.service.system.UsersService;
import com.zcloud.util.AsyncPlsUserTask;
import com.zcloud.util.PLSUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

/**
 * 说明：企业类型主管部门
 * 作者：shaojie
 * 时间：2021-03-18
 * 官网：www.qdkjchina.com
 */
@Service
@Transactional //开启事物
public class CorpPlsInfoServiceImpl implements CorpPlsInfoService {

    @Autowired
    private CorpPlsInfoMapper corpplsinfoMapper;
    @Autowired
    private DepartmentService departmentService;
    @Autowired
    private OfficeService officeService;
    @Autowired
    private UsersService usersService;

    /**
     * 新增
     *
     * @param pd
     * @throws Exception
     */
    public void saveOrUpdate(PageData pd) throws Exception {
        PageData p = findById(pd);
        if (p != null) {
            corpplsinfoMapper.edit(pd);
            return;
        }
        corpplsinfoMapper.save(pd);
    }

    /**
     * 通过id获取数据
     *
     * @param pd
     * @throws Exception
     */
    public PageData findById(PageData pd) throws Exception {
        return corpplsinfoMapper.findById(pd);
    }

    @Override
    public PageData getDeptIdandempId(PageData user) {
        return corpplsinfoMapper.getDeptIdandempId(user);
    }

    @Override
    public void asyncPLSInfo(PageData pd) throws Exception {
        if (pd.get("enterpriseId") == null) {
            pd.put("enterpriseName", pd.getString("CORP_NAME"));
            JSONObject body = PLSUtil.GeneralPost(pd.getString("POST_URL"),
                    "/deploy/enterprise/addDepEnterprise", pd, pd.get("CORPINFO_ID").toString());
            if (body != null && "200".equals(body.getString("code"))) {
                pd.put("enterpriseId", body.getString("data"));
            } else {
                throw new RuntimeException("远程调用失败");
            }
        }

        List<PageData> deptList = departmentService.listAll(pd).stream().filter(dept -> dept.get("deptId") == null).collect(Collectors.toList());
        deptList.forEach(dept -> {
            try {
                dept.put("deptName", dept.getString("NAME"));
                dept.put("enterpriseId", pd.get("enterpriseId"));
                asyncDept(dept, pd.getString("POST_URL"), pd.get("CORPINFO_ID").toString());
            } catch (Exception e) {
                throw new RuntimeException("远程调用失败");
            }
        });
        departmentService.batchUpdate(deptList);

        List<PageData> officeList = officeService.listAll(pd);
        List<PageData> usersList = usersService.listAll(pd).stream().filter(
                user -> user.get("PLS_ID") == null && !"1".equals(user.getString("ISMAIN"))).collect(Collectors.toList());
        officeList.forEach(office -> {
            try {
                asyncOffice(office, pd.getString("POST_URL"), pd.get("CORPINFO_ID").toString());
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException("远程调用失败");
            }
        });

        CountDownLatch latch = new CountDownLatch(usersList.size());
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        usersList.forEach(user -> {
            try {
                user.put("empId", pd.get("enterpriseId"));
                Optional<PageData> optionalDept = deptList.stream().filter(dept -> dept.getString("DEPARTMENT_ID").equals(user.getString("DEPARTMENT_ID"))).findFirst();
                if (optionalDept.isPresent()) {
                    PageData dept = optionalDept.get();
                    user.put("deptId", dept.getString("deptId"));
                }
                Optional<PageData> optionalOffice = officeList.stream().filter(office -> office.getString("WORK_NAME").equals(user.getString("WORK_NAME")) && office.getString("CORPINFO_ID").equals(user.getString("CORPINFO_ID"))).findFirst();
                if (optionalOffice.isPresent()) {
                    PageData office = optionalOffice.get();
                    user.put("office", office.getString("WORK_ID"));
                    user.put("officeName", office.getString("WORK_NAME"));
                }
                executorService.execute(new AsyncPlsUserTask(user, pd.getString("POST_URL"), pd.get("CORPINFO_ID").toString(), latch));
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });

        latch.await();
        executorService.shutdown();
        if (!usersList.isEmpty())
            usersService.batchUpdate(usersList);
    }

    private void asyncDept(PageData dept, String url, String corpId) throws Exception {
        JSONObject body = PLSUtil.GeneralPost(url, "/deploy/dept", dept, corpId);
        if (body != null && "200".equals(body.getString("code"))) {
            dept.put("deptId", body.getString("data"));
        } else {
            throw new RuntimeException("远程调用失败");
        }
    }

    private void asyncOffice(PageData office, String url, String corpId) throws Exception {
        office.put("thumbnail", office.getString("THUMBNAIL"));
        office.put("remark", office.getString("REMARK"));
        office.put("status", office.getString("STATUS"));
        office.put("officeName", office.getString("WORK_NAME"));
        office.put("isCar", 0);
        JSONObject body = PLSUtil.GeneralPost(url, "/deploy/office", office, corpId);
        if (body != null && "200".equals(body.getString("code"))) {
            office.put("WORK_ID", body.getString("data"));
            officeService.edit(office);
        }
    }

    @Override
    public void editToken(PageData pd) {
        corpplsinfoMapper.edit(pd);
    }
}

