package cn.cslg.pas.service;

import cn.cslg.pas.common.model.vo.AnalysisItemCountVO;
import cn.cslg.pas.common.model.vo.PatentVO;
import cn.cslg.pas.common.utils.StringUtils;
import cn.cslg.pas.common.model.dto.analysis.DateTimeDTO;
import cn.cslg.pas.domain.CustomAnalysisItemSource;
import cn.cslg.pas.common.utils.CacheUtils;
import cn.hutool.core.date.DateUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor(onConstructor_ = {@Lazy})
public class DataAnalysisService {

    private final CacheUtils cacheUtils;
    private final PatentService patentService;
    private final AreaService areaService;
    private final CustomAnalysisItemSourceService customAnalysisItemSourceService;

    public Map<String, Object> getMapCount(AnalysisItemCountVO countVO) {
        Map<String, Object> result = new HashMap<>();
        for (CustomAnalysisItemSource source : countVO.getSource().getX()) {
            Map<String, Object> map = new HashMap<>();
            List<String> cities = areaService.getAreaCitiesName(source.getName());
            for (String city : cities) {
                Object ids = cacheUtils.getAnalysisCountIdsV2(countVO.getPatentKey(), countVO.getSchema().getX().getField(), 19, city);
                if (StringUtils.isNotNull(ids)) {
                    map.put(city, StringUtils.changeStringToString(ids.toString(), ",").size());
                }
            }
            result.put(source.getName(), map);
        }
        return result;
    }

    public Integer getAnalysisPatentCount(String value, String key, String type, Integer projectId) {
        PatentVO params = new PatentVO();
        List<PatentVO.Field> fieldList = new ArrayList<>();
        PatentVO.Field field = new PatentVO.Field();
        field.setValue(Collections.singletonList(value));
        field.setKey(key);
        field.setType(type);
        fieldList.add(field);
        params.setField(fieldList);
        params.setProjectId(projectId);
        List<Integer> patentIds = patentService.getQueryPatentIds(params);
        return patentIds.size();
    }

    public Map<String, Map<String, Object>> getMatrix(AnalysisItemCountVO countVO, String id) {
        Map<String, Map<String, Object>> result = new LinkedHashMap<>();
        Map<String, Object> resultMap1 = this.getCount2(
                countVO.getSource().getX(),
                countVO.getSchema().getX().getType(),
                countVO.getPatentKey(),
                countVO.getSchema().getX().getField(),
                countVO.getSchema().getX().getExpand(),
                countVO.getSchema().getX().getMerge(),
                countVO.getSchema().getX().getPtype(),
                countVO.getProjectId(),
                id,
                1
        );
        Map<String, Object> resultMap2 = this.getCount2(
                countVO.getSource().getY(),
                countVO.getSchema().getY().getType(),
                countVO.getPatentKey(),
                countVO.getSchema().getY().getField(),
                countVO.getSchema().getY().getExpand(),
                countVO.getSchema().getY().getMerge(),
                countVO.getSchema().getY().getPtype(),
                countVO.getProjectId(),
                id,
                1
        );
        for (Object map1 : resultMap1.keySet()) {
            Object value1 = resultMap1.get(map1.toString());
            if (StringUtils.isNotNull(value1)) {
                List<Integer> ids1 = StringUtils.changeStringToInteger(value1.toString(), ",").stream().distinct().collect(Collectors.toList());
                Map<String, Object> objectMap = new LinkedHashMap<>();
                for (Object map2 : resultMap2.keySet()) {
                    Object value2 = resultMap2.get(map2.toString());
                    if (StringUtils.isNotNull(value2)) {
                        List<Integer> ids2 = StringUtils.changeStringToInteger(value2.toString(), ",").stream().distinct().collect(Collectors.toList());
                        objectMap.put(map2.toString(), ids1.stream().filter(ids2::contains).count());
                    }
                }
                result.put(map1.toString(), objectMap);
            }
        }
        return result;
    }

    public Map<String, Object> getCount2(
            List<CustomAnalysisItemSource> sourceList,
            Integer type,
            String patentKey,
            Integer field,
            Integer expand,
            Integer merge,
            Integer ptype,
            Integer projectId,
            String id,
            Integer countType
    ) {
        Map<String, Object> result = new LinkedHashMap<>();
        for (CustomAnalysisItemSource source : sourceList) {
            Object score;
            Object value;
            String key;
            if (type.equals(6)) {
                key = String.valueOf(source.getId());
                value = cacheUtils.getAnalysisCountIdsV2(patentKey, field, merge.equals(0) ? 1 : 0, key);
            } else {
                key = source.getName();
                value = cacheUtils.getAnalysisCountIdsV2(patentKey, field, expand, key);
            }
            switch (ptype) {
                case 3: value = patentService.getPatentNumberTypeCount(projectId, id, field, source);break;
                case 4:
                    DateTimeDTO dto = this.createDateTime(expand, source.getStartTime(), source.getEndTime(), source.getName());
                    value = patentService.getPatentDateTime2(projectId, field, dto.getStartTime(), dto.getEndTime(), id);
                    break;
            }
            if (StringUtils.isNotNull(value)) {
                score = StringUtils.changeStringToInteger(value.toString(), ",").size();
            } else {
                score = null;
            }
            if (score != null) {
                result.put(key, countType == 0 ? score : value);
                continue;
            }
            switch (ptype) {
                case 1: break;
                case 2:
                    DateTimeDTO dto = this.createDateTime(expand, source.getName(), null, null);
                    String ids = patentService.getPatentDateTime2(projectId, field, dto.getStartTime(), dto.getEndTime(), id);
                    cacheUtils.setAnalysisCountV2(patentKey, field, expand, source.getName(), ids);
                    if (StringUtils.isNotEmpty(ids)) {
                        result.put(source.getName(), countType == 0 ? StringUtils.changeStringToInteger(ids, ",").size() : ids);
                    }
                    break;
            }
        }
        return result;
    }

    public DateTimeDTO createDateTime(Integer field, String name1, String name2, String key) {
        try {
            SimpleDateFormat format2 = new SimpleDateFormat("yyyy-MM");
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            SimpleDateFormat formatTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date sd, ed;
            switch (field) {
                case 9://月
                    if (!StringUtils.isEmpty(name1)) {
                        sd = DateUtil.beginOfMonth(format2.parse(name1));
                        ed = DateUtil.endOfMonth(format2.parse(name1));
                        return new DateTimeDTO(sd.getTime(), ed.getTime(), name1);
                    }
                case 10://季
                    String[] ds = name1.split("-");
                    String y = ds[0];
                    int q = Integer.parseInt(ds[1].substring(1));
                    Integer m = (q - 1) * 3 + 1;
                    String time = y + "-" + m + "-01";
                    sd = DateUtil.beginOfQuarter(format.parse(time));
                    ed = DateUtil.endOfQuarter(format.parse(time));
                    return new DateTimeDTO(sd.getTime(), ed.getTime(), name1);
                case 11://半年
                    String[] bds = name1.split("-");
                    String by = bds[0];
                    String mb = name1.substring(name1.indexOf("H") + 1);
                    if (mb.equalsIgnoreCase("1")) {
                        sd = format.parse(by + "-01-01");
                        ed = formatTime.parse(by + "-06-30 23:59:59");
                    } else {
                        sd = format.parse(by + "-07-01");
                        ed = formatTime.parse(by + "-12-31 23:59:59");
                    }
                    return new DateTimeDTO(sd.getTime(), ed.getTime(), name1);
                case 12://年
                    sd = format.parse(name1 + "-01-01");
                    ed = formatTime.parse(name1 + "-12-31 23:59:59");
                    return new DateTimeDTO(sd.getTime(), ed.getTime(), name1);
                case 13://两年
                case 14://三年
                case 15://5年
                    String[] ys = name1.split("-");
                    sd = format.parse(ys[0] + "-01-01");
                    ed = formatTime.parse(ys[1] + "-12-31 23:59:59");
                    return new DateTimeDTO(sd.getTime(), ed.getTime(), name1);
                case 16://自定义
                    sd = format.parse(name1);
                    ed = formatTime.parse(name2 + " 23:59:59");
                    return new DateTimeDTO(sd.getTime(), ed.getTime(), key);
                default:
                    return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}
