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

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yida.data.common.core.entity.card.EduStudentCard;
import com.yida.data.common.core.entity.card.EduStudentCardPhone;
import com.yida.data.common.core.enums.CardDeviceEnum;
import com.yida.data.device.studentCard.constant._810AMethod;
import com.yida.data.device.studentCard.mapper.EduStudentCardMapper;
import com.yida.data.device.studentCard.mapper.EduStudentCardPhoneMapper;
import com.yida.data.device.studentCard.service.EduStudentCardPhoneService;
import com.yida.data.device.studentCard.utils.JimiUtils;
import com.yida.data.device.studentCard.utils._810AUtil;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 电子学生证关联电话 Service实现
 *
 * @author zhanghaijun
 * @date 2021-08-05 09:52:38
 */
@Service
@RequiredArgsConstructor
@Transactional
public class EduStudentCardPhoneServiceImpl extends ServiceImpl
    <EduStudentCardPhoneMapper, EduStudentCardPhone> implements EduStudentCardPhoneService {

    private final EduStudentCardMapper eduStudentCardMapper;
    private final JimiUtils jimiUtils;

    @Override
    public void updateDevicePhone(String imei) {
        EduStudentCard studentCard = eduStudentCardMapper.selectOne(Wrappers.<EduStudentCard>lambdaQuery()
            .eq(EduStudentCard::getImei, imei));
        // 当前学生证绑定的全部电话
        if (studentCard.getMcType().contains(CardDeviceEnum.JIMI.getValue())) { //几米学生证
            List<EduStudentCardPhone> phoneList = list(Wrappers.lambdaQuery(new EduStudentCardPhone())
                .eq(EduStudentCardPhone::getImei, imei)
                .orderByAsc(EduStudentCardPhone::getType)
                .orderByAsc(EduStudentCardPhone::getLocation));
            List<String> familyPhone = new ArrayList<>();
            List<String> familyName = new ArrayList<>();
            List<String> sosPhone = new ArrayList<>();
            List<String> whitePhone = new ArrayList<>();

            for (int i = 0; i < 3; i++) {
                familyPhone.add("");
                familyName.add("");
            }
            for (EduStudentCardPhone phone : phoneList) {
                if (phone.getType() == 1 && phone.getLocation() != null
                    && phone.getPhone() != null && phone.getName() != null) {
                    familyPhone.set(phone.getLocation() - 1, phone.getPhone());
                    familyName.set(phone.getLocation() - 1, phone.getName());
                }
                if (phone.getType() == 2) {
                    sosPhone.add(phone.getPhone());
                }
                if (phone.getType() == 3) {
                    whitePhone.add(phone.getName());
                    whitePhone.add(phone.getPhone());
                }
            }
            jimiUtils.setFamilyPhone(imei, familyName, familyPhone);
            jimiUtils.setSos(imei, sosPhone);
            jimiUtils.setWhiteList(imei, whitePhone);
        } else { // 810A学生证
            List<EduStudentCardPhone> familyPhone = list(Wrappers.lambdaQuery(new EduStudentCardPhone())
                .eq(EduStudentCardPhone::getImei, imei)
                .eq(EduStudentCardPhone::getType, 1)
                .orderByAsc(EduStudentCardPhone::getLocation));
            // 白名单排除亲情号码
            LambdaQueryWrapper<EduStudentCardPhone> whiteCondition = Wrappers.lambdaQuery(new EduStudentCardPhone())
                .eq(EduStudentCardPhone::getImei, imei)
                .eq(EduStudentCardPhone::getType, 3);
            // 构造所需的电话列表
            List<String> phone = new ArrayList<>();
            if (CollUtil.isNotEmpty(familyPhone)) {
                phone = familyPhone.stream().map(EduStudentCardPhone::getPhone)
                    .collect(Collectors.toList());
                whiteCondition.notIn(EduStudentCardPhone::getPhone, phone);
            }
            List<EduStudentCardPhone> whitePhone = list(whiteCondition);
            // 前三个亲情号码吗
            if (CollUtil.isNotEmpty(familyPhone)) {
                for (int i = 0; i < familyPhone.size(); i++) {
                    EduStudentCardPhone cardPhone = familyPhone.get(0);
                    LinkedHashMap<String, String> params = new LinkedHashMap<>();
                    params.put("DEVICENUM", imei);
                    params.put("PHONE", cardPhone.getPhone());
                    params.put("NAME", "111");
                    params.put("POS", String.valueOf(cardPhone.getLocation()));
                    params.put("FAMILYKEY", cardPhone.getPhone());
                    params.put("OPTTYPE", "0");
                    _810AUtil.convertAndSend(_810AMethod.DEV_FAMILY.getValue(), params);
                }
            }
            if (CollUtil.isNotEmpty(whitePhone)) {
                for (int i = 0; i < familyPhone.size(); i++) {
                    EduStudentCardPhone cardPhone = familyPhone.get(0);
                    LinkedHashMap<String, String> params = new LinkedHashMap<>();
                    params.put("DEVICENUM", imei);
                    params.put("PHONE", cardPhone.getPhone());
                    params.put("NAME", "111");
                    params.put("POS", String.valueOf(i + 4));
                    params.put("FAMILYKEY", cardPhone.getPhone());
                    params.put("OPTTYPE", "0");
                    _810AUtil.convertAndSend(_810AMethod.DEV_FAMILY.getValue(), params);
                }
            }
            // TODO: 2021/12/20 小于最大限制时删除多余数据
        }
    }

    @Override
    public void savePhone(EduStudentCardPhone phone) {
        if (phone.getType() == 1) {
            if (phone.getId() != null) {
                EduStudentCardPhone exist = getById(phone.getId());
                // 删除sos
                remove(Wrappers.<EduStudentCardPhone>lambdaQuery()
                    .eq(EduStudentCardPhone::getImei, exist.getImei())
                    .eq(EduStudentCardPhone::getPhone, exist.getPhone())
                    .in(EduStudentCardPhone::getType, 2));
            }
            // 保存新的sos
            EduStudentCardPhone sosPhone = new EduStudentCardPhone();
            BeanUtils.copyProperties(phone, sosPhone);
            sosPhone.setType(2);
            sosPhone.setId(null);
            save(sosPhone);
        }
        saveOrUpdate(phone);
        EduStudentCard card = eduStudentCardMapper
            .selectOne(Wrappers.<EduStudentCard>lambdaQuery().eq(EduStudentCard::getImei, phone.getImei()));
        // 810A直接处理
        if (card.getMcType().contains(CardDeviceEnum._810A.getValue())) {
            LinkedHashMap<String, String> params = new LinkedHashMap<>();
            params.put("DEVICENUM", card.getImei());
            params.put("PHONE", phone.getPhone());
            params.put("NAME", "111");
            params.put("POS", String.valueOf(phone.getLocation()));
            params.put("FAMILYKEY", phone.getPhone());
            params.put("OPTTYPE", "0");
            _810AUtil.convertAndSend(_810AMethod.DEV_FAMILY.getValue(), params);
        } else {
            updateDevicePhone(phone.getImei());
        }
    }

    @Override
    public void delPhone(Long id) {
        EduStudentCardPhone phone = getById(id);
        EduStudentCard card = eduStudentCardMapper.selectOne(Wrappers.<EduStudentCard>lambdaQuery()
            .eq(EduStudentCard::getImei, phone.getImei()));
        removeById(id);
        // 810A删除亲情电话同时删除sos
        if (phone.getType() == 1) {
            remove(Wrappers.lambdaQuery(new EduStudentCardPhone())
                .eq(EduStudentCardPhone::getImei, phone.getImei())
                .eq(EduStudentCardPhone::getType, 2)
                .eq(EduStudentCardPhone::getPhone, phone.getPhone()));
        }
        // 810A直接处理
        if (card.getMcType().contains(CardDeviceEnum._810A.getValue())) {
            LinkedHashMap<String, String> params = new LinkedHashMap<>();
            params.put("DEVICENUM", card.getImei());
            params.put("PHONE", phone.getPhone());
            params.put("NAME", "111");
            params.put("POS", String.valueOf(phone.getLocation()));
            params.put("FAMILYKEY", phone.getPhone());
            params.put("OPTTYPE", "1");
            _810AUtil.convertAndSend(_810AMethod.DEV_FAMILY.getValue(), params);
        } else {
            updateDevicePhone(phone.getImei());
        }
    }

    @Override
    public void updatePhoneBatch(List<EduStudentCardPhone> phones, Integer type, String imei) {
        EduStudentCard card = eduStudentCardMapper.selectOne(Wrappers.<EduStudentCard>lambdaQuery()
            .eq(EduStudentCard::getImei, imei));
        if (type == 1) {
            // 810a保存亲情电话时需要同时保存sos
            if (card.getMcType().contains(CardDeviceEnum._810A.getValue())) {
                remove(Wrappers.<EduStudentCardPhone>lambdaQuery()
                    .eq(EduStudentCardPhone::getImei, imei)
                    .eq(EduStudentCardPhone::getType, 2));
                if (CollUtil.isNotEmpty(phones)) {
                    int length = phones.size();
                    for (int i = 0; i < length; i++) {
                        EduStudentCardPhone cardPhone = new EduStudentCardPhone();
                        BeanUtils.copyProperties(phones.get(i), cardPhone);
                        cardPhone.setType(2);
                        phones.add(cardPhone);
                    }
                }
            }
        } else if (type == 3 && CollUtil.isNotEmpty(phones)) {
            // 白名单从4开始计数
            for (int i = 0; i < phones.size(); i++) {
                phones.get(i).setLocation(i + 4);
            }
        }
        List<EduStudentCardPhone> existPhones = list(Wrappers.<EduStudentCardPhone>lambdaQuery()
            .eq(EduStudentCardPhone::getImei, imei)
            .eq(EduStudentCardPhone::getType, type));
        // 删除已有数据
        if (CollUtil.isNotEmpty(existPhones)) {
            removeByIds(existPhones.stream().map(EduStudentCardPhone::getId).collect(Collectors.toList()));
        }
        // 重新保存
        if (CollUtil.isNotEmpty(phones)) {
            saveBatch(phones);
        }
        // 810A直接处理
        if (card.getMcType().contains(CardDeviceEnum._810A.getValue())) {
            if (CollUtil.isNotEmpty(existPhones)) {
                for (EduStudentCardPhone existPhone : existPhones) {
                    LinkedHashMap<String, String> params = new LinkedHashMap<>();
                    params.put("DEVICENUM", card.getImei());
                    params.put("PHONE", existPhone.getPhone());
                    params.put("NAME", "111");
                    params.put("POS", String.valueOf(existPhone.getLocation()));
                    params.put("FAMILYKEY", existPhone.getPhone());
                    params.put("OPTTYPE", "1");
                    _810AUtil.convertAndSend(_810AMethod.DEV_FAMILY.getValue(), params);
                }
            }
            if (CollUtil.isNotEmpty(phones)) {
                for (EduStudentCardPhone phone : phones) {
                    LinkedHashMap<String, String> params = new LinkedHashMap<>();
                    params.put("DEVICENUM", card.getImei());
                    params.put("PHONE", phone.getPhone());
                    params.put("NAME", "111");
                    params.put("POS", String.valueOf(phone.getLocation()));
                    params.put("FAMILYKEY", phone.getPhone());
                    params.put("OPTTYPE", "0");
                    _810AUtil.convertAndSend(_810AMethod.DEV_FAMILY.getValue(), params);
                }
            }
        } else {
            updateDevicePhone(imei);
        }
    }
}
