package com.github.wxiaoqi.security.admin.biz;

import com.github.wxiaoqi.security.admin.dto.AppShareholderDetailDTO;
import com.github.wxiaoqi.security.admin.dto.AppShareholderDetailFindDTO;
import com.github.wxiaoqi.security.admin.entity.AppShareholderDetail;
import com.github.wxiaoqi.security.admin.entity.AppUserDetail;
import com.github.wxiaoqi.security.admin.entity.AppUserLogin;
import com.github.wxiaoqi.security.admin.entity.AppUserPosition;
import com.github.wxiaoqi.security.admin.mapper.AppShareholderDetailMapper;
import com.github.wxiaoqi.security.admin.vo.AppShareholderDetailVo;
import com.github.wxiaoqi.security.common.biz.BaseBiz;
import com.github.wxiaoqi.security.common.exception.BaseException;
import com.github.wxiaoqi.security.common.msg.ObjectRestResponse;
import com.github.wxiaoqi.security.common.util.process.ResultCode;
import com.github.wxiaoqi.security.common.vo.PageDataVO;
import com.google.common.collect.Lists;
import com.xxfc.platform.vehicle.common.RestResponse;
import com.xxfc.platform.vehicle.entity.BranchCompany;
import com.xxfc.platform.vehicle.feign.VehicleFeign;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.bouncycastle.jcajce.provider.asymmetric.ec.KeyFactorySpi;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;


@Slf4j
@Transactional
@Service("appShareholderDetailBiz")
public class AppShareholderDetailBiz extends BaseBiz<AppShareholderDetailMapper, AppShareholderDetail> {

    @Autowired
    private VehicleFeign vehicleFeign;

    @Autowired
    private AppUserDetailBiz detailBiz;

    @Autowired
    private AppUserLoginBiz loginBiz;

    @Autowired
    private AppUserPositionBiz appUserPositionBiz;

    @Autowired
    private AppShareholderDetailChangeRecordBiz appShareholderDetailChangeRecordBiz;

    @Autowired
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;


    public static int HEADQUARTERS_SHAREHOLDER = 1;

    public static int BRANCH_HEADQUARTERS_SHAREHOLDER = 2;

    public static int SHAREHOLDERDE_IS_TRUE = 0;

    public static int SHAREHOLDERDE_IS_FALSE = 1;

    private final int BORDER_NUM = 250;


    public Integer findShareholderByUserIdOrPhone(Integer userId, String phone) {
        return mapper.selectShareHolderByUserIdOrPhone(userId, phone);
    }

    /**
     * 新增股东
     * zuoyh
     *
     * @param appShareholderDetailDTO
     * @param updUserId
     * @return
     */
    public ObjectRestResponse add(AppShareholderDetailDTO appShareholderDetailDTO, Integer updUserId) {

        if (appShareholderDetailDTO == null || StringUtils.isBlank(appShareholderDetailDTO.getName()) || StringUtils.isBlank(appShareholderDetailDTO.getPhone()) ||
                appShareholderDetailDTO.getCompanyList() == null) {
            return ObjectRestResponse.createFailedResult(ResultCode.NOTEXIST_CODE, "参数不能为空");
        }
        AppShareholderDetail appShareholderDetail = new AppShareholderDetail();
        String[] companyArray = appShareholderDetailDTO.getCompanyList();

        for (String company : companyArray) {
            Integer companyId = Integer.valueOf(company);
            if (!(companyId != null && companyId > 0))
                return ObjectRestResponse.createFailedResult(ResultCode.NOTEXIST_CODE, "分公司不存在");
            RestResponse<BranchCompany> branchCompany = vehicleFeign.get(companyId);

            if (branchCompany.getData() == null) {
                return ObjectRestResponse.createFailedResult(ResultCode.NOTEXIST_CODE, "分公司不存在");
            }
            appShareholderDetailDTO.setCompanyId(companyId);
            appShareholderDetailDTO.setCompanyName(branchCompany.getData().getName());
            Integer positionId = branchCompany.getData().getId().equals(1) ? HEADQUARTERS_SHAREHOLDER : BRANCH_HEADQUARTERS_SHAREHOLDER;
            //用户表更改其身份
            Integer userId = 0;
            //登陆表查询用户手机号
            AppUserLogin userLogin = loginBiz.checkeUserLogin(appShareholderDetailDTO.getPhone());
            if (userLogin != null) {
                userId = userLogin.getId();
                //关联查询detail表 获取身份
                AppUserDetail appUserDetail = detailBiz.checkeIsAppUser(userId);
                if (!(appUserDetail.getPositionId().equals(1))) {
                    detailBiz.updateUserPositionByUserId(userId, positionId);
                }
            }
            //判断股东表是否有数据，有则不插入
            Example example = new Example(AppShareholderDetail.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("userId", userId);
            criteria.andEqualTo("companyId", companyId);
            if (appShareholderDetailDTO.getPhone() != null) {
                criteria.andEqualTo("phone", appShareholderDetailDTO.getPhone());
            }

            List<AppShareholderDetail> listappShareholderDetai = selectByExample(example);
            if (listappShareholderDetai.size() == 0) {
                Integer id = appShareholderDetailDTO.getId() == null ? 0 : appShareholderDetailDTO.getId();
                BeanUtils.copyProperties(appShareholderDetailDTO, appShareholderDetail);
                appShareholderDetail.setPositionId(positionId);
                appShareholderDetailDTO.setUserId(userId);
                // insertSelective(appShareholderDetail);
                addUserFindId(appShareholderDetail);
                //插入记录表
                appShareholderDetailChangeRecordBiz.addAppShareholderDetailChangeRecord(appShareholderDetail, updUserId, SHAREHOLDERDE_IS_TRUE);
            }
        }
        return ObjectRestResponse.succ();
    }

    //分开事务，先新增股东表 ，获取自增长ID ，存入股东变更记录表
    public AppShareholderDetail addUserFindId(AppShareholderDetail appShareholderDetail) {
        AppShareholderDetail appShareholderDetailNew = new AppShareholderDetail();
        insertSelective(appShareholderDetail);
        BeanUtils.copyProperties(appShareholderDetail, appShareholderDetailNew);
        return appShareholderDetailNew;
    }

    /**
     * 编辑股东信息
     */
    public ObjectRestResponse updSharehoder(AppShareholderDetailDTO appShareholderDetailDTO, Integer updUserId) {

        if (appShareholderDetailDTO.getChangeState() == null) {
            return ObjectRestResponse.createFailedResult(ResultCode.NOTEXIST_CODE, "请输入操作指令");
        }
        if (appShareholderDetailDTO.getId() == null) {
            return ObjectRestResponse.createFailedResult(ResultCode.NOTEXIST_CODE, "请传入修改股东ID");
        }

        AppShareholderDetail appShareholderDetail = new AppShareholderDetail();
        BeanUtils.copyProperties(appShareholderDetailDTO, appShareholderDetail);
        //信息修改
        if (appShareholderDetailDTO.getChangeState().equals(1)) {
            updateSelectiveById(appShareholderDetail);
            //         updateById(appShareholderDetail);
        } else if (appShareholderDetailDTO.getChangeState().equals(2)) {
            if (appShareholderDetailDTO.getCompanyList() == null) {
                return ObjectRestResponse.createFailedResult(ResultCode.NOTEXIST_CODE, "请传入需要退股的公司");
            }
            if (appShareholderDetailDTO.getRelTime() == null) {
                return ObjectRestResponse.createFailedResult(ResultCode.NOTEXIST_CODE, "请输入退股时间");
            }
            if (appShareholderDetailDTO.getPhone() == null) {
                return ObjectRestResponse.createFailedResult(ResultCode.NOTEXIST_CODE, "请输入股东号码");
            }
            for (String company : appShareholderDetailDTO.getCompanyList()) {
                Integer companyId = Integer.valueOf(company);
                appShareholderDetail.setIsQuit(SHAREHOLDERDE_IS_FALSE);
                updateSelectiveById(appShareholderDetail);
                AppShareholderDetail updAppShareholderDetail = selectById(appShareholderDetail);
                RestResponse<BranchCompany> branchCompany = vehicleFeign.get(companyId);
                String companyName = branchCompany.getData().getName();
                updAppShareholderDetail.setCompanyName(companyName);
                //插入记录表
                appShareholderDetailChangeRecordBiz.addAppShareholderDetailChangeRecord(updAppShareholderDetail, updUserId, SHAREHOLDERDE_IS_FALSE);
            }
        }

        return ObjectRestResponse.succ();
    }

    /**
     * 分页查询
     */
    public PageDataVO<AppShareholderDetailVo> findWithPage(AppShareholderDetailFindDTO appShareholderDetailFindDTO) {

        PageDataVO<AppShareholderDetailVo> dataVO = new PageDataVO<>();
        String name = null;
        String phone = null;
        Integer positionId = null;
        Integer companyID = null;
        if (StringUtils.isNotEmpty(appShareholderDetailFindDTO.getName())) {
            name = String.format("%%%s%%", appShareholderDetailFindDTO.getName().trim());
        }
        if (StringUtils.isNotEmpty(appShareholderDetailFindDTO.getPhone())) {
            phone = appShareholderDetailFindDTO.getPhone();
        }
        if (Objects.nonNull(appShareholderDetailFindDTO.getCompanyId())) {
            companyID = appShareholderDetailFindDTO.getCompanyId();
        }
        if (Objects.nonNull(appShareholderDetailFindDTO.getPositionId())) {
            positionId = appShareholderDetailFindDTO.getPositionId();
        }

        PageDataVO<AppShareholderDetail> pageDataVO = findPage(appShareholderDetailFindDTO, positionId, companyID, phone, name);
        List<AppShareholderDetail> data = pageDataVO.getData();
        if (CollectionUtils.isEmpty(data)) {
            dataVO.setData(Collections.EMPTY_LIST);
            dataVO.setPageNum(appShareholderDetailFindDTO.getPage());
            dataVO.setPageSize(appShareholderDetailFindDTO.getLimit());
            return dataVO;
        }

        List<Integer> postionIds = data.stream().map(AppShareholderDetail::getPositionId).collect(Collectors.toList());
        Map<Integer, AppUserPosition> postionMap = appUserPositionBiz.findPostionIdAndPostionMapByIds(postionIds);
        List<AppShareholderDetailVo> AppShareholderDetailVos = new ArrayList<>();
        //    List<AppShareholderDetailVo> AppShareholderDetailMerge = new ArrayList<>();
        AppShareholderDetailVo appShareholderDetailVo;
        for (AppShareholderDetail appShareholderDetail : data) {
            appShareholderDetailVo = new AppShareholderDetailVo();
            BeanUtils.copyProperties(appShareholderDetail, appShareholderDetailVo);
            String postionName = postionMap == null ? "" : postionMap.get(appShareholderDetail.getPositionId()) == null ? "" : postionMap.get(appShareholderDetail.getPositionId()).getName();
            appShareholderDetailVo.setPositionName(postionName);
            AppShareholderDetailVos.add(appShareholderDetailVo);
        }
  /* for (AppShareholderDetailVo appShareholderDetailVoOld : AppShareholderDetailVos) {
            boolean flag = true;
            for (AppShareholderDetailVo appShareholderDetailVoNew : AppShareholderDetailMerge) {
                if (appShareholderDetailVoNew.getPhone().equals(appShareholderDetailVoOld.getPhone()) && appShareholderDetailVoNew.getIsQuit().equals(appShareholderDetailVoOld.getIsQuit())) {//判断姓名是否相同
                    appShareholderDetailVoNew.setCompanyName(appShareholderDetailVoNew.getCompanyName() + "," + appShareholderDetailVoOld.getCompanyName());
                    flag = false;
                }
            }
            if (flag) {
                appShareholderDetailMerge.add(appShareholderDetailVoOld);//给整合后集合添加子元素
            }
        }*/
        dataVO.setPageSize(pageDataVO.getPageSize());
        dataVO.setPageNum(pageDataVO.getPageNum());
        dataVO.setData(AppShareholderDetailVos);
        dataVO.setTotalCount(pageDataVO.getTotalCount());
        dataVO.setTotalPage(pageDataVO.getTotalPage());
        return dataVO;
    }

    private PageDataVO<AppShareholderDetail> findPage(AppShareholderDetailFindDTO appShareholderDetailFindDTO, Integer finalPositionId, Integer finalCompanyID, String finalPhone, String finalName) {
        return PageDataVO.pageInfo(appShareholderDetailFindDTO.getPage(), appShareholderDetailFindDTO.getLimit(), () -> {
            mapper.findPage(finalName, finalPhone, finalPositionId, finalCompanyID);
        });
    }

    /**
     * 批量导入
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Map<String, Object> importShareholder(List<String[]> shareholderData, Integer operatorId) {
        List<AppShareholderDetail> appShareholderDetail = new ArrayList<>();
        Map<String, Object> mapResult = wrapperData(shareholderData, operatorId);

   /*int threadNums = shareholderData.size() / BORDER_NUM == 0 ? 1 : shareholderData.size() / BORDER_NUM;
        CountDownLatch latch = new CountDownLatch(threadNums);
        for (int i = 0; i < threadNums; i++) {
            int startIndex = i * BORDER_NUM;
            int endIndex = i == (threadNums - 1) ? shareholderData.size() : (i + 1) * BORDER_NUM;
            List<String[]> subResultDate = shareholderData.subList(startIndex, endIndex);
            threadPoolTaskExecutor.execute(() -> {

                latch.countDown();
            });
            try {
                latch.await();
            } catch (InterruptedException e) {
                throw new BaseException("导入数据失败");
            }
        }*/
        return mapResult;
    }

    /**
     * @param subResultDate
     */
    private Map<String, Object> wrapperData(List<String[]> subResultDate, Integer operatorId) {
        Map<String, Object> result = new HashMap<>(1);
        Map<String, Object> errorResultMap;
        List<Map<String, Object>> errorResult = Lists.newArrayList();
        //     Map<String, Object> exist;
        List<Map<String, Object>> existResult = Lists.newArrayList();
        int size = subResultDate.get(0).length;
        int total = 0;
        int exist = 0;
        int error = 0;
        subResultDate.remove(0);
        for (String[] data : subResultDate) {
            error++;
            data = Arrays.copyOf(data, size);
            String name = data[0];
            String phone = data[1];
            String companyName = data[2];
            String time = data[3];
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
            try {
                if (StringUtils.isBlank(phone)) {
                    throw new BaseException("手机号为空");
                }
                if (StringUtils.isBlank(companyName)) {
                    throw new BaseException("股东入股公司为空");
                }
                if (StringUtils.isBlank(name)) {
                    throw new BaseException("股东名称为空");
                }
                if (StringUtils.isNotBlank(name)) {
                    name.replaceAll(" ", "");
                }
                if (StringUtils.isNotBlank(companyName)) {
                    name.replaceAll(" ", "");
                }

                Date relTime = StringUtils.isNoneBlank(time) ? formatter.parse(time) : null;
                BranchCompany branchCompany = vehicleFeign.companyId(companyName);
                if (branchCompany != null) {
                    if (branchCompany.getId() != null) {
                        Integer positionId = branchCompany.getId().equals(1) ? HEADQUARTERS_SHAREHOLDER : BRANCH_HEADQUARTERS_SHAREHOLDER;
                        AppShareholderDetailDTO appShareholderDetailDTO = new AppShareholderDetailDTO();
                        //用户表更改其身份
                        Integer userId = 0;
                        //登陆表查询用户手机号
                        AppUserLogin userLogin = loginBiz.checkeUserLogin(phone);
                        if (userLogin != null) {
                            userId = userLogin.getId();
                            appShareholderDetailDTO.setUserId(userId);
                            //关联查询detail表 获取身份
                            AppUserDetail appUserDetail = detailBiz.checkeIsAppUser(userId);
                            if (!(appUserDetail.getPositionId().equals(1))) {
                                detailBiz.updateUserPositionByUserId(userId, positionId);
                            }
                        }
                        exist++;
                        appShareholderDetailDTO.setUserId(userId);
                        appShareholderDetailDTO.setPositionId(positionId);
                        appShareholderDetailDTO.setCompanyId(branchCompany.getId());
                        appShareholderDetailDTO.setCompanyName(branchCompany.getName());
                        appShareholderDetailDTO.setName(name);
                        appShareholderDetailDTO.setPhone(phone);
                        appShareholderDetailDTO.setRelTime(relTime);
                        appShareholderDetailDTO.setIsQuit(0);
                        appShareholderDetailDTO.setCrtTime(System.currentTimeMillis());
                        AppShareholderDetail appShareholderDetail = new AppShareholderDetail();
                        BeanUtils.copyProperties(appShareholderDetailDTO, appShareholderDetail);

                        //判断股东表是否有数据，有则不插入
                        Example example = new Example(AppShareholderDetail.class);
                        Example.Criteria criteria = example.createCriteria();
                        criteria.andEqualTo("userId", userId);
                        criteria.andEqualTo("companyId", branchCompany.getId());
                        if (appShareholderDetailDTO.getPhone() != null) {
                            criteria.andEqualTo("phone", appShareholderDetailDTO.getPhone());
                        }
                        List<AppShareholderDetail> listappShareholderDetai = selectByExample(example);
                        if (listappShareholderDetai.size() == 0) {
                            total++;
                            Integer id = appShareholderDetailDTO.getId() == null ? 0 : appShareholderDetailDTO.getId();
                            BeanUtils.copyProperties(appShareholderDetailDTO, appShareholderDetail);
                            appShareholderDetail.setPositionId(positionId);
                            appShareholderDetailDTO.setUserId(userId);
                            addUserFindId(appShareholderDetail);
                            //插入记录表
                            appShareholderDetailChangeRecordBiz.addAppShareholderDetailChangeRecord(appShareholderDetail, operatorId, SHAREHOLDERDE_IS_TRUE);
                        }
                    }
                }
            } catch (BaseException ex) {
                errorResultMap = new HashMap<>(1);
                errorResultMap.put("num", error);
                errorResultMap.put("msg", ex.getMessage());
                errorResult.add(errorResultMap);
            } catch (ArrayIndexOutOfBoundsException ex) {
                errorResultMap = new HashMap<>(1);
                errorResultMap.put("num", error);
                String msg = "";
                if (StringUtils.isEmpty(phone)) {
                    msg += "手机号码缺失";
                }
                if (StringUtils.isEmpty(companyName)) {
                    msg += ",股东入股公司确实";
                }
                if (StringUtils.isEmpty(name)) {
                    msg += "股东姓名缺失";
                }
                errorResultMap.put("msg", msg);
                errorResult.add(errorResultMap);
            } catch (Exception ex) {
                errorResultMap = new HashMap<>(1);
                errorResultMap.put("num", error);
                errorResultMap.put("msg", "数据" + Arrays.toString(data) + "保存失败");
                errorResult.add(errorResultMap);
            }
        }
        result.put("success", total);
        result.put("error", errorResult.size());
        result.put("data", errorResult);
        result.put("exist", exist - total);
        return result;
    }
}
