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.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.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.mapreduce.GroupBy;
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.concurrent.CountDownLatch;
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 ThreadPoolTaskExecutor threadPoolTaskExecutor;


    public static int HEADQUARTERS_SHAREHOLDER = 1;

    public static int BRANCH_HEADQUARTERS_SHAREHOLDER = 2;

    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))) {
                    if (positionId.equals(1)) {
                        detailBiz.updateUserPositionByUserId(userId, positionId);
                    }
                }
            }
            Integer id = appShareholderDetailDTO.getId() == null ? 0 : appShareholderDetailDTO.getId();
            BeanUtils.copyProperties(appShareholderDetailDTO, appShareholderDetail);
            appShareholderDetail.setPositionId(positionId);
            appShareholderDetailDTO.setUserId(userId);
            insertSelective(appShareholderDetail);
        }
        return ObjectRestResponse.succ();
    }


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

        PageDataVO<AppShareholderDetailVo> dataVO = new PageDataVO<>();
        Example example = new Example(AppShareholderDetail.class);
        Example.Criteria criteria = example.createCriteria();

        if (StringUtils.isNotEmpty(appShareholderDetailFindDTO.getName())) {
            criteria.andLike("name", String.format("%%%s%%", appShareholderDetailFindDTO.getName().trim()));
        }
        if (StringUtils.isNotEmpty(appShareholderDetailFindDTO.getPhone())) {
            criteria.andEqualTo("phone", appShareholderDetailFindDTO.getPhone());
        }
        if (Objects.nonNull(appShareholderDetailFindDTO.getCompanyId())) {
            criteria.andEqualTo("companyId", appShareholderDetailFindDTO.getCompanyId());
        }
        if (Objects.nonNull(appShareholderDetailFindDTO.getPositionId())) {
            criteria.andEqualTo("positionId", appShareholderDetailFindDTO.getPositionId());
        }
        List<AppShareholderDetail> list = mapper.selectByExample(example);
        example.setOrderByClause("upd_time desc");
        PageDataVO<AppShareholderDetail> pageDataVO = PageDataVO.pageInfo(appShareholderDetailFindDTO.getPage(), appShareholderDetailFindDTO.getLimit(), () -> mapper.selectByExample(example));
        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(AppShareholderDetailMerge);
        dataVO.setTotalCount(pageDataVO.getTotalCount());
        dataVO.setTotalPage(pageDataVO.getTotalPage());
        return dataVO;
    }

    /**
     * 批量导入
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public int importShareholder(List<String[]> shareholderData, Integer userId, String userName) {
        List<AppShareholderDetail> appShareholderDetail = new ArrayList<>();
        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(() -> {
                wrapperData(subResultDate);
                latch.countDown();
            });
            try {
                latch.await();
            } catch (InterruptedException e) {
                throw new BaseException("导入数据失败");
            }
        }
        return appShareholderDetail.size();
    }

    /**
     * @param subResultDate
     */
    private void wrapperData(List<String[]> subResultDate) {

        for (String[] data : subResultDate) {
            String name = data[0];
            String phone = data[1];
            String companyName = data[2];
            String Time = data[3];
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
            try {
                Date relTime = formatter.parse(Time);
                BranchCompany branchCompany = vehicleFeign.companyId(companyName);
                if (branchCompany != 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))) {
                            if (positionId.equals(1)) {
                                detailBiz.updateUserPositionByUserId(userId, positionId);
                            }
                        }
                    }
                    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);
                    mapper.insertSelective(appShareholderDetail);
                }
            } catch (ParseException e) {
                log.error("股东导入失败：【{}】", e);
            }
        }
    }
}
