package com.kiisoo.ic.store.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.kiisoo.ic.constants.Constants;
import com.kiisoo.ic.customer.entity.OpSellerCustomerRelation;
import com.kiisoo.ic.customer.mapper.OpSellerCustomerRelationDOMapper;
import com.kiisoo.ic.domain.service.PrivilageDomainService;
import com.kiisoo.ic.employee.entity.QrCodeDO;
import com.kiisoo.ic.employee.entity.QrCodeVO;
import com.kiisoo.ic.employee.service.QrCodeService;
import com.kiisoo.ic.store.entity.PoiStore;
import com.kiisoo.ic.store.entity.PoiStoreStaff;
import com.kiisoo.ic.store.entity.PoiStoreStaffVO;
import com.kiisoo.ic.store.mapper.PoiStoreDOMapper;
import com.kiisoo.ic.store.mapper.PoiStoreStaffDOMapper;
import com.kiisoo.ic.store.mapper.PrivilageCpUserStoreDOMapper;
import com.kiisoo.ic.system.bean.ImportAccountErrorBean;
import com.kiisoo.ic.system.bean.PrivilageUserBean;
import com.kiisoo.ic.system.entity.PrivilageAccountDO;
import com.kiisoo.ic.system.entity.PrivilageRoleDO;
import com.kiisoo.ic.system.entity.PrivilageUserDO;
import com.kiisoo.ic.system.enums.AccountEnum;
import com.kiisoo.ic.system.mapper.PrivilageAccountDOMapper;
import com.kiisoo.ic.system.mapper.PrivilageRoleDOMapper;
import com.kiisoo.ic.system.mapper.PrivilageUserDOMapper;
import com.kiisoo.ic.system.service.PrivilageAccountService;
import com.kiisoo.ic.system.service.PrivilageUserRoleService;
import com.kiisoo.ic.system.service.PrivilageUserService;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

import static com.kiisoo.ic.store.constant.Constants.TYPE_MANAGER;
import static com.kiisoo.ic.store.constant.Constants.TYPE_SELLER;

/**
 * 店铺
 */
@Service
public class PoiStoreStaffService {

    @Autowired
    private PoiStoreStaffDOMapper poiStoreStaffDOMapper;
    @Autowired
    private PrivilageDomainService privilageDomainService;
    @Autowired
    private PoiStoreService poiStoreService;
    @Autowired
    private PrivilageUserDOMapper privilageUserDOMapper;
    @Autowired
    private PoiStoreDOMapper poiStoreDOMapper;
    @Autowired
    private PrivilageCpUserStoreDOMapper privilageCpUserStoreDOMapper;
    @Autowired
    private PrivilageAccountService privilageAccountService;
    @Autowired
    private  PrivilageUserService privilageUserService;
    @Autowired
    private PrivilageUserRoleService privilageUserRoleService;
    @Autowired
    private QrCodeService qrCodeService;
    @Autowired
    private PrivilageRoleDOMapper privilageRoleDOMapper;
    @Autowired
    private OpSellerCustomerRelationDOMapper opSellerCustomerRelationDOMapper;
    @Autowired
    private PrivilageAccountDOMapper privilageAccountDOMapper;
    /**
     * 根据条件查询导购信息
     *
     * @param shopId   店铺id
     */
    public IPage<PoiStoreStaffVO> getStaffByUserAndDate(int pageNum, int pageSize,  Long shopId) {

        //根据店铺查询所有扫码客户信息
        QueryWrapper<PoiStoreStaff> wrapper = new QueryWrapper<>();
        //如果有店铺则查店铺
        wrapper.eq("store_id", shopId);
        //状态有效
        wrapper.eq("status", 1);
        wrapper.orderByDesc("id");
        //返回店铺对应的导购
        IPage<PoiStoreStaff> poiStoreStaffs = poiStoreStaffDOMapper.selectPage(new Page<>(pageNum, pageSize), wrapper);
        IPage<PoiStoreStaffVO> resultList = new Page<>();
        List<PoiStoreStaffVO> list = new ArrayList<>();
        BeanUtils.copyProperties(poiStoreStaffs, resultList);
        List<PoiStoreStaff> records = poiStoreStaffs.getRecords();
        records.forEach(poiStoreStaff -> {
            PoiStoreStaffVO poiStoreStaffVO = new PoiStoreStaffVO();
            BeanUtils.copyProperties(poiStoreStaff, poiStoreStaffVO);
            poiStoreStaffVO.setRole(Constants.SELLER_TYPE.get(poiStoreStaff.getType()));
            //拿到用户信息
            PrivilageUserBean privilageUserBean = privilageUserDOMapper.selectUserInfoAndRoleInfo(poiStoreStaff.getUserId());
            if(null != privilageUserBean){
                poiStoreStaffVO.setName(privilageUserBean.getName());
                poiStoreStaffVO.setMobil(privilageUserBean.getMobil());
            }
            //店铺信息
            PoiStore poiStore = poiStoreDOMapper.selectById(poiStoreStaff.getStoreId());
            if (null != poiStore) {
                poiStoreStaffVO.setStoreName(poiStore.getName());
            }
            //导购对应的客户数
            QueryWrapper<OpSellerCustomerRelation> wrapper2 = new QueryWrapper<>();
            wrapper2.eq("store_id",shopId);
            wrapper2.eq("user_id",poiStoreStaff.getUserId());
            wrapper2.eq("type",1);
            List<OpSellerCustomerRelation> opRelations = opSellerCustomerRelationDOMapper.selectList(wrapper2);
            long count = opRelations.stream().map(OpSellerCustomerRelation::getCustomerId).distinct().count();
            poiStoreStaffVO.setCustomerNum((int)count);
            list.add(poiStoreStaffVO);
        });
        resultList.setTotal(poiStoreStaffs.getTotal());
        resultList.setRecords(list);
        return resultList;
    }

    /**
     * 根据条件查询导购信息
     *
     * @param userId
     */
    public Map<String, Object> getStaffByUserId(Long userId) {
        Map<String, Object> result = new HashMap<>();
        List<PoiStoreStaffVO> list = new ArrayList<>();
        QueryWrapper<PoiStoreStaff> wrapperUser = new QueryWrapper<>();
        wrapperUser.eq("user_id", userId).eq("type", TYPE_MANAGER).last("limit 1");
        //店长的店铺
        PoiStoreStaff shopNameByUserId = poiStoreStaffDOMapper.selectOne(wrapperUser);

        if(shopNameByUserId!=null){
            //根据店铺查询所有扫码客户信息
            QueryWrapper<PoiStoreStaff> wrapper = new QueryWrapper<>();
            //如果有店铺则查店铺
            wrapper.eq("store_id", shopNameByUserId.getStoreId());
            //状态有效
            wrapper.eq("status", 1);
            //导购
            wrapper.eq("type", TYPE_SELLER);
            wrapper.orderByDesc("id");
            //返回店铺对应的导购
            List<PoiStoreStaff> poiStoreStaffs = poiStoreStaffDOMapper.selectList(wrapper);
            poiStoreStaffs.forEach(poiStoreStaff -> {
                PoiStoreStaffVO poiStoreStaffVO = new PoiStoreStaffVO();
                BeanUtils.copyProperties(poiStoreStaff, poiStoreStaffVO);
                poiStoreStaffVO.setRole(Constants.SELLER_TYPE.get(poiStoreStaff.getType()));
                //拿到用户信息
                PrivilageUserBean privilageUserBean = privilageUserDOMapper.selectUserInfoAndRoleInfo(poiStoreStaff.getUserId());
                if(null != privilageUserBean){
                    poiStoreStaffVO.setName(privilageUserBean.getName());
                    poiStoreStaffVO.setMobil(privilageUserBean.getMobil());
                }
                //账号信息
                QueryWrapper<PrivilageAccountDO> wrapperAccount = new QueryWrapper<>();
                wrapperAccount.eq("user_id",poiStoreStaff.getUserId()).eq("type",Constants.ACCOUNT_STATUS_UNABLE);
                PrivilageAccountDO privilageAccountDO = privilageAccountDOMapper.selectOne(wrapperAccount);
                if(privilageAccountDO!=null){
                    poiStoreStaffVO.setAccountId(privilageAccountDO.getId());
                    if(privilageAccountDO.getStatus()!=null &&privilageAccountDO.getStatus()== 1){
                        poiStoreStaffVO.setAccountFlag(true);
                    }else{
                        poiStoreStaffVO.setAccountFlag(false);
                    }
                }
                list.add(poiStoreStaffVO);
            });
            result.put("shopId",shopNameByUserId.getStoreId());
            //店铺信息
            PoiStore poiStore = poiStoreDOMapper.selectById(shopNameByUserId.getStoreId());
            if (null != poiStore) {
                result.put("shopName",poiStore.getName());
            }
            result.put("list",list);
            result.put("staffNum",poiStoreStaffs.size());

        }


        return result;
    }

    /**
     * 添加店铺人员
     * @param poiStoreStaffVO
     */
    public int addStaff(PoiStoreStaffVO poiStoreStaffVO) throws Exception {
        //添加一个用户
        PrivilageUserDO privilageUserDO = new PrivilageUserDO();
        BeanUtils.copyProperties(poiStoreStaffVO,privilageUserDO);
        Long userId =  privilageUserService.addUser(privilageUserDO);
        if (null == userId ) return 0;
        //添加用户和角色的关系
        privilageUserRoleService.insertUserRoleRelation(userId,poiStoreStaffVO.getRoleId());
        if (StringUtils.isNotBlank(poiStoreStaffVO.getIsOpen())){
            //添加一个账号
            privilageAccountService.insertAccount(poiStoreStaffVO.getStaffCode(), AccountEnum.ACCOUNT_FIRST_PWD.getDescribe(), userId);
        }
        //去生成一个推广人员二维码
        QrCodeVO qrCodeVO = parseQrCode(poiStoreStaffVO);
        //添加一个店铺人员
        PoiStoreStaff poiStoreStaff = new PoiStoreStaff();
        BeanUtils.copyProperties(poiStoreStaffVO,poiStoreStaff);
        poiStoreStaff.setUserId(userId);
        poiStoreStaff.setType(poiStoreStaffVO.getRoleId());
        poiStoreStaff.setEpWechatQrCode(qrCodeVO.getQr_code());
        poiStoreStaff.setEpWechatConfigId(qrCodeVO.getConfig_id());
       return poiStoreStaffDOMapper.insert(poiStoreStaff);
    }

    /**
     * 修改推广人信息
     */
    public int ediStaff(PoiStoreStaffVO poiStoreStaffVO) throws Exception {
        //修改用户信息
        Long userId = poiStoreStaffVO.getUserId();
        PrivilageUserDO privilageUserDO = new PrivilageUserDO();
        BeanUtils.copyProperties(poiStoreStaffVO,privilageUserDO);
        privilageUserDO.setId(userId);
        privilageUserService.updateById(privilageUserDO);
        //保存用户角色
        privilageUserRoleService.saveUserRole(userId, poiStoreStaffVO.getRoleId());
        //修改店铺人员信息
        PoiStoreStaff  oldStaffInfo = poiStoreStaffDOMapper.selectById(poiStoreStaffVO.getId());
        PoiStoreStaff poiStoreStaff = new PoiStoreStaff();
        //修改了所属店铺
        if (!oldStaffInfo.getStoreId().equals(poiStoreStaffVO.getStoreId())){
            // 判断条件是否重新修改二维码
            QrCodeVO qrCodeVO =  parseQrCode(poiStoreStaffVO);
            poiStoreStaff.setEpWechatQrCode(qrCodeVO.getQr_code());
            poiStoreStaff.setEpWechatConfigId(qrCodeVO.getConfig_id());
        }
        BeanUtils.copyProperties(poiStoreStaffVO,poiStoreStaff);
        poiStoreStaff.setType(poiStoreStaffVO.getRoleId());
        return poiStoreStaffDOMapper.updateById(poiStoreStaff);
    }

    /**
     * 生成企业微信二维码
     */
    public QrCodeVO  parseQrCode(PoiStoreStaffVO poiStoreStaffVO) throws Exception {
        QrCodeDO qrCodeDO = new QrCodeDO();
        qrCodeDO.setType(1);
        qrCodeDO.setScene(2);
        //查询店铺店长编码
        String cpUserId = privilageCpUserStoreDOMapper.selectCpUserIdByStoreId(poiStoreStaffVO.getStoreId());

        PoiStore poiStore = poiStoreDOMapper.selectById(poiStoreStaffVO.getStoreId());


        String[] data = new String[1];
        //选择店铺对应店长的编码
        data[0] = (cpUserId);
//        data[0] = ("JiangDeXiang");
        qrCodeDO.setUser(data);
        //店铺编码-导购编码
        qrCodeDO.setState(poiStore.getCode() + "-" + poiStoreStaffVO.getStaffCode());
        return qrCodeService.getQrCode(qrCodeDO);
    }

    /**
     * 查询单个推广人的详细信息
     *
     * @param id
     * @return
     */
    public PoiStoreStaffVO getStaffDetail(long id) {
        //店铺人员信息
        PoiStoreStaff poiStoreStaff = poiStoreStaffDOMapper.selectById(id);
        PoiStoreStaffVO staffVO = new PoiStoreStaffVO();
        if (null == poiStoreStaff) return staffVO;
        BeanUtils.copyProperties(poiStoreStaff,staffVO);
        PoiStore poiStore = poiStoreDOMapper.selectById(poiStoreStaff.getStoreId());
        if (poiStore != null) {
            staffVO.setStoreName(poiStore.getName());
        }
        //用户信息
        PrivilageUserBean privilageUserBean = privilageUserDOMapper.selectUserInfoAndRoleInfo(poiStoreStaff.getUserId());
        //账号
        QueryWrapper<PrivilageAccountDO> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", poiStoreStaff.getUserId());
        PrivilageAccountDO privilageAccountDO = privilageAccountDOMapper.selectOne(wrapper);
        staffVO.setName(privilageUserBean.getName());
        staffVO.setMobil(privilageUserBean.getMobil());
        staffVO.setAccountId(privilageAccountDO.getId());
        return staffVO;
    }
    /**
     * 批量上传推广人员
     * @param files
     * @return
     */
    public List<ImportAccountErrorBean> uploadStaff(MultipartFile[] files) throws IOException, InvocationTargetException, IllegalAccessException {
        //错误list
        List<ImportAccountErrorBean> errorBeanList = new ArrayList<>();
        //商品VOList
        List<PoiStoreStaffVO> poiStoreStaffVOList = new ArrayList<>();
        if (files == null || files.length == 0) {
            ImportAccountErrorBean errorBean = new ImportAccountErrorBean();
            errorBean.setError("文件上传异常");
            errorBeanList.add(errorBean);
            return errorBeanList;
        }
        for(MultipartFile file : files){
            if (file.isEmpty()) {
                continue;
            }
            String sourceName = file.getOriginalFilename();
            InputStream fileInput = file.getInputStream();
            Workbook book;
            if (isExcel2007(sourceName)) {
                book = new XSSFWorkbook(fileInput);
            } else {
                book = new HSSFWorkbook(fileInput);
            }
            // 第一个sheet
            Sheet sheet = book.getSheetAt(0);
            // 行数
            int totalRows = sheet.getPhysicalNumberOfRows();
            if(totalRows == 4){
                ImportAccountErrorBean errorBean = new ImportAccountErrorBean();
                errorBean.setError("文件内没有人员信息");
                errorBeanList.add(errorBean);
                return errorBeanList;
            }
            for (int r = 4; r < totalRows; r++) {
                Row row = sheet.getRow(r);
                if (row == null) {
                    continue;
                }
                //检查必填项为空，并插入goodsVOList
                PoiStoreStaffVO poiStoreStaffVO = checkStaffExcelBlank(row, r, errorBeanList);
                poiStoreStaffVOList.add(poiStoreStaffVO);
            }
            //检查重复项 查询条件
            checkRepeat(poiStoreStaffVOList, errorBeanList);

            //插表
            if(errorBeanList.size() == 0){

            }
            errorBeanList.sort(Comparator.comparing(ImportAccountErrorBean::getRow));
        }
        return errorBeanList;


    }

    /**
     * 检查项
     * @param poiStoreStaffVOList 人员VOList
     * @param errorBeanList 错误List
     */
    public void checkRepeat(List<PoiStoreStaffVO> poiStoreStaffVOList, List<ImportAccountErrorBean> errorBeanList){
        AtomicInteger rowNum = new AtomicInteger(5);
        //表格内重复
        for(int i=0;i<poiStoreStaffVOList.size();i++){
            String staffCode = poiStoreStaffVOList.get(i).getStaffCode();
            for(int j = i;j<poiStoreStaffVOList.size();j++){
                if(j != i && poiStoreStaffVOList.get(j).getStaffCode().equals(staffCode)){
                    ImportAccountErrorBean errorBean = new ImportAccountErrorBean();
                    errorBean.setError("第" + rowNum.get() +"行工号，表格内有重复");
                    errorBean.setRow(rowNum.get());
                    errorBeanList.add(errorBean);
                    break;
                }
            }
            rowNum.incrementAndGet();
        }
        //与数据库重复
        rowNum.set(5);
        poiStoreStaffVOList.forEach(staff -> {
            //查询是否存在
            QueryWrapper<PoiStoreStaff> wrapper = new QueryWrapper<>();
            wrapper.eq("staff_code", staff.getStaffCode());
            PoiStoreStaff poiStoreStaff = poiStoreStaffDOMapper.selectOne(wrapper);
            if(poiStoreStaff != null){
                ImportAccountErrorBean errorBean = new ImportAccountErrorBean();
                errorBean.setError("第" + rowNum.get() +"行工号，与数据库内有重复");
                errorBean.setRow(rowNum.get());
                errorBeanList.add(errorBean);
            }
            //查询店铺
            if(StringUtils.isNoneBlank(staff.getStoreName())&&StringUtils.isNoneBlank(staff.getStaffCode())){
                QueryWrapper<PoiStore> wrapperStore = new QueryWrapper<>();
                wrapperStore.eq("name",staff.getStoreName()).eq("code",staff.getStoreCode()).last("limit 1");
                PoiStore shop = poiStoreDOMapper.selectOne(wrapperStore);
                if(shop!=null){
                    staff.setStoreId(shop.getId());
                }else{
                    ImportAccountErrorBean errorBean = new ImportAccountErrorBean();
                    errorBean.setError("第" + rowNum.get() +"行店铺不存在");
                    errorBean.setRow(rowNum.get());
                    errorBeanList.add(errorBean);
                }
            }
            //查询角色
            if(StringUtils.isNoneBlank(staff.getRole())){
                QueryWrapper<PrivilageRoleDO> wrapperRole = new QueryWrapper<>();
                wrapperRole.eq("name",staff.getRole()).last("limit 1");
                PrivilageRoleDO role = privilageRoleDOMapper.selectOne(wrapperRole);
                if(role!=null){
                    staff.setRoleId(role.getId());
                }else{
                    ImportAccountErrorBean errorBean = new ImportAccountErrorBean();
                    errorBean.setError("第" + rowNum.get() +"行角色不存在");
                    errorBean.setRow(rowNum.get());
                    errorBeanList.add(errorBean);
                }
            }
            rowNum.incrementAndGet();
        });

    }

    /**
     * 检查excel字段为空
     * @param row 行
     * @param r 行数
     * @param errorBeanList 错误List
     * @return
     * @throws InvocationTargetException 异常
     * @throws IllegalAccessException 异常
     */
    private PoiStoreStaffVO checkStaffExcelBlank(Row row, int r, List<ImportAccountErrorBean> errorBeanList) throws InvocationTargetException, IllegalAccessException {
        PoiStoreStaffVO poiStoreStaffVO = new PoiStoreStaffVO();
        //所有列(跟下面的属性对上)
        String cellNames = "推广人员姓名,工号,手机号,所属店铺,店铺编号,角色";
        List<String> paramList = Arrays.asList("name","staffCode","mobil","storeName","storeCode","role");
        String[] cellNameArr = cellNames.split(",");
        //必填列
        String mustCellNames = "推广人员姓名,工号,所属店铺,店铺编号,角色";
        Map<String, String> mustCellMap = Arrays.stream(mustCellNames.split(",")).collect(Collectors.toMap(name -> name, name -> name));
        //必填但空List
        List<String> blankNameList = new ArrayList<>();
        for(int i=0;i<cellNameArr.length;i++){
            String cellValue = getCellValue(row.getCell(i));
            //属性值放入VO
            org.apache.commons.beanutils.BeanUtils.setProperty(poiStoreStaffVO, paramList.get(i), cellValue);
            //必填为空
            if(StringUtils.isBlank(cellValue) && mustCellMap.get(cellNameArr[i]) != null){
                blankNameList.add(cellNameArr[i]);
            }
        }
        //必填但空string
        String blankNames = blankNameList.stream().collect(Collectors.joining(",","",""));
        if(StringUtils.isNotBlank(blankNames)){
            ImportAccountErrorBean errorBean = new ImportAccountErrorBean();
            errorBean.setError("第" + (r+1) + "行："+blankNames+"不能为空，请输入完整重新导入！");
            errorBean.setRow(r+1);
            errorBeanList.add(errorBean);
        }
        return poiStoreStaffVO;
    }

    /**
     * 读取cell单元格的值，如果为日期格式，进行转换
     *
     * @param cell 单元格
     * @return 单元格中的值(字符串形式)
     */
    private String getCellValue(Cell cell) {
        if (cell == null) {
            return "";
        }

        if (cell.getCellTypeEnum() == CellType.STRING) {
            return String.valueOf(cell.getRichStringCellValue());
        } else if (cell.getCellTypeEnum() == CellType.BOOLEAN) {
            return String.valueOf(cell.getBooleanCellValue());
        } else if (cell.getCellTypeEnum() == CellType.FORMULA) {
            return cell.getCellFormula();
        } else if (cell.getCellTypeEnum() == CellType.NUMERIC) {
            short format = cell.getCellStyle().getDataFormat();

            SimpleDateFormat sdf;
            if (format == 14 || format == 31 || format == 57 || format == 58
                    || (176 <= format && format <= 178) || (182 <= format && format <= 196)
                    || (210 <= format && format <= 213) || (208 == format)) {
                // 日期
                sdf = new SimpleDateFormat("yyyy-MM-dd");
            } else if (format == 20 || format == 32 || 200 <= format && format <= 209) {
                // 时间
                sdf = new SimpleDateFormat("HH:mm");
            } else {
                // 不是日期格式
                return String.valueOf(cell.getNumericCellValue());
            }

            double value = cell.getNumericCellValue();
            Date date = org.apache.poi.ss.usermodel.DateUtil.getJavaDate(value);
            if (date == null) {
                return "";
            }
            String result;
            try {
                result = sdf.format(date);
            } catch (Exception e) {
                e.printStackTrace();
                return "";
            }
            return result;
        }

        return "";
    }

    /**
     * 描述：是否是2007的excel，返回true是2007
     */
    private static boolean isExcel2007(String filePath) {
        return filePath.matches("^.+\\.(?i)(xlsx)$");
    }

    /**
     * 删除店铺人员
     * @param staffId
     */
    public boolean deleteStaff(long staffId) throws Exception {
        PoiStoreStaff poiStoreStaff = poiStoreStaffDOMapper.selectById(staffId);
        //删除店铺人员
        Long userId = poiStoreStaff.getUserId();
        if (null != poiStoreStaff && null !=userId ){
            //删除用户
            privilageUserService.removeUser(userId);
            //删除用户角色关系
            privilageUserRoleService.removeUserRoleRelation(userId);
            //删除用户店铺和域关系
            privilageDomainService.removeUserEntity(userId);
            //删除账号
            privilageAccountDOMapper.deleteByUserId(userId);
        }
        int i =  poiStoreStaffDOMapper.deleteById(staffId);
        if (i <= 0){
            throw new Exception("删除店铺人员失败");
        }
        return i > 0;

    }
}
