package com.om.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.om.entity.dto.AppmenuUpdateDTO;
import com.om.entity.dto.DiaMenuQueryPageDTO;
import com.om.entity.dto.DiagnosticMenuDTO;
import com.om.entity.dto.GuidDTO;
import com.om.entity.po.Client;
import com.om.entity.po.DiagnosticMenu;
import com.om.entity.po.DiagnosticMenuVO;
import com.om.entity.po.Distributor;
import com.om.entity.vo.AppMenuVO;
import com.om.entity.vo.DiaMenuQueryPageVO;
import com.om.entity.vo.DiaMenuUploadVO;
import com.om.entity.vo.DistributorQueryPageVO;
import com.om.exception.BadReqException;
import com.om.exception.BizException;
import com.om.mapper.DiagnosticMenuMapper;
import com.om.service.IClientService;
import com.om.service.IDiagnosticMenuService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.om.utils.*;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;

import java.io.IOException;
import java.lang.reflect.Array;
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.DIAGNOSTIC_MENU_PREFIX;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author bmmx
 * @since 2024-03-05
 */
@Service
public class DiagnosticMenuServiceImpl extends ServiceImpl<DiagnosticMenuMapper, DiagnosticMenu> implements IDiagnosticMenuService {

    @Resource
    private HuaweiObsUtil obsUtil;

    @Resource
    private IClientService clientService;

    @Resource
    private JwtUtils jwtUtils;

    @Override
    public Result createDiaMenu(DiagnosticMenuDTO dto) {

        if (BeanUtil.isEmpty(dto)) {
            throw new BadReqException("数据为空");
        }
        List<Integer> clientIds = dto.getClientIds();

        //查询 客户端id
        List<Client> clients = clientService.listByIds(clientIds);
        if (clients.isEmpty()) {
            throw new BadReqException("客户端查询错误");
        }

        DiagnosticMenu diagnosticMenu = BeanUtil.copyProperties(dto, DiagnosticMenu.class);
        diagnosticMenu.setCreateTime(LocalDateTime.now());
        diagnosticMenu.setUpdateTime(LocalDateTime.now());
        diagnosticMenu.setClientIds(diagnosticMenu.getClientIds()
                .substring(1, diagnosticMenu.getClientIds().length() - 1)
                .replaceAll(" ", ""));
        this.save(diagnosticMenu);

        return Result.ok();
    }

    @Override
    public Result<DiaMenuUploadVO> uploadDiaMenu(MultipartFile file) {
        long fileSize = file.getSize();
        String size = FileSizeConverter.convertBytes(fileSize);
        String filename = file.getOriginalFilename();

        //上传文件
        LocalDate now = LocalDate.now();
        int year = now.getYear();
        int monthValue = now.getMonthValue();
        int day = now.getDayOfMonth();
        String prefix = DIAGNOSTIC_MENU_PREFIX + "/" + year + "/" + monthValue + "/" + day;
        try {
            String upload = obsUtil.upload(file, prefix);
            DiaMenuUploadVO vo = new DiaMenuUploadVO();
            vo.setFileName(filename);
            vo.setFileSize(size);
            vo.setSavePath(upload);
            return Result.ok(vo);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public Result deleteDiaMenu(Integer id) {
        //根据id查询
        DiagnosticMenu diagnosticMenu = this.getById(id);
        if (BeanUtil.isEmpty(diagnosticMenu)) {
            throw new BadReqException("该诊断菜单不存在");
        }
        //根据id删除
        this.removeById(id);
        return Result.ok();
    }

    @Override
    public Result updateStatus(Integer id, Integer status) {
        //根据id查询
        DiagnosticMenu diagnosticMenu = this.getById(id);
        if (BeanUtil.isEmpty(diagnosticMenu)) {
            throw new BadReqException("该诊断菜单不存在");
        }

        diagnosticMenu.setEnableStatus(status);
        diagnosticMenu.setUpdateTime(LocalDateTime.now());
        //修改
        this.updateById(diagnosticMenu);
        return Result.ok();
    }

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

        //分页查询数据库
        Page<DiagnosticMenu> page = this.lambdaQuery()
                .like(fileName != null, DiagnosticMenu::getFileName, fileName)
                .like(versionNum != null, DiagnosticMenu::getVersionNum, versionNum)
                .orderByDesc(DiagnosticMenu::getCreateTime)
                .page(new Page<>(pageIndex, pageSize));

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

        List<DiagnosticMenu> records = page.getRecords();
        List<DiagnosticMenuVO> voList = new ArrayList<>();
        for (DiagnosticMenu diagnosticMenu : records) {
            DiagnosticMenuVO diagnosticMenuVO = BeanUtil.copyProperties(diagnosticMenu, DiagnosticMenuVO.class);
            List<Integer> clientIds = new ArrayList<>();
            try {
                clientIds = Arrays.stream(diagnosticMenu.getClientIds()
                                .trim()
                                .split(","))
                        .map(Integer::parseInt)
                        .collect(Collectors.toList());
            } catch (Exception e) {
                throw new BizException("字符串转换数组错误，请检查字符串是否正确");
            }


            //根据id集合批量查询 客户端
            List<Client> clients = clientService.listByIds(clientIds);
            List<String> clientNames = clients.stream().map(c -> c.getName()).collect(Collectors.toList());
            List<String> clientNums = clients.stream().map(c -> c.getNumber()).collect(Collectors.toList());
            if (clients != null) {
                diagnosticMenuVO.setClientNames(clientNames);
                diagnosticMenuVO.setClientNums(clientNums);
            }
            voList.add(diagnosticMenuVO);
        }
        vo.setRecords(voList);
        return Result.ok(vo);
    }

    @Override
    public Result menuUpdate(AppmenuUpdateDTO dto) {
        if (BeanUtil.isEmpty(dto)) {
            return Result.fail("未获取到数据").result(ResultCode.NO_DATA);
        }
        String version = dto.getVersion();

        String guid = dto.getGuid();
        GuidDTO guidDTO = AesUtil.getGuidDTOFromGuid(guid);
        String clientNum = guidDTO.getClientNum();

        //根据客户端编号查询id
        Client client = clientService.lambdaQuery()
                .eq(Client::getNumber, clientNum)
                .one();
        if (BeanUtil.isEmpty(client)) {
            throw new BadReqException("该客户端不存在");
        }
        QueryWrapper<DiagnosticMenu> wrapper = new QueryWrapper<>();
        wrapper.apply("CONCAT(',', client_ids, ',') LIKE {0}", "%," + client.getId() + ",%");

        DiagnosticMenu diagnosticMenu = this.getOne(wrapper);
        if (BeanUtil.isEmpty(diagnosticMenu)) {
            return Result.fail("该菜单不存在").result(24001);
        }
        AppMenuVO vo = new AppMenuVO();
        BeanUtil.copyProperties(diagnosticMenu, vo);
        LocalDate now = LocalDate.now();
        int year = now.getYear();
        int monthValue = now.getMonthValue();
        int day = now.getDayOfMonth();
        String prefix = DIAGNOSTIC_MENU_PREFIX + "/" + year + "/" + monthValue + "/" + day;
        String uploadUrl = obsUtil.getUploadUrl(diagnosticMenu.getFileName(), prefix);
        vo.setUrl(uploadUrl);
        vo.setVersion(diagnosticMenu.getVersionNum());
        vo.setCreateTime(diagnosticMenu.getCreateTime().toInstant(ZoneOffset.of("+8")).toEpochMilli());

        return Result.ok(vo);
    }


}
