package com.izouma.zhirongip.service.resource;

import cn.hutool.core.collection.CollUtil;
import com.izouma.zhirongip.converter.StringArrayConverter;
import com.izouma.zhirongip.domain.Setting;
import com.izouma.zhirongip.domain.resource.Digital;
import com.izouma.zhirongip.domain.resource.IntellectualProperty;
import com.izouma.zhirongip.domain.supply.Logo;
import com.izouma.zhirongip.dto.IntellectualPropertyDTO;
import com.izouma.zhirongip.dto.PageQuery;
import com.izouma.zhirongip.dto.ProductDTO;
import com.izouma.zhirongip.dto.TechnologyDTO;
import com.izouma.zhirongip.enums.DigitalType;
import com.izouma.zhirongip.exception.BusinessException;
import com.izouma.zhirongip.repo.SettingRepo;
import com.izouma.zhirongip.repo.resource.DigitalRepo;
import com.izouma.zhirongip.utils.JpaUtils;
import com.izouma.zhirongip.utils.excel.ExcelUtils;
import lombok.AllArgsConstructor;
import org.apache.xmlbeans.impl.xb.xsdschema.Public;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@AllArgsConstructor
public class DigitalService {

    private final DigitalRepo digitalRepo;
    private final SettingRepo settingRepo;

    public Page<Digital> all(PageQuery pageQuery) {
        Map<Long, String> settingMap = settingRepo.findAll().stream()
                .collect(Collectors.toMap(Setting::getId, Setting::getName));
        return digitalRepo.findAll(JpaUtils.toSpecification(pageQuery, Digital.class), JpaUtils.toPageRequest(pageQuery))
                .map(cd -> {
                    cd.setFieldName(settingMap.get(cd.getField()));
                    cd.setSettingName(settingMap.get(cd.getSettingId()));
                    return cd;
                });
    }

    public Digital get(Long id) {
        Digital _digital = digitalRepo.findById(id).orElseThrow(new BusinessException("无记录"));
        _digital.setFieldName(settingRepo.findById(_digital.getField())
                .orElseThrow(new BusinessException("无记录"))
                .getName());
        _digital.setSettingName(settingRepo.findById(_digital.getSettingId())
                .orElseThrow(new BusinessException("无记录"))
                .getName());
        return _digital;
    }

    @Transactional(rollbackOn = Exception.class)
    public void upload(InputStream is) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        byte[] buffer = new byte[1024];
        int len;
        while ((len = is.read(buffer)) > -1) {
            baos.write(buffer, 0, len);
        }
        baos.flush();

        InputStream indicatorStream = new ByteArrayInputStream(baos.toByteArray());
        List<TechnologyDTO> dtos = ExcelUtils.readExcel(indicatorStream, TechnologyDTO.class, 1, 1);

        List<Digital> records = new ArrayList<>();
        List<Setting> settings = settingRepo.findAllByFlagIn(CollUtil.newArrayList(1, 10));
        Map<Integer, Map<String, Long>> mapMap = settings
                .stream()
                .collect(Collectors.groupingBy(Setting::getFlag, Collectors.toMap(Setting::getName, Setting::getId)));

        dtos.forEach(dto -> {
            Digital property = new Digital(dto);
            property.setType(DigitalType.TECHNOLOGY);
            property.setField(mapMap.get(1).get(dto.getFieldName()));
            property.setSettingId(mapMap.get(10).get(dto.getSettingName()));

            records.add(property);
        });

        digitalRepo.saveAll(records);
    }

    @Transactional(rollbackOn = Exception.class)
    public void uploadProduct(InputStream is) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        byte[] buffer = new byte[1024];
        int len;
        while ((len = is.read(buffer)) > -1) {
            baos.write(buffer, 0, len);
        }
        baos.flush();

        InputStream indicatorStream = new ByteArrayInputStream(baos.toByteArray());
        List<ProductDTO> dtos = ExcelUtils.readExcel(indicatorStream, ProductDTO.class, 1, 1);

        List<Digital> records = new ArrayList<>();
        List<Setting> settings = settingRepo.findAllByFlagIn(CollUtil.newArrayList(1, 12));
        Map<Integer, Map<String, Long>> mapMap = settings
                .stream()
                .collect(Collectors.groupingBy(Setting::getFlag, Collectors.toMap(Setting::getName, Setting::getId)));

        dtos.forEach(dto -> {
            Digital property = new Digital(dto);
            property.setType(DigitalType.PRODUCT);
            property.setField(mapMap.get(1).get(dto.getFieldName()));
            property.setSettingId(mapMap.get(12).get(dto.getSettingName()));

            records.add(property);
        });

        digitalRepo.saveAll(records);
    }
}
