package com.ruoyi.demo.service.impl;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import com.ruoyi.demo.entity.*;
import com.ruoyi.demo.entity.bo.*;
import com.ruoyi.demo.entity.vo.*;
import com.ruoyi.demo.mapper.*;
import com.ruoyi.demo.service.BrandService;
import com.ruoyi.demo.utils.CategoryUtil;
import com.ruoyi.demo.utils.WdRedisStoreage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;

@Service
public class BrandServiceImpl implements BrandService {
    @Autowired
    BrandMapper brandMapper;
    @Autowired
    BrandStatisticsMapper brandStatisticsMapper;
    @Autowired
    BrandProvinceMapper brandProvinceMapper;
    @Autowired
    BrandCityMapper brandCityMapper;
    @Autowired
    BrandZoneMapper brandZoneMapper;
    @Autowired
    EnterpriseMapper enterpriseMapper;
    @Autowired
    AttentionPoolDao attentionPoolDao;
    @Autowired
    CategoryMapper categoryMapper;
    @Autowired
    IndustryCategoryDao industryCategoryDao;
    @Autowired
    StoreWdDao storeWdDao;
    @Autowired
    TypeByDao typeByDao;
    @Autowired
    WdInfoServiceImpl wdInfoService;
    @Autowired
    CategoryUtil categoryUtil;
    @Autowired
    BrandEvolveDao brandEvolveDao;
    @Autowired
    StoreWdOpcloseDao storeWdOpcloseDao;
    @Autowired
    WdRedisStoreage wdRedisStoreage;
    @Autowired
    WdInfoDao wdInfoDao;
    @Autowired
    BrandCityTierMapper tierMapper;

    @Override
    public List<BrandSearch> searchByLikeName(String text) {
        // 根据品牌名称模糊查询
        QueryWrapper<Brand> brandQueryWrapper = new QueryWrapper<>();
        brandQueryWrapper.like("brand_name", text)
            .eq("show_delete", 0);
        List<Brand> list = brandMapper.selectList(brandQueryWrapper);

        List<BrandSearch> sList = new ArrayList<>();
        // 补齐品牌的企业信息
        for (Brand brand : list) {
            QueryWrapper<Enterprise> enterpriseQueryWrapper = new QueryWrapper<>();
            enterpriseQueryWrapper.eq("enterprise_usci", brand.getEnterpriseUsci());
            Enterprise enterprise = enterpriseMapper.selectOne(enterpriseQueryWrapper);
            BrandSearch bs = new BrandSearch();
            bs.setBrandId(brand.getBrandId());
            bs.setBrandName(brand.getBrandName());
            if (enterprise != null)
                bs.setEnterpriseName(enterprise.getEnterpriseName());
            bs.setUpdateTime(brand.getUpdateTime());
            sList.add(bs);
        }
        return sList;
    }

    @Override
    public BrandInfo searchByBrandId(String brandId, String userId) {
        // 查询品牌
        QueryWrapper<Brand> brandQueryWrapper = new QueryWrapper<>();
        brandQueryWrapper.eq("brand_id", brandId)
            .eq("show_delete", 0);
        Brand brand = brandMapper.selectOne(brandQueryWrapper);

        if (brand == null)
            return null;
        // 查询企业
        QueryWrapper<Enterprise> enterpriseQueryWrapper = new QueryWrapper<>();
        enterpriseQueryWrapper.eq("enterprise_usci", brand.getEnterpriseUsci());
        Enterprise enterprise = enterpriseMapper.selectOne(enterpriseQueryWrapper);
        // 赋值
        BrandInfo info = new BrandInfo(brand, enterprise);
        if (brand.getIndustryCode() != null) {
            QueryWrapper<IndustryCategory> industryCategoryQueryWrapper = new QueryWrapper<>();
            industryCategoryQueryWrapper.eq("industry_code", brand.getIndustryCode());
            IndustryCategory industryCategory = industryCategoryDao.selectOne(industryCategoryQueryWrapper);
            info.setIndustryName(industryCategory != null ? industryCategory.getSubCategory() : null);
        } else info.setIndustryName(null);
        // 是否已经关注
        QueryWrapper<AttentionPool> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("brand_id", brandId)
            .eq("wd_id", "");
        AttentionPool pool = attentionPoolDao.selectOne(queryWrapper);
        info.setAttention(pool == null ? 0 : 1);
        return info;
    }

    @Override
    public BrandProperty searchPropertyByBrandId(String brandId) {
        // 获取品牌统计信息
        QueryWrapper<BrandStatistics> statisticsQueryWrapper = new QueryWrapper<>();
        statisticsQueryWrapper.eq("brand_id", brandId);
        BrandStatistics brandStatistics = brandStatisticsMapper.selectOne(statisticsQueryWrapper);

        QueryWrapper<Brand> brandQueryWrapper = new QueryWrapper<>();
        brandQueryWrapper.eq("brand_id", brandId)
            .eq("show_delete", 0);
        Brand brand = brandMapper.selectOne(brandQueryWrapper);

        // 赋值
        BrandProperty bp = new BrandProperty();
        if (brand != null) {
            bp.setIndustryCode(brand.getIndustryCode());
            if (brand.getIndustryCode() == null || brand.getIndustryCode().equals(""))
                bp.setIndustryName("");
            else
                bp.setIndustryName(categoryMapper.searchSubIndustryByCode(brand.getIndustryCode()).getName());
            bp.setPerCapitaConsumption(brand.getPerCapitaConsumption());
            bp.setCommentCount(brand.getCommentCount());
            bp.setScore(brand.getScore());
        } else bp.setIndustryName("****");
        if (brandStatistics != null) {
            float activeRatio = (float) brandStatistics.getBusinessCount() / brandStatistics.getTotal();
            bp.setActiveRatio((int) (activeRatio * 100) + "%");
        } else bp.setActiveRatio("****");
        return bp;
    }

    @Override
    public List<BrandSimilar> searchSimilarByBrandId(String brandId) {
        // 先查询品牌id得到industryCode
        QueryWrapper<Brand> brandQueryWrapper = new QueryWrapper<>();
        brandQueryWrapper.eq("brand_id", brandId)
            .eq("show_delete", 0);
        Brand brand = brandMapper.selectOne(brandQueryWrapper);
        if (brand == null)
            return new ArrayList<>();

        // 再根据industryCode得到其他品牌的信息
        if (brand.getIndustryCode() == null)
            return new ArrayList<>();
        List<Brand> brands = brandMapper.searchByIndustryCodeList(brandId, brand.getIndustryCode());
        if (brands.isEmpty())
            return new ArrayList<>();

        List<BrandSimilar> similarList = new ArrayList<>();
        brands.forEach(b -> similarList.add(new BrandSimilar(b)));
        return similarList;
    }

    @Override
    public List<BrandStatus> searchStatusByBrandId(String brandId) {
//        查询状态后拆分
        QueryWrapper<BrandStatistics> statisticsQueryWrapper = new QueryWrapper<>();
        statisticsQueryWrapper.eq("brand_id", brandId);
        BrandStatistics statistics = brandStatisticsMapper.selectOne(statisticsQueryWrapper);

        if (statistics == null) return new ArrayList<>();
        int businessCount = statistics.getBusinessCount();
        int pauseBusinessCount = statistics.getPauseBusinessCount();
        int noBusinessCount = statistics.getNoBusinessCount();

        List<BrandStatus> statuses = new ArrayList<>();
        if (businessCount != 0)
            statuses.add(new BrandStatus("正常", businessCount));
        if (pauseBusinessCount != 0)
            statuses.add(new BrandStatus("暂停", pauseBusinessCount));
        if (noBusinessCount != 0)
            statuses.add(new BrandStatus("尚未营业", noBusinessCount));
        return statuses;
    }

    @Override
    public BrandDistribution searchDistributionByBrandId(String brandId) {
//        省份:31
//        城市:342
//        区县:2989
//        查询统计并附加信息
        int province = 31;
        int city = 342;
        int zone = 2989;

        QueryWrapper<BrandStatistics> statisticsQueryWrapper = new QueryWrapper<>();
        statisticsQueryWrapper.eq("brand_id", brandId);
        BrandStatistics statistics = brandStatisticsMapper.selectOne(statisticsQueryWrapper);
        if (statistics == null)
            return null;

        return new BrandDistribution(statistics, province, city, zone);
    }

    @Override
    public List<BrandProvinceBo> searchProvinceByBrandId(String brandId) {
        // 查询品牌省级分布
        QueryWrapper<BrandProvince> provinceQueryWrapper = new QueryWrapper<>();
        provinceQueryWrapper.eq("brand_id", brandId);
        List<BrandProvince> provinces = brandProvinceMapper.selectList(provinceQueryWrapper);
        // 查询品牌统计信息
        QueryWrapper<BrandStatistics> statisticsQueryWrapper = new QueryWrapper<>();
        statisticsQueryWrapper.eq("brand_id", brandId);
        BrandStatistics statistics = brandStatisticsMapper.selectOne(statisticsQueryWrapper);

        if (provinces == null || provinces.isEmpty() || statistics == null)
            return new ArrayList<>();

        List<BrandProvinceBo> bpbs = new ArrayList<>();
        provinces.forEach(bp -> bpbs.add(new BrandProvinceBo(bp, statistics.getTotal())));
        return bpbs;
    }

    @Override
    public BrandDisCloud searchDisCloudByBrandId(String brandId) {
        // 获取市级别统计分布数据
        QueryWrapper<BrandCity> cityQueryWrapper = new QueryWrapper<>();
        cityQueryWrapper.eq("brand_id", brandId);
        List<BrandCity> brandCities = brandCityMapper.selectList(cityQueryWrapper);
        // 获取区级别统计分布数据
        QueryWrapper<BrandZone> zoneQueryWrapper = new QueryWrapper<>();
        zoneQueryWrapper.eq("brand_id", brandId);
        List<BrandZone> brandZones = brandZoneMapper.selectList(zoneQueryWrapper);

        BrandDisCloud disCloud = new BrandDisCloud();
        List<BrandDisItem> zoneDis = new ArrayList<>();
        List<BrandDisItem> cityDis = new ArrayList<>();
        brandZones.forEach(zone -> zoneDis.add(new BrandDisItem(zone)));
        brandCities.forEach(city -> zoneDis.add(new BrandDisItem(city)));
        disCloud.setZoneDistribution(zoneDis);
        disCloud.setCityDistribution(cityDis);
        return disCloud;
    }

    @Override
    public PageInfo<List<BrandSearch>> searchListByMulti(ListQueryBody body, String userId) {
        PageHelper.startPage(body.getPageNum(), body.getPageSize(), true);
        List<String> industryCode = body.getIndustryCode();
        /*
        industryCode行业类别码，例如101000，但不确定，需要对其拆解，查询其子类别。
        因数据库数据不齐，这里没有进行相关处理
         */
        Integer countDown = null;
        Integer countUp = null;
        Integer coverDown = null;
        Integer coverUp = null;
        if (body.getWdCount() != null) { // 拆分搜索字段：网点数量
            if (body.getWdCount().size() == 1)
                countDown = Integer.parseInt(body.getWdCount().get(0));
            else if (body.getWdCount().size() >= 2) {
                countDown = Integer.parseInt(body.getWdCount().get(0));
                countUp = Integer.parseInt(body.getWdCount().get(1));
            }
        }
        if (body.getCoverCityCount() != null) { // 拆分搜索字段：覆盖城市数
            if (body.getCoverCityCount().size() == 1) {
                coverDown = Integer.parseInt(body.getCoverCityCount().get(0));
            } else if (body.getCoverCityCount().size() >= 2) {
                coverDown = Integer.parseInt(body.getCoverCityCount().get(0));
                coverUp = Integer.parseInt(body.getCoverCityCount().get(1));
            }
        }
        List<BrandSearch> brandSearches = brandMapper.searchSearchByMulti(body.getText(), industryCode, countUp, countDown, coverUp, coverDown);
        // 赋予attention字段信息，0：未关注；1：已关注
        if (userId == null || userId.equals("")) { // 用户未登录或无效用户id，都是未关注状态
            for (BrandSearch search : brandSearches) {
                QueryWrapper<Enterprise> enterpriseQueryWrapper = new QueryWrapper<>();
                enterpriseQueryWrapper.eq("enterprise_usci", search.getEnterpriseName());
                Enterprise enterprise = enterpriseMapper.selectOne(enterpriseQueryWrapper);
                search.setEnterpriseName(enterprise != null ? enterprise.getEnterpriseName() : null);
                search.setAttention(0);
            }
        } else { // 否则，根据用户潜客池，赋予字段相应的值
            List<AttentionPool> pools = attentionPoolDao.searchByMulti(null, userId);
            Map<String, String> map = new HashMap<>();
            for (AttentionPool pool : pools)
                map.put(pool.getBrandId(), "1");
            for (BrandSearch search : brandSearches) {
                QueryWrapper<Enterprise> enterpriseQueryWrapper = new QueryWrapper<>();
                enterpriseQueryWrapper.eq("enterprise_usci", search.getEnterpriseName());
                Enterprise enterprise = enterpriseMapper.selectOne(enterpriseQueryWrapper);
                search.setEnterpriseName(enterprise != null ? enterprise.getEnterpriseName() : null);
                search.setAttention(map.get(search.getBrandId()) == null ? 0 : 1);
            }
        }
        return new PageInfo(brandSearches);
    }

    @Override
    public List<BrandTotal> searchTotal(Integer pageSize) {
        QueryWrapper<BrandStatistics> statisticsQueryWrapper = new QueryWrapper<>();
        statisticsQueryWrapper.orderByDesc("total");
        List<BrandStatistics> list = brandStatisticsMapper.selectList(statisticsQueryWrapper);
        if (list == null || list.isEmpty())
            return new ArrayList<>();

        // 取pageSize大小的数量，默认10条
        List<BrandTotal> tList = new ArrayList<>();
        if (pageSize == null) pageSize = 10;
        int index = 0;
        for (BrandStatistics bs : list) {
            if (index >= pageSize)
                break;
            tList.add(new BrandTotal(bs));
            index++;
        }
        return tList;
    }

    @Override
    public List<BrandGeoLabelBo> searchGeoLabel(String brandId) {
        List<BrandGeoLabelBo> bos = new ArrayList<>();
        // 查询门店
        QueryWrapper<StoreWd> storeWdQueryWrapper = new QueryWrapper<>();
        storeWdQueryWrapper.eq("brand_id", brandId);
        List<StoreWd> storeWds = storeWdDao.selectList(storeWdQueryWrapper);
        if (storeWds.isEmpty())
            return bos;
//         查询门店标签
        int count = storeWds.size(); // 总数，用于做比率
        // 将门店列表中的网点id抽取出来
        List<String> wdIds = new ArrayList<>();
        storeWds.forEach(storeWd -> wdIds.add(storeWd.getWdId()));
        // 查询网点基本信息列表
        QueryWrapper<WdInfo> wdInfoQueryWrapper = new QueryWrapper<>();
        wdInfoQueryWrapper.in("wd_id", wdIds);
        List<WdInfo> wdInfos = wdInfoDao.selectList(wdInfoQueryWrapper);
        // 统计标签
        Map<String, Integer> typeMap = new HashMap<>();
        for (WdInfo wdInfo : wdInfos) {
            List<String> wdTag = wdRedisStoreage.getWdTag(wdInfo);
            if (wdTag == null) return bos;
            for (String tag : wdTag) {
                if (typeMap.get(tag) != null) {
                    typeMap.replace(tag, typeMap.get(tag) + 1);
                    continue;
                }
                typeMap.put(tag, 1);
            }
        }
        // 排序标签统计结果
        List<Map.Entry<String, Integer>> sortMap = new ArrayList<>(typeMap.entrySet());
        Collections.sort(sortMap, new Comparator<Map.Entry<String, Integer>>() {
            @Override
            public int compare(Map.Entry<String, Integer> t1, Map.Entry<String, Integer> t2) {
                return t2.getValue().compareTo(t1.getValue()); // 降序
            }
        });
        // 获取前10项标签统计结果
        List<String> searchList = new ArrayList<>();
        for (int i = 0; i < sortMap.size(); i++) {
            searchList.add(sortMap.get(i).getKey());
            if (searchList.size() >= 10)
                break;
        }
        // 赋值
        searchList.forEach(s -> bos.add(new BrandGeoLabelBo(s, typeMap.get(s), count)));
        return bos;
    }

    @Override
    public List<BrandEvolveVo> searchEvolveByMulti(List<String> addrCodes, List<String> typeCodes, List<String> brandIds) {
        // 补齐地址码
        List<String> addrs = new ArrayList<>();
        if (addrCodes != null) {
            if (!addrCodes.isEmpty())
                for (String code : addrCodes)
                    addrs.addAll(categoryUtil.getAllOtherAddrCode(code));
        } else
            addrs = null;
        // 补齐网点分类（犇云）
        List<String> types = new ArrayList<>();
        if (typeCodes != null) {
            if (!typeCodes.isEmpty())
                for (String code : typeCodes)
                    types.addAll(categoryUtil.getAllOtherTypeBy(code));
        } else
            types = null;

        List<BrandEvolveVo> vos = new ArrayList<>();
        for (String brandId : brandIds) {
            List<BrandEvolveVo> evolveVos = brandEvolveDao.selectByMulti(addrs, types, brandId);
            for (int i = 1; i < evolveVos.size(); i++)
                evolveVos.get(i).setTotal(evolveVos.get(i - 1).getTotal() + evolveVos.get(i).getTotal());
            vos.addAll(evolveVos);
        }
        return vos;
    }

    @Override
    public Map<String, List<BrandEvolveVo>> searchEvolveByMulti2Map(List<String> addrCodes, List<String> typeCodes, List<String> brandIds) {
        // 补齐地址码
        List<String> addrs = new ArrayList<>();
        if (addrCodes != null) {
            if (!addrCodes.isEmpty())
                for (String code : addrCodes)
                    addrs.addAll(categoryUtil.getAllOtherAddrCode(code));
        } else
            addrs = null;
        // 补齐网点分类（犇云）
        List<String> types = new ArrayList<>();
        if (typeCodes != null) {
            if (!typeCodes.isEmpty())
                for (String code : typeCodes)
                    types.addAll(categoryUtil.getAllOtherTypeBy(code));
        } else
            types = null;

        List<BrandEvolveVo> vos = new ArrayList<>();
        // 向后累和
        for (String brandId : brandIds) {
            List<BrandEvolveVo> evolveVos = brandEvolveDao.selectByMulti(addrs, types, brandId);
            for (int i = 1; i < evolveVos.size(); i++)
                evolveVos.get(i).setTotal(evolveVos.get(i - 1).getTotal() + evolveVos.get(i).getTotal());
            vos.addAll(evolveVos);
        }
        // 构造时间映射对象
        Map<String, List<BrandEvolveVo>> times = new HashMap<>();
        for (int i = 0; i < 12; i++) {
            List<BrandEvolveVo> evos = new ArrayList<>();
            // times.put(LocalDateTime.now(ZoneId.of("Asia/Shanghai")).plusMonths(-i).format(DateTimeFormatter.ofPattern("yyyy-MM")), evos);
            times.put(DateUtil.offsetMonth(new Date(), -i).toString("yyyy-MM"), evos);
        }
        // 向时间映射对象中赋值
        vos.forEach(vo -> {
            if (times.get(vo.getTime()) != null) {
                List<BrandEvolveVo> brandEvolveVos = times.get(vo.getTime());
                brandEvolveVos.add(vo);
            }
        });
        return times;
    }

    public Integer timeUtil(String time) {
        String[] split = time.split(":");
        int hour = Integer.parseInt(split[0]);
        int min = Integer.parseInt(split[1]);
        return hour * 100 + min;
    }

    public int compareTime(String time1, String time2) {
        return timeUtil(time1).compareTo(timeUtil(time2));
    }

    @Override
    public List<OpcloseTimeVo> searchOpenTims(List<String> brandIds, List<String> addrCodes, List<String> typeCodeBys) {
        // 补齐地址码
        List<String> addrs = new ArrayList<>();
        if (addrCodes != null) {
            if (!addrCodes.isEmpty())
                for (String addr : addrCodes)
                    addrs.addAll(categoryUtil.getAllOtherAddrCode(addr));
        } else
            addrs = null;

        // 补齐网点分类（犇云）
        List<String> types = new ArrayList<>();
        if (typeCodeBys != null) {
            if (!typeCodeBys.isEmpty())
                for (String type : typeCodeBys)
                    types.addAll(categoryUtil.getAllOtherTypeBy(type));
        } else
            types = null;

        // 合并，计算
        List<OpcloseTimeVo> vos = storeWdOpcloseDao.selectBrandOpenTimes(brandIds, addrs, types);
        List<OpcloseTimeVo> rvos = new ArrayList<>();
        for (int i = 0; i < 24; i += 2) {
            OpcloseTimeVo vo = new OpcloseTimeVo();
            vo.setTime(i + ":00~" + (i + 2) + ":00");
            vo.setCount(0);
            rvos.add(vo);
        }
        vos.forEach(vo -> {
            for (OpcloseTimeVo rvo : rvos) {
                String[] times = rvo.getTime().split("~");
                if (compareTime(vo.getTime(), times[0]) < 0 || compareTime(times[1], vo.getTime()) < 0)
                    continue;
                rvo.setCount(rvo.getCount() + vo.getCount());
            }
        });
        return rvos;
    }

    @Override
    public List<OpcloseTimeVo> searchCloseTims(List<String> brandIds, List<String> addrCodes, List<String> typeCodeBys) {
        // 补齐地址码
        List<String> addrs = new ArrayList<>();
        if (addrCodes != null) {
            if (!addrCodes.isEmpty())
                for (String addr : addrCodes)
                    addrs.addAll(categoryUtil.getAllOtherAddrCode(addr));
        } else
            addrs = null;

        // 补齐网点分类（犇云）
        List<String> types = new ArrayList<>();
        if (typeCodeBys != null) {
            if (!typeCodeBys.isEmpty())
                for (String type : typeCodeBys)
                    types.addAll(categoryUtil.getAllOtherTypeBy(type));
        } else
            types = null;

        // 合并，计算
        List<OpcloseTimeVo> vos = storeWdOpcloseDao.selectBrandCloseTimes(brandIds, addrs, types);
        List<OpcloseTimeVo> rvos = new ArrayList<>();
        for (int i = 0; i < 24; i += 2) {
            OpcloseTimeVo vo = new OpcloseTimeVo();
            vo.setTime(i + ":00~" + (i + 2) + ":00");
            vo.setCount(0);
            rvos.add(vo);
        }
        vos.forEach(vo -> {
            for (OpcloseTimeVo rvo : rvos) {
                String[] times = rvo.getTime().split("~");
                if (compareTime(vo.getTime(), times[0]) < 0 || compareTime(times[1], vo.getTime()) < 0)
                    continue;
                rvo.setCount(rvo.getCount() + vo.getCount());
            }
        });
        return rvos;
    }

    @Override
    public List<BrandCityTier> getCityTier(String brandId) {
        QueryWrapper<BrandCityTier> cityTierQueryWrapper = new QueryWrapper<>();
        return tierMapper.selectList(cityTierQueryWrapper.eq("brand_id", brandId));
    }

    @Override
    public List<TimeVo> searchNew(List<String> industryCodes) {
        /* 补齐行业分类码，目前行业分类为空，这里作保留

         */
        List<TimeVo> vos = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            TimeVo timeVo = new TimeVo();
            // timeVo.setTime(LocalDateTime.now(ZoneId.of("Asia/Shanghai")).plusYears(-i).format(DateTimeFormatter.ofPattern("yyyy")));
            timeVo.setTime(DateUtil.offset(DateUtil.date(), DateField.YEAR, -i).toString("yyyy"));
            timeVo.setCount(brandMapper.selectCountByYear(timeVo.getTime(), null));
            vos.add(timeVo);
        }
        return vos;
    }
}
