package com.om.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.om.entity.dto.*;
import com.om.entity.po.*;
import com.om.entity.vo.*;
import com.om.exception.BadReqException;
import com.om.exception.BizException;
import com.om.mapper.BrushFileMapper;
import com.om.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.om.utils.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;


import javax.annotation.Resource;
import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import static com.om.constant.UploadConstant.BRUSH_PREFIX;
import static com.om.constant.UploadConstant.DIAGNOSTIC_MENU_PREFIX;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author bmmx
 * @since 2024-03-21
 */
@Service
public class BrushFileServiceImpl extends ServiceImpl<BrushFileMapper, BrushFile> implements IBrushFileService {

    @Resource
    private JwtUtils jwtUtils;

    @Resource
    private HuaweiObsUtil obsUtil;

    @Resource
    private IBrushDescriptionService brushDescriptionService;

    @Resource
    private IBrushClientService brushClientService;

    @Resource
    private IClientService clientService;

    @Resource
    private IBrandService brandService;

    @Resource
    private PushUtil pushUtil;

    @Override
    public Result getBrushFileList(AppBrushFileDTO dto) {
        if (BeanUtil.isEmpty(dto)){
            return Result.fail("未获取到数据").result(ResultCode.NO_DATA);
        }

        String brandCode = dto.getBrandCode();
        String language = dto.getLanguage();
        String guid = dto.getGuid();
        GuidDTO guidDTO = AesUtil.getGuidDTOFromGuid(guid);
        String clientNum = guidDTO.getClientNum();

        List<BrushFile> brushFileList = this.lambdaQuery()
                .eq(BrushFile::getBrandCode, brandCode)
                .eq(BrushFile::getStatus,1)
                .list();
        List<AppBrushFileVO> brushFileVOList = new ArrayList<>();
        if (!brushFileList.isEmpty()){
            for (BrushFile brushFile : brushFileList) {
                AppBrushFileVO appBrushFileVO = BeanUtil.copyProperties(brushFile, AppBrushFileVO.class);

                BrushDescription brushDescription = brushDescriptionService.lambdaQuery()
                        .eq(BrushDescription::getBrushId, brushFile.getId())
                        .eq(BrushDescription::getLanguage, language)
                        .one();
                if (!BeanUtil.isEmpty(brushDescription)){
                    appBrushFileVO.setDescription(brushDescription.getDescription());
                }else {
                    appBrushFileVO.setDescription("");
                }
                appBrushFileVO.setFileSize((long) (Double.valueOf(brushFile.getFileSize())*1024*1024));

                appBrushFileVO.setFileName(brushFile.getBrushFileName());
                int lastIndexOf = brushFile.getBrushFileName().lastIndexOf('.');
                appBrushFileVO.setVersion(brushFile.getBrushFileName());
                if (lastIndexOf != -1){
                    appBrushFileVO.setVersion(brushFile.getBrushFileName().substring(0, lastIndexOf));
                }

                // appBrushFileVO.setUrl(obsUtil.getUploadUrl(brushFile.getBrushFileName(),));
                appBrushFileVO.setCreateTime(brushFile.getCreateTime().toInstant(ZoneOffset.of("+8")).toEpochMilli());
                brushFileVOList.add(appBrushFileVO);
            }
        }


        return Result.ok(brushFileVOList);
    }

    @Override
    public Result<BlushQueryPageVO> getPageList(BlushQueryPageDTO dto) {
        //从dto中获取数据
        Integer pageSize = dto.getPageSize();
        Integer pageIndex = dto.getPageIndex();
        String fileName = dto.getFileName();

        //分页查询数据库
        Page<BrushFile> page = this.lambdaQuery()
                .like(StringUtils.isNotBlank(fileName), BrushFile::getBrushFileName, fileName)
                .orderByDesc(BrushFile::getCreateTime)
                .page(new Page<>(pageIndex, pageSize));

        //封装vo
        BlushQueryPageVO vo = new BlushQueryPageVO();
        vo.setCurrent((int) page.getCurrent());
        vo.setSize((int) page.getSize());
        vo.setPages((int) page.getPages());
        vo.setTotal((int) page.getTotal());
        if (fileName != null) {
            vo.setSearchCount(true);
        }

        List<BrushFile> records = page.getRecords();
        if (records.isEmpty()){
            return Result.ok(vo);
        }
        List<BrushVO> voList = new ArrayList<>();
        for (BrushFile brushFile : records) {
            BrushVO brushVO = BeanUtil.copyProperties(brushFile, BrushVO.class);

            Brand brand = brandService.lambdaQuery()
                    .eq(Brand::getBrandCode, brushFile.getBrandCode())
                    .one();
            if (BeanUtil.isNotEmpty(brand)){
                brushVO.setBrandName(brand.getBrandCn());
            }
            //根据id查询  描述信息
            List<BrushDescription> brushDescriptionList = brushDescriptionService.lambdaQuery()
                    .eq(BrushDescription::getBrushId, brushFile.getId())
                    .list();
            List<BrushDescriptionVO> brushDescriptionVOList = new ArrayList<>();
            if (!brushDescriptionList.isEmpty()){
                for (BrushDescription brushDescription : brushDescriptionList) {
                    BrushDescriptionVO brushDescriptionVO = new BrushDescriptionVO();
                    brushDescriptionVO.setDescription(brushDescription.getDescription());
                    brushDescriptionVO.setLanguage(brushDescription.getLanguage());

                    brushDescriptionVOList.add(brushDescriptionVO);
                }

                brushVO.setDescriptions(brushDescriptionVOList);
            }

            voList.add(brushVO);
        }
        vo.setRecords(voList);
        return Result.ok(vo);
    }

    @Override
    public Result<BrushUploadVO> uploadBrush(MultipartFile file) {
        try {
            file = FileSigner.sign(file);
        } catch (Exception e) {
            throw new BizException("ECU刷写文件签名出错");
        }
        long fileSize = file.getSize();
        String size = FileSizeConverter.convertBytes(fileSize);
        String filename = file.getOriginalFilename();

        //上传文件
        String prefix = "ecu";
        try {
            String upload = obsUtil.upload(file, prefix);
            BrushUploadVO vo = new BrushUploadVO();
            vo.setBrushFileName(filename);
            vo.setFileSize(size);
            vo.setSavePath(upload);
            return Result.ok(vo);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    @Transactional
    public Result deleteBrush(Integer id) {
        //根据id查询
        BrushFile brushFile = this.getById(id);
        if (BeanUtil.isEmpty(brushFile)) {
            throw new BadReqException("该ECU刷写文件不存在");
        }
        //根据id查询 描述
        List<Integer> integers = brushDescriptionService.lambdaQuery()
                .eq(BrushDescription::getBrushId, brushFile.getId())
                .list().stream().map(c -> c.getId()).collect(Collectors.toList());

        if (!integers.isEmpty()){
            brushDescriptionService.removeBatchByIds(integers);
        }
        //根据id删除
        this.removeById(id);
        return Result.ok();
    }

    @Override
    public Result updateStatus(Integer id, Integer status) {
        //根据id查询
        BrushFile brushFile = this.getById(id);
        if (BeanUtil.isEmpty(brushFile)) {
            throw new BadReqException("该ECU刷写文件不存在");
        }
        brushFile.setStatus(status);
        //修改
        this.updateById(brushFile);
        return Result.ok();
    }

    @Override
    @Transactional
    public Result createBrush(BrushAddDTO dto) {
        if (BeanUtil.isEmpty(dto)) {
            throw new BadReqException("参数为空");
        }
        //刷写文件表
        BrushFile brushFile = new BrushFile();
        brushFile.setBrushFileName(dto.getBrushFileName());
        brushFile.setFileSize(dto.getFileSize());
        brushFile.setUrl(dto.getUrl());
        brushFile.setCreateTime(LocalDateTime.now());
        brushFile.setUpdateTime(LocalDateTime.now());
        brushFile.setBrandCode(dto.getBrandCode());
        brushFile.setStatus(1);
        this.save(brushFile);
        //刷写文件描述表
        List<BrushDescriptionVO> descriptionList = dto.getDescriptionList();
        List<BrushDescription> descriptions = new ArrayList<>();
        for (BrushDescriptionVO description : descriptionList) {
            BrushDescription brushDescription = new BrushDescription();
            brushDescription.setDescription(description.getDescription());
            brushDescription.setLanguage(description.getLanguage());
            brushDescription.setBrushId(brushFile.getId());
            descriptions.add(brushDescription);
        }
        brushDescriptionService.saveBatch(descriptions);
        //刷写文件-客户端表
        List<String> clientNums = dto.getClientNums();
        List<BrushClient> clients = new ArrayList<>();
        for (String clientNum : clientNums) {
            //根据client_cum查询
            Client client = clientService.lambdaQuery()
                    .eq(Client::getNumber, clientNum)
                    .one();
            if (BeanUtil.isEmpty(client)){
                throw new BadReqException("该客户端不存在");
            }
            BrushClient brushClient = new BrushClient();
            brushClient.setClientNum(clientNum);
            brushClient.setClientName(client.getName());
            brushClient.setBrushId(brushFile.getId());
            clients.add(brushClient);
        }
        brushClientService.saveBatch(clients);
        return Result.ok();
    }

    @Override
    public Result pushBrush(Integer id) {
        BrushFile brushFile = this.getById(id);
        if (BeanUtil.isEmpty(brushFile)) {
            throw new BadReqException("该ECU刷写文件不存在");
        }

        PushInfo pushInfo = new PushInfo();
        pushInfo.setPushInfoType(5);

        BrushInfo brushInfo = new BrushInfo();
        brushInfo.setBrushFileName(brushFile.getBrushFileName());
        brushInfo.setCreateTime(brushFile.getCreateTime().toInstant(ZoneOffset.of("+8")).toEpochMilli());
        brushInfo.setUrl(brushFile.getUrl());
        brushInfo.setFileSize((long) (Double.valueOf(brushFile.getFileSize())*1024*1024));

        List<BrushDescription> brushDescriptions = brushDescriptionService.lambdaQuery()
                .eq(BrushDescription::getBrushId, brushFile.getId())
                .list();
        List<Describe> describeList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(brushDescriptions)){
            for (BrushDescription brushDescription : brushDescriptions) {
                Describe describe = new Describe();
                describe.setDescription(brushDescription.getDescription());
                describe.setLanguage(brushDescription.getLanguage());
                describeList.add(describe);
            }
        }
        brushInfo.setDescribeList(describeList);


        List<BrushClient> brushClientList = brushClientService.lambdaQuery()
                .eq(BrushClient::getBrushId, brushFile.getId())
                .list();

        if (CollectionUtil.isNotEmpty(brushClientList)) {
            List<String> clientNums = brushClientList.stream().map(c -> c.getClientNum()).collect(Collectors.toList());
            String[] tokens = new String[clientNums.size()];
            for (String clientNum : clientNums) {
                int i = 0;
                Client client = clientService.lambdaQuery()
                        .eq(Client::getNumber, clientNum)
                        .one();
                if (BeanUtil.isNotEmpty(client)) {
                    tokens[i] = client.getDeviceToken();
                    i++;
                }
            }
            //调用工具类
            pushInfo.setJson(GsonUtils.toJsonString(brushInfo));
            try {
                pushUtil.sendAndroidListcastJSON(tokens,pushInfo);
            } catch (Exception e) {
                throw new BizException("推送失败！！！");
            }
        }
        return Result.ok();
    }
}
