package org.dromara.system.controller;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.redis.utils.RedisUtils;
import org.dromara.common.web.core.BaseController;
import org.dromara.system.domain.GpsData;
import org.dromara.system.domain.TblCarInfo;
import org.dromara.system.domain.bo.*;
import org.dromara.system.domain.vo.*;
import org.dromara.system.service.*;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;

/**
 * 车辆信息
 *
 * @author Lion Li
 * @date 2024-02-22
 */
@Validated
@RequiredArgsConstructor
@RestController
@Slf4j
@RequestMapping("/system")
public class TblGpsDataController extends BaseController {

    private final ITblGpsDataService gpsDataService;

    private final ITblCountDataService countDataService;

    private final ISysDictDataService sysDictDataService;

    private final ITblCarScheduleService carScheduleService;
    private final ITblCarInfoService carInfoService;

    /**
     * 查询车辆信息列表
     */
    //@SaCheckPermission("system:carInfo:list")
    @GetMapping("/gpsdata/list")
    public TableDataInfo<GpsDataVo> list(GpsDataBo bo, PageQuery pageQuery) {
        return gpsDataService.queryPageList(bo, pageQuery);
    }


    /**
     * 查询设备人流量
     */
    @GetMapping("/peoplecount/list")
    public Object list(CountDataBo bo) {
        if(bo.getCarNum()!=null){
            try {
                TblCarInfoBo carbo = new TblCarInfoBo();
                carbo.setCarNum(bo.getCarNum());
                List<TblCarInfoVo> list= carInfoService.queryList(carbo);
                if(list.size()>0){
                    JSONUtil.parseArray( list.get(0).getDeviceInfos()).toList(JSONObject.class).forEach(deviceInfo -> {
                        if (deviceInfo.getStr("type").equals("people_count")) {
                            bo.setDevicecode(deviceInfo.getStr("code"));
                            bo.setCarNum(null);
                        }
                    });
                }
                if(bo.getDevicecode()==null){
                    List<Map> ret = new ArrayList<>();
                    Map<String,Object> data = new HashMap<>();
                    data.put("totalin",0);
                    data.put("totalout",0);
                    ret.add(data);

                    return R.ok(ret);
                }
            }catch (Exception e){}
        }
        if(bo.getParams()!=null && bo.getParams().get("times")!=null){
            List<Map> ret = new ArrayList<>();
           String [] times = bo.getParams().get("times").toString().split("\\$");
            for (int i = 0; i <times.length ; i++) {
               String [] dates = times[i].split("\\|");
               bo.getParams().put("starttime",dates[0]);
               bo.getParams().put("endtime",dates[1]);
                List<CountDataVo> dataVos = countDataService.queryList(bo);
                Map<String,Object> data = new HashMap<>();
                int totalin = 0;
                int totalout = 0;
                for (int j = 0; j < dataVos.size(); j++) {
                    totalin+=dataVos.get(j).getIncount();
                    totalout+=dataVos.get(j).getOutcount();
                }
                data.put("totalin",totalin);
                data.put("totalout",totalout);

                ret.add(data);

            }
            return R.ok(ret);

        }else{
            List<CountDataVo> dataVos = countDataService.queryList(bo);
            Map<String,Object> data = new HashMap<>();
            int totalin = 0;
            int totalout = 0;
            for (int i = 0; i < dataVos.size(); i++) {
                totalin+=dataVos.get(i).getIncount();
                totalout+=dataVos.get(i).getOutcount();
            }
            data.put("totalin",totalin);
            data.put("totalout",totalout);
            return R.ok(data);
        }



    }


    /**
     * 查询站点人流量列表
     */
    @GetMapping("/sites/flow")
    public TableDataInfo<SysDictDataVo> listFalow(SysDictDataBo bo, PageQuery pageQuery) {

        bo.setDictType("tbl_sites");
        //查询站点
        TableDataInfo<SysDictDataVo>  sites = sysDictDataService.selectPageDictDataList(bo, pageQuery);


        List<TblCarScheduleVo> usedSchedule = new ArrayList<>();
        //查询时间段内包含上述站点的排班
        TblCarScheduleBo bo1 = new TblCarScheduleBo();
        bo1.setParams(bo.getParams());
        List<TblCarScheduleVo> scheduleVos =  carScheduleService.queryList(bo1);
        scheduleVos.forEach(item->{
            if(!StrUtil.isEmptyIfStr(item.getExt1())){
                for (int i = 0; i < sites.getRows().size(); i++) {
                    SysDictDataVo site = sites.getRows().get(i);
                    if(item.getExt1().contains(site.getDictLabel())){
                        usedSchedule.add(item);
                        break;
                    }
                }
            }
        });
        if(usedSchedule.size()<1) return sites;
        //获取车牌
        TblCarInfoBo bo3 = new TblCarInfoBo();
        bo3.getParams().put("carNums",usedSchedule.stream().map(TblCarScheduleVo::getCarNum).toList());
        List<TblCarInfoVo> carInfoVos =  carInfoService.queryList(bo3);
        //  站点        设备     时间范围
        Map<String,Map<String,List<Map<String,String>>>> sitesMap = new HashMap<>();

        //车牌设备
        Map<String,List<String>> deviceMap = new HashMap<>();
        carInfoVos.forEach(item->{
            JSONUtil.parseArray(item.getDeviceInfos()).toList(JSONObject.class).forEach(deviceInfo -> {
                try {
                    if(deviceInfo.getStr("type").contains("people_count")){
                       if(deviceMap.get(item.getCarNum())==null) deviceMap.put(item.getCarNum(),new ArrayList<>());
                       deviceMap.get(item.getCarNum()).add(deviceInfo.getStr("code"));
                    }

                }catch (Exception e){}

            });
        });
        //{
        //    "程家垄": {
        //        "intime": "2024-05-07 10:48:34",
        //        "outtime": "2024-05-07 10:48:39"
        //    },
        //    "福安客运站": {
        //        "intime": "2024-05-07 10:47:42",
        //        "outtime": "2024-05-07 10:48:01"
        //    }
        //}
        usedSchedule.forEach(item->{
            if(deviceMap.get(item.getCarNum())!=null) {
                JSONObject ext1 = JSONUtil.parseObj(item.getExt1());
                for (String key : ext1.keySet()) {
                    if (sitesMap.get(key) == null) {
                        sitesMap.put(key, new HashMap<>());
                    }
                    Map<String, List<Map<String, String>>> ideviceMap = sitesMap.get(key);
                    deviceMap.get(item.getCarNum()).forEach(deviceCode->{
                        if(ideviceMap.get(deviceCode)==null) ideviceMap.put(deviceCode,new ArrayList<>());
                        ideviceMap.get(deviceCode).add(ext1.get(key, Map.class));
                    });
                }
            }
        });
        log.info("{}",JSONUtil.toJsonStr(sitesMap));
        Map<String,Map<String,Object>> sitesc = new HashMap<>();
        sitesMap.forEach((key,value)->{
            AtomicReference<Integer> incount = new AtomicReference<>(0);
            AtomicReference<Integer> outcount = new AtomicReference<>(0);
            value.forEach((deviceCode,times)->{
                times.forEach(time->{
                    if(time.get("intime")==null||time.get("outtime")==null){
                        return;
                    }
                    CountDataBo bo2 = new CountDataBo();
                    bo2.getParams().put("starttime",time.get("intime"));
                    bo2.getParams().put("endtime",time.get("outtime"));
                    bo2.setDevicecode(deviceCode);
                    List<CountDataVo> countDataVos = countDataService.queryList(bo2);
                    countDataVos.forEach(item1->{
                        incount.updateAndGet(v -> v + item1.getIncount());
                        outcount.updateAndGet(v -> v + item1.getOutcount());
                    });
                });
            });
            sitesc.put(key,Map.of("incount",incount.get(),"outcount",outcount.get()));
        });

        sites.getRows().forEach(item->{
            item.setOthers(new HashMap<>());
            if(sitesc.get(item.getDictLabel())!=null){
                item.setOthers(sitesc.get(item.getDictLabel()));
            }else{
                item.getOthers().put("incount",0);
                item.getOthers().put("outcount",0);
            }
        });


//        //查询人流量数据
//        CountDataBo bo2 = new CountDataBo();
//        bo2.getParams().put("starttime",bo.getParams().get("starttime"));
//        bo2.getParams().put("endtime",bo.getParams().get("endtime"));
//        bo2.getParams().put("deviceCodes",);
//        countDataService.queryList(bo2)
//
//
//
//        //根据排班查询车辆在站点时间
//        for (TblCarScheduleVo scheduleVo : usedSchedule) {
//
//        }


        //根据车辆查人流量数据

        //统计

        return sites;

//        return gpsDataService.queryPageList(bo, pageQuery);
    }


}
