package com.yida.data.device.telephone.service.impl;

import cc.mrbird.febs.common.redis.service.RedisService;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yida.data.common.core.entity.constant.CachePrefixConstant;
import com.yida.data.common.core.entity.system.Dept;
import com.yida.data.common.core.entity.telephone.EduTelephone;
import com.yida.data.common.core.entity.telephone.EduTelephoneCard;
import com.yida.data.common.core.entity.telephone.EduTelephoneFamily;
import com.yida.data.common.core.entity.telephone.EduTelephonePrice;
import com.yida.data.common.core.entity.user.EduStudent;
import com.yida.data.common.core.exception.FebsException;
import com.yida.data.common.core.utils.ExcelUtil;
import com.yida.data.device.telephone.mapper.EduTelephoneCardMapper;
import com.yida.data.device.telephone.mapper.EduTelephoneRecordMapper;
import com.yida.data.device.telephone.service.EduTelephoneCardService;
import com.yida.data.device.telephone.service.EduTelephoneFamilyService;
import com.yida.data.device.telephone.service.EduTelephonePriceService;
import com.yida.data.device.telephone.util.BalanceUtil;
import com.yida.data.device.vo.OnlineCountVO;
import com.yida.data.device.vo.telephone.IcCardVO;
import com.yida.data.device.vo.telephone.ImportICCardVO;
import com.yida.data.device.vo.telephone.TelephoneCardVO;
import com.yida.data.system.feign.RemoteDeptService;
import com.yida.data.user.feign.RemoteStudentService;
import java.util.Collections;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import static com.yida.data.common.core.utils.ExcelUtil.getCellValue;

/**
 * 亲情电话-ic卡 Service实现
 *
 * @author zhanghaijun
 * @date 2021-08-10 16:28:12
 */
@Service
@RequiredArgsConstructor
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
public class EduTelephoneCardServiceImpl extends ServiceImpl
    <EduTelephoneCardMapper, EduTelephoneCard> implements EduTelephoneCardService {

    private static final String XLS = "xls";
    private static final String XLSK = "xlsx";
    private final EduTelephoneCardMapper eduTelephoneCardMapper;
    @Resource
    private EduTelephoneFamilyService eduTelephoneFamilyService;
    @Resource
    private EduTelephonePriceService eduTelephonePriceService;
    @Resource
    private EduTelephoneRecordMapper eduTelephoneRecordMapper;
    @Resource
    private RemoteStudentService remoteStudentService;
    @Resource
    private RemoteDeptService remoteDeptService;
    @Resource
    private RedisService redisService;

    @Override
    public IPage<IcCardVO> findCardList(Page page, Integer status, String icc, String studentName, Long schoolId, Long campusId,
        Long sectionId, Long gradeId, Long classId) {
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime start = now.with(TemporalAdjusters.firstDayOfMonth()).withHour(0).withMinute(0).withSecond(0);
        IPage<IcCardVO> cardList = eduTelephoneCardMapper
            .findCardList(page, status, icc, studentName, start, now, schoolId, campusId, sectionId, gradeId, classId);
        for (IcCardVO record : cardList.getRecords()) {
            if (StringUtils.isNotEmpty(record.getBalance())) {
                Double decode = BalanceUtil.decode(record.getBalance());
                record.setBalanceValue(decode);
            }
        }
        return cardList;
    }

    /**
     * 卡详情
     *
     * @param id
     * @return
     */
    @Override
    public TelephoneCardVO findCard(Long id) {
        //查询这张卡的详情，卡基础信息
        EduTelephoneCard eduTelephoneCard = baseMapper.selectById(id);
        Long studentId = eduTelephoneCard.getStudentId();
        EduStudent student = new EduStudent();
        //查询学生信息
        if (redisService.hasKey(CachePrefixConstant.STUDENT_DATA)) {
            student = (EduStudent) redisService.hget(CachePrefixConstant.STUDENT_DATA, studentId.toString());
        }
        //缓存没有,查询并添加缓存
        if (ObjectUtil.isEmpty(student)) {
            student = remoteStudentService.getStudentNoPermission(studentId).getData();
            redisService.hset(CachePrefixConstant.STUDENT_DATA, studentId.toString(), student);
        }
        eduTelephoneCard.setSchoolName(student.getSchoolName());
        eduTelephoneCard.setStudentName(student.getStuName());
        eduTelephoneCard.setGradeName(student.getGradeName());
        eduTelephoneCard.setClassName(student.getClassName());
        eduTelephoneCard.setSectionName(student.getSectionName());
        eduTelephoneCard.setCampusName(student.getCampusName());

        Double decode = BalanceUtil.decode(eduTelephoneCard.getBalance());
        eduTelephoneCard.setBalanceValue(decode);
        List<EduTelephoneFamily> list = eduTelephoneFamilyService
            .list(Wrappers.lambdaQuery(new EduTelephoneFamily()).eq(EduTelephoneFamily::getCardId, id));
        EduTelephonePrice price = eduTelephonePriceService.getById(eduTelephoneCard.getPriceId());
        LocalDateTime now = LocalDateTime.now();
        int month = now.getMonthValue();
        String start = now.getYear() + ":" + (month > 10 ? month : "0" + month) + ":01 00:00:00";
        //总共通话时间
        Integer integer = eduTelephoneRecordMapper.selectMonthMaxLen(now, start, eduTelephoneCard.getId());
        List<EduTelephoneFamily> eduTelephoneFamilies = eduTelephoneRecordMapper.selectRecord(id);

        //查询统计数据
        TelephoneCardVO telephoneCardVO = eduTelephoneRecordMapper.selectStartAndEnd(id);
        if (ObjectUtil.isEmpty(telephoneCardVO)) {
            telephoneCardVO = new TelephoneCardVO();
        }
        if (CollectionUtil.isEmpty(list)) {
            telephoneCardVO.setFamilyList(null);
        } else if (CollectionUtil.isNotEmpty(list)) {
            telephoneCardVO.setFamilyList(list);
        }

        telephoneCardVO.setEduTelephoneCard(eduTelephoneCard);
        if (ObjectUtil.isEmpty(price)) {
            telephoneCardVO.setPrice(null);
        } else {
            telephoneCardVO.setPrice(price.getPrice());
        }
        if (ObjectUtil.isEmpty(integer)) {
            telephoneCardVO.setCallDuration(null);
        } else {
            telephoneCardVO.setCallDuration(integer);
        }
        if (CollectionUtil.isEmpty(eduTelephoneFamilies)) {
            telephoneCardVO.setPhone(null);
        } else {
            telephoneCardVO.setPhone(eduTelephoneFamilies.get(0).getPhone());
        }

        if (CollectionUtil.isEmpty(eduTelephoneFamilies)) {
            telephoneCardVO.setRelation(null);
        } else {
            telephoneCardVO.setRelation(eduTelephoneFamilies.get(0).getRelation());
        }
        return telephoneCardVO;
    }

    @Override
    public EduTelephoneCard findStudentCard(Long id) {

        return baseMapper.findStudentCard(id, LocalDateTime.now());
    }


    /**
     * 批量上传ic卡
     *
     * @param
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchUpIcCard(String path, String key) {
        ImportICCardVO vo = new ImportICCardVO();
        vo.setStatus(0);
        vo.setPercent(0);
        List<String> errMsg = new ArrayList<>();
        try {

            redisService.hset(CachePrefixConstant.TELEPHONE_IMPORT, key, vo);
            Workbook workbook = ExcelUtil.readExcel(new FileInputStream(path), "xlsx");
            List<EduTelephoneCard> list = new ArrayList<>();
            List<Map<Integer, Cell>> mapList = ExcelUtil.readData(workbook.getSheetAt(0), 1);
            int rowNum = 0;
            int percent = 0;
            int size = mapList.size();

            Sheet sheet = workbook.getSheet("Sheet1");
            //指定行数。一共多少+
            int rows = sheet.getLastRowNum();

            for (Map<Integer, Cell> cellMap : mapList) {
                rowNum++;

                //读取cell
                EduTelephoneCard eduTelephoneCard = new EduTelephoneCard();
                //学校名字
                String schoolName = getCellValue(cellMap.get(0));

                eduTelephoneCard.setSchoolName(schoolName);
                //年级
                String gradeName = getCellValue(cellMap.get(1));
                eduTelephoneCard.setGradeName(gradeName);
                //班级
                String className = getCellValue(cellMap.get(2));
                eduTelephoneCard.setClassName(className);
                //学生姓名
                String studentName = getCellValue(cellMap.get(3));
                eduTelephoneCard.setStudentName(studentName);
                //学号
                String studentNo = getCellValue(cellMap.get(4));
                //ic卡号
                String icCardNo = getCellValue(cellMap.get(5));
                eduTelephoneCard.setCardNo(icCardNo);

                //空说明最后一行，跳出循环
                if (StringUtils.isEmpty(getCellValue(cellMap.get(6)))) {
                    break;
                }
                //费率
                Double price = Double.parseDouble(getCellValue(cellMap.get(6)));

                List<EduTelephonePrice> prices = eduTelephonePriceService.list(Wrappers.lambdaQuery(new EduTelephonePrice())
                    .eq(EduTelephonePrice::getPrice, price));
                Long priceId = prices.get(0).getId();
                Dept school = remoteDeptService.getSchoolByName(schoolName).getData();
                if (ObjectUtil.isEmpty(school)) {
                    errMsg.add(String.format("第%d行:[%s]学校不存在", rowNum, schoolName));
                    continue;
                }
                eduTelephoneCard.setSchoolId(school.getDeptId());
                eduTelephoneCard.setPriceId(priceId);
                //设置学生id
                EduStudent data = remoteStudentService.getStudentByStuNumAndSchool(studentNo, school.getDeptId()).getData();
                if (ObjectUtil.isEmpty(data)) {
                    errMsg.add(String.format("第%d行:[%s]学生不存在", rowNum, studentName));
                    continue;
                }
                Long id = data.getId();
                eduTelephoneCard.setStudentId(id);
                eduTelephoneCard.setClassId(data.getClassId());
                eduTelephoneCard.setGradeId(data.getGradeId());

                //把实数据放入集合里
                list.add(eduTelephoneCard);
                if (rowNum / size > percent) {
                    percent = rowNum / size;
                    vo.setPercent(rowNum / size);
                    redisService.hset(CachePrefixConstant.TELEPHONE_IMPORT, key, vo);
                }

            }
            //批量添加 (执行sql语句批量增加)
            List<String> cardNo = new ArrayList<>();
            for (EduTelephoneCard card : list) {
                cardNo.add(card.getCardNo());

            }
            remove(Wrappers.lambdaQuery(new EduTelephoneCard())
                .in(EduTelephoneCard::getCardNo, cardNo));
            saveOrUpdateBatch(list);
        } catch (Exception e) {
            log.error("错误", e);
        } finally {
            vo.setStatus(1);
            vo.setErrorMsg(errMsg);
            redisService.hset(CachePrefixConstant.TELEPHONE_IMPORT, key, vo);
        }

    }

    @Override
    public void downloadTemplate(HttpServletResponse response) {
        InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("template/telephone/icard.xlsx");
        try {
            com.yida.data.common.core.utils.FileUtil.download(inputStream, "导入模板.xlsx", response);
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            throw new FebsException("下载失败");
        }
    }

    @Override
    public OnlineCountVO getOnlineDistrib(List<Long> schoolIds) {
        OnlineCountVO vo = new OnlineCountVO();
        if (CollUtil.isNotEmpty(schoolIds)) {
            List<EduTelephoneCard> cardList = list(
                Wrappers.<EduTelephoneCard>lambdaQuery().in(EduTelephoneCard::getSchoolId, schoolIds)
                    .select(EduTelephoneCard::getStatus));
            Map<Integer, List<EduTelephoneCard>> onlineGroup = cardList.stream()
                .collect(Collectors.groupingBy(EduTelephoneCard::getStatus));
            vo.setOnlineNum(onlineGroup.getOrDefault(0, Collections.emptyList()).size());
            vo.setOfflineNum(onlineGroup.getOrDefault(1, Collections.emptyList()).size());
        }
        return vo;
    }
}
