package com.ruoyi.demo.service.impl;


import com.ruoyi.demo.entity.WdOpclose;
import com.ruoyi.demo.entity.vo.AddStatusVo;
import com.ruoyi.demo.entity.vo.OpcloseTimeVo;
import com.ruoyi.demo.entity.vo.WdOpcloseVo;
import com.ruoyi.demo.mapper.StoreWdOpcloseDao;
import com.ruoyi.demo.mapper.WdInfoMapper;
import com.ruoyi.demo.mapper.WdOpcloseDao;
import com.ruoyi.demo.service.WdInfoService;
import com.ruoyi.demo.utils.CategoryUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

@Service
@Transactional
public class WdInfoServiceImpl implements WdInfoService {
    @Autowired
    CategoryUtil categoryUtil;
    @Autowired
    WdInfoMapper wdInfoMapper;
    @Autowired
    WdOpcloseDao wdOpcloseDao;
    @Autowired
    StoreWdOpcloseDao storeWdOpcloseDao;

    @Override
    public List<AddStatusVo> searchAddStatus(List<String> addrCodes, List<String> typeCodes) {
        categoryUtil.setWdTypeMap();
        List<String> addrs = new ArrayList<>();
        List<String> times = new ArrayList<>();
        for (int i = 0; i < 12; i++){
            times.add(LocalDateTime.now(ZoneId.of("Asia/Shanghai")).plusMonths(-i).format(DateTimeFormatter.ofPattern("yyyy-MM")));
        }
        if (addrCodes != null){
            for (String s : addrCodes){
                List<String> allOtherAddrCode = categoryUtil.getAllOtherAddrCode(s);
                addrs.addAll(allOtherAddrCode);
            }
        }else{
            addrs = null;
        }
        List<AddStatusVo> addStatusVos = wdInfoMapper.searchAddStatusByMulti(times, addrs, typeCodes);
        for (AddStatusVo vo : addStatusVos){
            vo.setTypeName(categoryUtil.wdTypeMap.get(vo.getTypeCode()));
        }
        return addStatusVos;
    }

    @Override
    public List<WdOpcloseVo> searchWdOpcloses(List<String> addrCodes, List<String> wdTypeCodes) {
        categoryUtil.setAddrMap();

        List<WdOpcloseVo> vos = new ArrayList<>();
        if (addrCodes != null){
            for (String s : addrCodes){
                WdOpclose opclose = wdOpcloseDao.selectListByAddrCodeAndWdTypeCodes(categoryUtil.whatis(s), wdTypeCodes, LocalDateTime.now(ZoneId.of("Asia/Shanghai")).plusMonths(-1));
                if (opclose != null){
                    WdOpcloseVo vo = new WdOpcloseVo(s,opclose);
                    vo.setAddrName(categoryUtil.addrMap.get(s));
                    vos.add(vo);
                }
            }
            return vos;
        }
        return vos;
    }

    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){
        int result = timeUtil(time1).compareTo(timeUtil(time2));
//        if (result > 0)
//            System.out.println(time1 + " > " + time2);
//        if (result == 0)
//            System.out.println(time1 + " = " + time2);
//        if (result < 0)
//            System.out.println(time1 + " < " + time2);
        return result;
    }

    @Override
    public List<OpcloseTimeVo> searchOpenTimes(List<String> addrCodes, List<String> typeCodeBys) {
        List<String> addrs = new ArrayList<>();
        if (addrCodes != null){
            if (addrCodes.size() != 0)
                for (String addr : addrCodes){
                    List<String> otherAddrCode = categoryUtil.getAllOtherAddrCode(addr);
                    addrs.addAll(otherAddrCode);
                }
            else
                addrs = null;
        }else
            addrs = null;
        List<String> types = new ArrayList<>();
        if (typeCodeBys != null){
            if (typeCodeBys.size() != 0)
                for (String type : typeCodeBys){
                    List<String> otherTypeBy = categoryUtil.getAllOtherTypeBy(type);
                    types.addAll(otherTypeBy);
                }
            else
                types = null;
        }else
            types = null;
        List<OpcloseTimeVo> vos = storeWdOpcloseDao.selectWdOpenTimes(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);
        }
        for (OpcloseTimeVo vo : vos){
            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> searchCloseTimes(List<String> addrCodes, List<String> typeCodeBys) {
        List<String> addrs = new ArrayList<>();
        if (addrCodes != null){
            if (addrCodes.size() != 0)
                for (String addr : addrCodes){
                    List<String> otherAddrCode = categoryUtil.getAllOtherAddrCode(addr);
                    addrs.addAll(otherAddrCode);
                }
            else
                addrs = null;
        }else
            addrs = null;
        List<String> types = new ArrayList<>();
        if (typeCodeBys != null){
            if (typeCodeBys.size() != 0)
                for (String type : typeCodeBys){
                    List<String> otherTypeBy = categoryUtil.getAllOtherTypeBy(type);
                    types.addAll(otherTypeBy);
                }
            else
                types = null;
        }else
            types = null;
        List<OpcloseTimeVo> vos = storeWdOpcloseDao.selectWdCloseTimes(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);
        }
        for (OpcloseTimeVo vo : vos){
            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<WdAddrTypeDistribution> searchAddrTypeDistribution(List<String> addrCodes, List<String> typeCodes) {
//        List<String> acodes = new ArrayList<>();
//        for (String s : addrCodes){
//            List<String> allOtherAddrCode = getAllOtherAddrCode(s);
//            acodes.addAll(allOtherAddrCode);
//        }
//        List<WdAddrTypeDistribution> list = wdInfoMapper.searchAddrDisByMulti(acodes, typeCodes);
//        setTypeMap();
//        setAddrMap();
//        for (WdAddrTypeDistribution wd : list){
//            wd.setTypeName(typeMap.get(wd.getTypeCode()));
//            wd.setAddrName(addrMap.get(wd.getAddrCode()));
//        }
//        return list;
//    }

//    @Override
//    public List<WdAddrTypeDistribution> searchWdTypeDistribution(List<String> addrCodes, List<String> typeCodes) {
//        List<WdAddrTypeDistribution> list = wdInfoMapper.searchWdTypeDisByMulti(addrCodes, typeCodes);
//        setAddrMap();
//        setWdTypeMap();
//        for (WdAddrTypeDistribution wd : list){
//            wd.setAddrName(addrMap.get(wd.getAddrCode()));
//            wd.setTypeName(wdTypeMap.get(wd.getTypeCode()));
//        }
//        return list;
//    }

//    @Override
//    public List<WdAddrTypeDistribution> searchWdTotal() {
//        List<WdAddrTypeDistribution> list = wdInfoMapper.searchWdTotal();
//        setWdTypeMap();
//        for (WdAddrTypeDistribution wd : list){
//            wd.setTypeName(wdTypeMap.get(wd.getTypeCode()));
//        }
//        return list;
//    }

}
