package com.flossom.system.service.impl;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;

import com.alibaba.nacos.shaded.com.google.common.collect.Maps;
import com.flossom.common.core.domain.entity.WxInstrumentSerial;
import com.flossom.common.core.domain.entity.WxUserInstrument;
import com.flossom.common.core.domain.entity.WxUserInstrumentLog;
import com.flossom.common.core.domain.entity.WxUserMember;
import com.flossom.common.core.domain.req.WxUserInstrumentExportVm;
import com.flossom.common.core.enums.BindingStatusEnums;
import com.flossom.common.core.mapper.*;
import com.flossom.common.core.utils.DateUtils;
import com.flossom.common.core.utils.StringUtils;
import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.flossom.system.service.IWxUserInstrumentService;
import org.springframework.util.CollectionUtils;
import org.springframework.util.unit.DataUnit;

/**
 * 用户仪器绑定Service业务层处理
 *
 * @author flossom
 * @date 2024-01-10
 */
@Service
public class WxUserInstrumentServiceImpl implements IWxUserInstrumentService
{
    @Autowired
    private WxUserInstrumentMapper wxUserInstrumentMapper;
    @Autowired
    private WxUserMemberMapper wxUserMemberMapper;
    @Autowired
    private WxInstrumentMapper wxInstrumentMapper;
    @Autowired
    private WxInstrumentSerialMapper instrumentSerialMapper;
    @Autowired
    private WxUserInstrumentLogMapper wxUserInstrumentLogMapper;

    /**
     * 查询用户仪器绑定
     *
     * @param id 用户仪器绑定主键
     * @return 用户仪器绑定
     */
    @Override
    public WxUserInstrument selectWxUserInstrumentById(Long id)
    {
        return wxUserInstrumentMapper.selectWxUserInstrumentById(id);
    }

    /**
     * 查询用户仪器绑定列表
     *
     * @param wxUserInstrument 用户仪器绑定
     * @return 用户仪器绑定
     */
    @Override
    public List<WxUserInstrument> selectWxUserInstrumentList(WxUserInstrument wxUserInstrument)
    {
        // 处理用户昵称
        if (StringUtils.isNotEmpty(wxUserInstrument.getNickName())){
            WxUserMember userMember = new WxUserMember();
            userMember.setNickname(wxUserInstrument.getNickName());
            List<WxUserMember> wxUserMembersList = wxUserMemberMapper.selectWxUserMemberList(userMember);
            if (!CollectionUtils.isEmpty(wxUserMembersList)) {
                String userIds = (wxUserMembersList.stream().map(WxUserMember::getId).collect(Collectors.toList())).stream().map(String::valueOf).collect(Collectors.joining(","));
                wxUserInstrument.setUserIds(userIds);
            }
        }
        // 处理用户ID
        if (!CollectionUtils.isEmpty(wxUserInstrument.getUserIdArray())){
            String userIds =wxUserInstrument.getUserIdArray().stream().map(String::valueOf).collect(Collectors.joining(","));
            if (StringUtils.isNotEmpty(wxUserInstrument.getUserIds())) {
                wxUserInstrument.setUserIds(wxUserInstrument.getUserIds()+","+userIds);
            } else {
                wxUserInstrument.setUserIds(userIds);
            }
        }
        // 处理手机号码
        if (StringUtils.isNotEmpty(wxUserInstrument.getUserPhone())){
            List<Long> userIdList = Lists.newArrayList();
            // 获取手机集合
            List<String> mobileList = Arrays.asList(wxUserInstrument.getUserPhone().split(",")).stream().map(String::valueOf).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(mobileList)) {
                for (String mobile: mobileList) {
                    List<WxUserMember> wxUserMembers = wxUserMemberMapper.selectWxUserMemberByMobile(mobile);
                    if (!CollectionUtils.isEmpty(wxUserMembers)) {
                        userIdList.add(wxUserMembers.get(0).getId());
                    }
                }
            }
            if(!CollectionUtils.isEmpty(userIdList)) {
                String userIds = userIdList.stream().map(String::valueOf).collect(Collectors.joining(","));
                if (StringUtils.isNotEmpty(wxUserInstrument.getUserIds())) {
                    wxUserInstrument.setUserIds(wxUserInstrument.getUserIds()+","+userIds);
                } else {
                    wxUserInstrument.setUserIds(userIds);
                }
            }
        }
        // 处理仪器字段
        if (!CollectionUtils.isEmpty(wxUserInstrument.getInstrumentIdArray())) {
            String instrumentIds = wxUserInstrument.getInstrumentIdArray().stream().map(String::valueOf).collect(Collectors.joining(","));
            wxUserInstrument.setInstrumentIds(instrumentIds);
        }
        // 查询绑定的状态
        if (!CollectionUtils.isEmpty(wxUserInstrument.getBindingStatusArray())) {
            String bindStatus = wxUserInstrument.getBindingStatusArray().stream().map(String::valueOf).collect(Collectors.joining(","));
            wxUserInstrument.setMapperBindStatus(bindStatus);
        }

        return wxUserInstrumentMapper.selectWxUserInstrumentList(wxUserInstrument);
    }

    /**
     * 新增用户仪器绑定
     *
     * @param wxUserInstrument 用户仪器绑定
     * @return 结果
     */
    @Override
    public int insertWxUserInstrument(WxUserInstrument wxUserInstrument)
    {
        wxUserInstrument.setCreateTime(DateUtils.getNowDate());
        return wxUserInstrumentMapper.insertWxUserInstrument(wxUserInstrument);
    }

    /**
     * 修改用户仪器绑定
     *
     * @param wxUserInstrument 用户仪器绑定
     * @return 结果
     */
    @Override
    public int updateWxUserInstrument(WxUserInstrument wxUserInstrument)
    {
        wxUserInstrument.setUpdateTime(DateUtils.getNowDate());
        if (BindingStatusEnums.UN_BOUND.getCode() == wxUserInstrument.getBindingStatus()) {
            // 如果操作解绑，用户绑定仪器需要减一
            WxUserInstrument userInstrument = wxUserInstrumentMapper.selectWxUserInstrumentById(wxUserInstrument.getId());
            if(Objects.nonNull(userInstrument)) {
                // 获取绑定的用户
                Long userId = userInstrument.getUserId();
                if (Objects.nonNull(userId)) {
                    WxUserMember userMember = wxUserMemberMapper.selectWxUserMemberById(userId);
                    if (Objects.nonNull(userMember)) {
                        Integer devicesNum = userMember.getDevicesNum();
                        if (devicesNum > 0) {
                            devicesNum = devicesNum - 1;
                            // 更新处理
                            userMember.setDevicesNum(devicesNum);
                            wxUserMemberMapper.updateWxUserMember(userMember);
                        }
                    }
                }
            }
        }
        return wxUserInstrumentMapper.updateWxUserInstrument(wxUserInstrument);
    }

    /**
     * 批量删除用户仪器绑定
     *
     * @param ids 需要删除的用户仪器绑定主键
     * @return 结果
     */
    @Override
    public int deleteWxUserInstrumentByIds(Long[] ids)
    {
        return wxUserInstrumentMapper.deleteWxUserInstrumentByIds(ids);
    }

    /**
     * 删除用户仪器绑定信息
     *
     * @param id 用户仪器绑定主键
     * @return 结果
     */
    @Override
    public int deleteWxUserInstrumentById(Long id)
    {
        return wxUserInstrumentMapper.deleteWxUserInstrumentById(id);
    }

    @Override
    public Map<String,String> changeSerial(WxUserInstrument wxUserInstrument) {
        Map<String,String> resultMap = Maps.newHashMap();
        // 查询序列号是否有效存在
        WxInstrumentSerial serial = new WxInstrumentSerial();
        serial.setSerial(wxUserInstrument.getSerial());
        serial.setValidStatus(1); // 有效
        List<WxInstrumentSerial> serialList = instrumentSerialMapper.selectWxInstrumentSerialList(serial);
        if (CollectionUtils.isEmpty(serialList)) {
            resultMap.put("message","序列号无效,请确定后再绑定");
            resultMap.put("code", "500");
            return resultMap;
        }
        // 查看是否已经被绑定
        WxUserInstrument userInstrument = new WxUserInstrument();
        userInstrument.setSerial(wxUserInstrument.getSerial());
        List<WxUserInstrument> wxUserInstrumentsList = wxUserInstrumentMapper.selectWxUserInstrumentList(userInstrument);
        if (!CollectionUtils.isEmpty(wxUserInstrumentsList)) {
            resultMap.put("message","该序列号已经被绑定");
            resultMap.put("code", "500");
            return resultMap;
        }
        // 开始绑定
        WxUserInstrument userInstrumentRecord = wxUserInstrumentMapper.selectWxUserInstrumentById(wxUserInstrument.getId());

        // 操作变更日记
        // 是否已经绑定
        if (0 == userInstrumentRecord.getBindingStatus()) {
            // 已经绑定的情况下,先解绑，再绑定 0-已绑  2-解绑
            this.saveLog(userInstrumentRecord,2);
        } else {
            // 处于未绑定的情况下，需要用户仪器加 1，已绑定的情况下不需要变动
            if(Objects.nonNull(userInstrumentRecord)) {
                // 获取绑定的用户
                Long userId = userInstrumentRecord.getUserId();
                if (Objects.nonNull(userId)) {
                    WxUserMember userMember = wxUserMemberMapper.selectWxUserMemberById(userId);
                    if (Objects.nonNull(userMember)) {
                        userMember.setDevicesNum(userMember.getDevicesNum() + 1 );
                        wxUserMemberMapper.updateWxUserMember(userMember);
                    }
                }
            }
        }
        // 更新信息
        WxInstrumentSerial instrumentSerialVo = serialList.get(0);
        userInstrumentRecord.setInstrumentId(instrumentSerialVo.getInstrumentId());
        userInstrumentRecord.setSerial(instrumentSerialVo.getSerial());
        userInstrumentRecord.setInstrumentName(instrumentSerialVo.getInstrumentName());
//        userInstrumentRecord.setSerialImage(userInstrument.getSerialImage());
        // 从新绑定
        this.saveLog(userInstrumentRecord,0);

        // 更新绑定数据
        wxUserInstrumentMapper.updateWxUserInstrument(userInstrumentRecord);
        resultMap.put("message","换绑序列号成功");
        resultMap.put("code", "200");
        return resultMap ;
    }

    @Override
    public int changeGuarantee(WxUserInstrument wxUserInstrument) {
        WxUserInstrument userInstrumentRecord = wxUserInstrumentMapper.selectWxUserInstrumentById(wxUserInstrument.getId());
        if (Objects.nonNull(wxUserInstrument.getGuarantee())) {
            // 开始处理时间 需要变更的时间
            Long guarantee = wxUserInstrument.getGuarantee();
            userInstrumentRecord.setGuarantee(guarantee);
            // 设置到期时间
            Calendar calendar = Calendar.getInstance();
            // 将当前时间加多少年
            calendar.add(Calendar.YEAR,  wxUserInstrument.getGuarantee().intValue());
            Date lastYear = calendar.getTime();
            userInstrumentRecord.setGuaranteeEndtime(lastYear);
            wxUserInstrumentMapper.updateWxUserInstrument(userInstrumentRecord);
        }
        return 1;
    }

    @Override
    public List<WxUserInstrumentExportVm> findUserInstrumentExportData(WxUserInstrument exportVm) {
        // 初始化导出字段
        this.addDetailExportFields(exportVm);

        List<WxUserInstrument> wxUserInstruments = Lists.newArrayList();
        // 判断是不是全量导出
        if(CollectionUtils.isEmpty(exportVm.getUserInstrumentIdList())) {
            // 全量导出
            wxUserInstruments = this.selectWxUserInstrumentList(exportVm);
        } else {
            List<Long> userInstrumentIdList = exportVm.getUserInstrumentIdList();
            for (Long id : userInstrumentIdList) {
                // 针对ID获取
                WxUserInstrument userInstrument = wxUserInstrumentMapper.selectWxUserInstrumentById(id);
                wxUserInstruments.add(userInstrument);
            }
        }
        // 处理导出数据
        List<WxUserInstrumentExportVm> wxUserInstrumentExportVms = this.handleExportData(wxUserInstruments, exportVm.getQueryString());

        return wxUserInstrumentExportVms;
    }

    // 处理导出需要的数据
    private List<WxUserInstrumentExportVm> handleExportData(List<WxUserInstrument> wxUserInstruments, String flag){
        List<WxUserInstrumentExportVm> resultList = Lists.newArrayList();
        for (WxUserInstrument wxUserInstrument: wxUserInstruments) {
            WxUserInstrumentLog userInstrumentLog = new WxUserInstrumentLog();
            userInstrumentLog.setUserInstrumentId(wxUserInstrument.getId());
            List<WxUserInstrumentLog> wxUserInstrumentLogList = wxUserInstrumentLogMapper.selectWxUserInstrumentLogList(userInstrumentLog);
            if  ("all".equals(flag)) {
                // 补充日志详情数据
                if (!CollectionUtils.isEmpty(wxUserInstrumentLogList)){
                    for (WxUserInstrumentLog userInstrumentLogRecord : wxUserInstrumentLogList) {
                        // 组装响应数据
                        WxUserInstrumentExportVm exportVm = new WxUserInstrumentExportVm();
                        // 先复制数据
                        BeanUtils.copyProperties(wxUserInstrument,exportVm);
                        if (wxUserInstrument.getBindingStatus() == 0) {
                            exportVm.setBindingStatus("已绑定");
                        } else {
                            exportVm.setBindingStatus("已解绑");
                        }
                        // 补充用户信息
                        WxUserMember userMember = wxUserMemberMapper.selectWxUserMemberById(wxUserInstrument.getUserId());
                        if (Objects.nonNull(userMember)) {
                            exportVm.setNickname(userMember.getNickname());
                            exportVm.setMobile(userMember.getMobile());
                        }
                        exportVm.setUserInstrumentLogSerial(userInstrumentLogRecord.getSerial());
                        exportVm.setUserInstrumentLogBingStatus(userInstrumentLogRecord.getBindingStatus() == 0 ? "已绑定" : "已解绑");
                        exportVm.setUserInstrumentLogId(userInstrumentLogRecord.getId());
                        exportVm.setUserInstrumentLogCreateTime(userInstrumentLogRecord.getCreateTime());
                        resultList.add(exportVm);
                    }
                }
            } else {
                // 组装响应数据
                WxUserInstrumentExportVm exportVm = new WxUserInstrumentExportVm();
                // 先复制数据
                BeanUtils.copyProperties(wxUserInstrument,exportVm);
                if (wxUserInstrument.getBindingStatus() == 0) {
                    exportVm.setBindingStatus("已绑定");
                } else {
                    exportVm.setBindingStatus("已解绑");
                }
                // 补充用户信息
                WxUserMember userMember = wxUserMemberMapper.selectWxUserMemberById(wxUserInstrument.getUserId());
                if (Objects.nonNull(userMember)) {
                    exportVm.setNickname(userMember.getNickname());
                    exportVm.setMobile(userMember.getMobile());
                }
                // 补充日志详情数据
                if (!CollectionUtils.isEmpty(wxUserInstrumentLogList)){
                    WxUserInstrumentLog userInstrumentLogRecord = wxUserInstrumentLogList.get(0);
                    exportVm.setUserInstrumentLogSerial(userInstrumentLogRecord.getSerial());
                    exportVm.setUserInstrumentLogBingStatus(userInstrumentLogRecord.getBindingStatus() == 0 ? "已绑定" : "已解绑");
                    exportVm.setUserInstrumentLogId(userInstrumentLogRecord.getId());
                    exportVm.setUserInstrumentLogCreateTime(userInstrumentLogRecord.getCreateTime());
                }
                resultList.add(exportVm);
            }
        }

        return resultList;
    }

    // 默认加上详情的字段
    private void addDetailExportFields(WxUserInstrument exportVm){
        List<String> exportFields = exportVm.getExportFields();
        exportFields.add("userInstrumentLogId");
        exportFields.add("userInstrumentLogSerial");
        exportFields.add("userInstrumentLogBingStatus");
        exportFields.add("userInstrumentLogCreateTime");
    }

    public int saveLog(WxUserInstrument userInstrumentRecord, int status){
        WxUserInstrumentLog log = new WxUserInstrumentLog();
        log.setUserInstrumentId(userInstrumentRecord.getId());
        log.setBindingStatus(status);
        log.setGuarantee(userInstrumentRecord.getGuarantee());
        log.setInstrumentId(userInstrumentRecord.getInstrumentId());
        log.setUserId(userInstrumentRecord.getUserId());
        log.setInstrumentName(userInstrumentRecord.getInstrumentName());
        log.setSerialImage(userInstrumentRecord.getSerialImage());
        log.setSerial(userInstrumentRecord.getSerial());
        log.setGuaranteeEndtime(userInstrumentRecord.getGuaranteeEndtime());
        log.setCreateTime((DateUtils.getNowDate()));
        return wxUserInstrumentLogMapper.insertWxUserInstrumentLog(log);
    }
}
