package com.izouma.zhirongip.service;

import cn.hutool.core.util.ObjectUtil;
import com.izouma.zhirongip.domain.demand.CopyrightDemand;
import com.izouma.zhirongip.domain.demand.PatentDemand;
import com.izouma.zhirongip.domain.demand.TechProductDemand;
import com.izouma.zhirongip.domain.resource.SuccessCase;
import com.izouma.zhirongip.domain.supply.Copyright;
import com.izouma.zhirongip.domain.supply.Patent;
import com.izouma.zhirongip.domain.supply.TechnologyProduct;
import com.izouma.zhirongip.enums.*;
import com.izouma.zhirongip.repo.InstitutionRepo;
import com.izouma.zhirongip.repo.PersonalRepo;
import com.izouma.zhirongip.repo.UserRepo;
import com.izouma.zhirongip.repo.demand.*;
import com.izouma.zhirongip.repo.resource.*;
import com.izouma.zhirongip.repo.supply.*;
import lombok.AllArgsConstructor;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

@AllArgsConstructor
@Service
public class StatisticService {

    private final PolicyLawRepo            policyLawRepo;
    private final IntellectualPropertyRepo intellectualPropertyRepo;
    private final DigitalRepo              digitalRepo;
    private final CompanyRepo              companyRepo;
    private final ExpertRepo               expertRepo;
    private final PurchaseRepo             purchaseRepo;
    private final SuccessCaseRepo          successCaseRepo;
    private final CopyrightDemandRepo      copyrightDemandRepo;
    private final LogoDemandRepo           logoDemandRepo;
    private final PatentDemandRepo         patentDemandRepo;
    private final TechProductDemandRepo    techProductDemandRepo;
    private final FundingRepo              fundingRepo;
    private final CopyrightRepo            copyrightRepo;
    private final LogoRepo                 logoRepo;
    private final PatentRepo               patentRepo;
    private final ServiceProviderRepo      serviceProviderRepo;
    private final TechnicalManagerRepo     technicalManagerRepo;
    private final TechnologyProductRepo    technologyProductRepo;


    public Map<String, Long> getTotal() {
        long policy = policyLawRepo.countByCategory(ResourceCategory.POLICY);
        long law = policyLawRepo.countByCategory(ResourceCategory.LAW);
        long intellectualProperty = patentRepo
                .count();
        long technology = digitalRepo.countByType(DigitalType.TECHNOLOGY);
        long product = digitalRepo.countByType(DigitalType.PRODUCT);
        long company = companyRepo.count();
        long expert = expertRepo.count();
        long purchase = purchaseRepo.count();
        long successCase = successCaseRepo.count();

        Map<String, Long> map = new HashMap<>();
        map.put("policy", policy);
        map.put("law", law);
        map.put("intellectualProperty", intellectualProperty);
        map.put("technology", technology);
        map.put("product", product);
        map.put("company", company);
        map.put("expert", expert);
        map.put("purchase", purchase);
        map.put("successCase", successCase);

        return map;
    }


    public Map<Object, Long> getDemand(int type) {
        LocalDateTime startAt;
        LocalDate date = LocalDate.now();
        LocalDateTime now = date.atStartOfDay();
        int value;
        // 周
        if (type == 0) {
            value = now.getDayOfWeek().getValue();
        } else if (type == 1) {
            value = now.getDayOfMonth() - 1;
        } else {
            value = now.getDayOfYear() - 1;
        }
        startAt = now.minusDays(value);

        Map<CopyrightType, Long> copyright = copyrightDemandRepo.findAll()
                .stream()
                .filter(demand -> ObjectUtil.isNotNull(demand.getType()) && !startAt.isAfter(demand.getCreatedAt()))
                .collect(Collectors.groupingBy(CopyrightDemand::getType, Collectors.counting()));
        Map<Object, Long> map = new HashMap<>(copyright);

        long logo = logoDemandRepo.countByCreatedAtGreaterThanEqual(startAt);
        map.put("LOGO", logo);

        Map<CaseType, Long> patent = patentDemandRepo.findAll()
                .stream()
                .filter(demand -> ObjectUtil.isNotNull(demand.getCaseType()) && !startAt.isAfter(demand.getCreatedAt()))
                .collect(Collectors.groupingBy(PatentDemand::getCaseType, Collectors.counting()));
        map.putAll(patent);

        Map<TpType, Long> tech = techProductDemandRepo.findAll()
                .stream()
                .filter(demand -> ObjectUtil.isNotNull(demand.getTpType()) && !startAt.isAfter(demand.getCreatedAt()))
                .collect(Collectors.groupingBy(TechProductDemand::getTpType, Collectors.counting()));
        map.putAll(tech);

        long funding = fundingRepo.countByCreatedAtGreaterThanEqual(startAt);
        map.put("FUNDING", funding);
        return map;
    }

    public Map<Object, Long> getSupply(int type) {
        LocalDateTime startAt;
        LocalDate date = LocalDate.now();
        LocalDateTime now = date.atStartOfDay();
        int value;
        // 周
        if (type == 0) {
            value = now.getDayOfWeek().getValue();
        } else if (type == 1) {
            value = now.getDayOfMonth() - 1;
        } else {
            value = now.getDayOfYear() - 1;
        }
        startAt = now.minusDays(value);

        Map<CopyrightType, Long> copyright = copyrightRepo.findAll()
                .stream()
                .filter(demand -> ObjectUtil.isNotNull(demand.getType()) && !startAt.isAfter(demand.getCreatedAt()))
                .collect(Collectors.groupingBy(Copyright::getType, Collectors.counting()));
        Map<Object, Long> map = new HashMap<>(copyright);

        long logo = logoRepo.countByCreatedAtGreaterThanEqual(startAt);
        map.put("LOGO", logo);

        Map<CaseType, Long> patent = patentRepo.findAll()
                .stream()
                .filter(demand -> ObjectUtil.isNotNull(demand.getCaseType()) && !startAt.isAfter(demand.getCreatedAt()))
                .collect(Collectors.groupingBy(Patent::getCaseType, Collectors.counting()));
        map.putAll(patent);

        Map<TpType, Long> tech = technologyProductRepo.findAll()
                .stream()
                .filter(demand -> ObjectUtil.isNotNull(demand.getTpType()) && !startAt.isAfter(demand.getCreatedAt()))
                .collect(Collectors.groupingBy(TechnologyProduct::getTpType, Collectors.counting()));
        map.putAll(tech);

        long service = serviceProviderRepo.countByCreatedAtGreaterThanEqual(startAt);
        map.put("SERVICE", service);

        long manager = technicalManagerRepo.countByCreatedAtGreaterThanEqual(startAt);
        map.put("MANAGER", manager);
        return map;
    }
}
