package com.izouma.zhirongip.service.supply;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.excel.EasyExcel;
import com.izouma.zhirongip.domain.Information;
import com.izouma.zhirongip.domain.Setting;
import com.izouma.zhirongip.domain.supply.Patent;
import com.izouma.zhirongip.dto.PageQuery;
import com.izouma.zhirongip.dto.PatentExcelDto;
import com.izouma.zhirongip.dto.excel.PatentExcel;
import com.izouma.zhirongip.enums.ApplyStatus;
import com.izouma.zhirongip.enums.CaseType;
import com.izouma.zhirongip.enums.OwnerType;
import com.izouma.zhirongip.exception.BusinessException;
import com.izouma.zhirongip.repo.InformationRepo;
import com.izouma.zhirongip.repo.SettingRepo;
import com.izouma.zhirongip.repo.supply.PatentRepo;
import com.izouma.zhirongip.service.SettingService;
import com.izouma.zhirongip.utils.JpaUtils;
import com.izouma.zhirongip.utils.excel.ExcelUtils;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
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.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@AllArgsConstructor
public class PatentService {

    private final PatentRepo      patentRepo;
    private final SettingRepo     settingRepo;
    private final InformationRepo informationRepo;
    private final SettingService  settingService;

    public Page<Patent> all(PageQuery pageQuery) {
        Map<Long, String> settingMap = settingRepo.findAllByFlagIn(CollUtil.list(false, 1, 13, 24, 25, 26)).stream()
                                                  .collect(Collectors.toMap(Setting::getId, Setting::getName));
        return patentRepo.findAll(JpaUtils.toSpecification(pageQuery, Patent.class), JpaUtils.toPageRequest(pageQuery))
                         .map(cd -> {
//                             cd.setIndustryName(settingMap.get(cd.getIndustryClass()));
//                             if (cd.getPatentTypeId() != null) {
//                                 cd.setPatentType(settingMap.get(cd.getPatentTypeId()));
//                             }
//                             if (cd.getLawStatusId() != null) {
//                                 cd.setLawStatus(settingMap.get(cd.getLawStatusId()));
//                             }
//                             if (cd.getTradingMethodId() != null) {
//                                 cd.setTradingMethod(settingMap.get(cd.getTradingMethodId()));
//                             }
//                             cd.setView((long) (Math.random() * 10 + 10));
                             return cd;
                         });
    }

    public Patent get(Long id) {
        Patent patent = patentRepo.findById(id).orElseThrow(new BusinessException("无记录"));
        if(patent.getIndustryClass() != null) {
            patent.setIndustryName(settingRepo.findById(patent.getIndustryClass())
                                              .orElseThrow(new BusinessException("无记录"))
                                              .getName());
        }
        if (patent.getPatentTypeId() != null) {
            patent.setPatentType(settingRepo.findById(patent.getPatentTypeId())
                                            .orElseThrow(new BusinessException("无记录"))
                                            .getName());
        }
        if (patent.getLawStatusId() != null) {
            patent.setLawStatus(settingRepo.findById(patent.getLawStatusId())
                                           .orElseThrow(new BusinessException("无记录"))
                                           .getName());
        }
        if (patent.getTradingMethodId() != null) {
            patent.setTradingMethod(settingRepo.findById(patent.getTradingMethodId())
                                               .orElseThrow(new BusinessException("无记录"))
                                               .getName());
        }
        return patent;
    }

    public void audit(Long id, boolean pass, String remark) {
        Patent record = patentRepo.findById(id).orElseThrow(new BusinessException("无记录"));

        Information information = Information.builder()
                                             .receiveUserId(record.getUserId())
                                             .isRead(false)
                                             .build();

        if (pass) {
            record.setStatus(ApplyStatus.PASS);
            patentRepo.save(record);

            information.setContent("您发布的供给侧：" + record.getName() + "已通过审核！");
            informationRepo.save(information);
            return;
        }
        record.setStatus(ApplyStatus.DENY);
        patentRepo.save(record);

        information.setContent("您发布的的供给侧：" + record.getName() + "未通过审核，原因为：" + remark);
        informationRepo.save(information);
    }

    @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 storeInfoStream = new ByteArrayInputStream(baos.toByteArray());
        List<PatentExcel> patentExcels =
                ExcelUtils.readExcel(storeInfoStream, PatentExcel.class, 1, 2);
        List<Patent> patents = new ArrayList<>();
        int index = 0;
        Map<String, Long> settingMap = settingRepo.findAllByFlagIn(CollUtil.list(false, 1, 13, 24, 25, 26)).stream()
                                                  .collect(Collectors.toMap(Setting::getName, Setting::getId));
        Map<String, OwnerType> typeMap = new HashMap<>();
        typeMap.put("企事业单位", OwnerType.ENTERPRISES_AND_INSTITUTIONS);
        typeMap.put("高校院所", OwnerType.UNIVERSITIES_AND_INSTITUTES);
        typeMap.put("研究院", OwnerType.RESEARCH);
        typeMap.put("个人", OwnerType.PERSONAL);
        for (PatentExcel patentExcel : patentExcels) {
            index++;
            if (StringUtils.isNotBlank(patentExcel.getIcpNo())) {
                Patent patent = new Patent();
                try {
                    patent.setName(patentExcel.getName());
                    patent.setUserId(1L);
                    patent.setCaseType(CaseType.GENERAL);
                    patent.setCode(patentExcel.getIcpNo());
                    patent.setPatentType("发明");
                    patent.setPatentTypeId(7239L);
//                    patent.setPatentStatus("有效");
//                    patent.setPatentStatusId(7246L);
                    patent.setIndustryName(patentExcel.getInventory());
                    patent.setIndustryClass(settingMap.get(patentExcel.getIcpNo()));
                    List<String> applicant = new ArrayList<>();
                    applicant.add(patentExcel.getOwner());
                    patent.setApplicant(applicant);
                    patent.setLawStatusId(7244L);
                    patent.setLawStatus("已授权未期满");
                    patent.setOwnerType(typeMap.get(patentExcel.getOwnerType()));
                    patent.setDigest(patentExcel.getDetail());
                    patent.setManual(patentExcel.getDemand());
                    patent.setTradingMethod("转让");
                    patent.setTradingMethodId(7232L);
                    patent.setNegotiateDirectly(true);
                } catch (Exception e) {
                    throw new BusinessException("上传失败，请检查上传表格" + index + "行的内容");
                }
            }
        }
        patentRepo.saveAll(patents);
    }

    @Transactional(rollbackOn = Exception.class)
    public void upload1(InputStream is) throws IOException {
        List<PatentExcelDto> dtos = EasyExcel.read(is).head(PatentExcelDto.class).sheet().doReadSync();
        List<Patent> patents = dtos.stream().map(PatentExcelDto::toPatent).collect(Collectors.toList());
        List<Setting> settings = settingService.getTree(settingRepo.findAllByFlag(1));
        patents.forEach(d -> {
            d.setIndustryClass(settings.stream().filter(s -> s.getName().equals(d.getIndustryName())).findFirst()
                                       .map(Setting::getId).orElse(null));
        });
        patentRepo.saveAll(patents);
    }
}
