package com.base.track.task.handler;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.base.api.client.PayloadRpcService;
import com.base.api.model.SatelliteAndInstanceRpcDTO;
import com.base.api.model.YxInfoBasisSatelliteRpcDTO;
import com.base.orbit.utils.FileUtil;
import com.base.orbit.utils.IdGenerator;
import com.base.orbit.utils.StringUtil;
import com.base.task.handler.TaskHandler;
import com.base.task.model.Enums.TaskTypeEnum;
import com.base.task.model.Mapping;
import com.base.task.model.Task;
import com.base.track.config.sharding.ShardingAlgorithmTool;
import com.base.track.config.sharding.enums.ShardingTableCacheEnum;
import com.base.track.mapper.SubPointDataMapper;
import com.base.track.model.entity.*;
import com.base.track.service.CalService;
import com.base.track.service.SubPointDataService;
import com.base.track.thread.SubPointThread;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


@Mapping(taskTypeEnum = TaskTypeEnum.SUB_POINT)
@Service
@Slf4j
public class SubPointTaskHandler implements TaskHandler {
    @Resource
    PayloadRpcService yxInfoSatellitePayloadService;

    @Resource
    SubPointDataService subPointDataService;

    @Resource
    CalService calService;

    @Resource
    SubPointThread subPointThread;
    @Resource
    SubPointDataMapper subPointDataMapper;



    @Override
    public void taskExecute(Task task) {
        try {
            log.info("星下点入库");
            String startTime=task.getStartTime();
            String endTime=task.getEndTime();

            List<SatelliteAndInstanceRpcDTO> satelliteAndInstances = calService.groupingData(task.getSatelliteCodes());
            for (SatelliteAndInstanceRpcDTO satelliteAndInstance : satelliteAndInstances) {
                YxInfoBasisSatelliteRpcDTO yxInfoBasisSatellite=satelliteAndInstance.getYxInfoBasisSatelliteDTO();
                // 星下点的处理方法 根据ID获取卫星的数据和卫星的载荷
                SatellitePara satellitePara = subPointThread.findThisEphData(yxInfoBasisSatellite);

                DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");

                FileInputStream fileInputStream = new FileInputStream(task.getResultDataSavePath()+task.getResultDataSaveName());
                InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);
                BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
                System.out.println("===========读取到星下点数据===========");
                // 每行数据
                String result;
                // 执行的行数
                int line = 0;
                // 初始数据
                List<SubPointData> subPointDataList = new ArrayList<>();
                // 遍历结果文件数据
                String code = StringUtil.change(yxInfoBasisSatellite.getSatelliteCode());
                while ((result = bufferedReader.readLine()) != null) {
                    if (line != 0 && line != 1) {
                        // 数据转换
                        List<String> r = FileUtil.getLineArray(result);
                        String dateStr = r.get(0) + " " + r.get(1);

                        Date date = sdf.parse(dateStr);
                        SubPointData subpointData = new SubPointData();
                        subpointData.setId(String.valueOf(IdGenerator.getId()));
                        subpointData.setSatelliteId(yxInfoBasisSatellite.getId());
                        subpointData.setCode(code);
                        subpointData.setSatelliteCode(yxInfoBasisSatellite.getSatelliteCode());
                        subpointData.setDate( new Date(date.getTime()+8*3600*1000));
                        subpointData.setLon(Double.parseDouble(r.get(2)));
                        subpointData.setLat(Double.parseDouble(r.get(3)));
                        subpointData.setAlt(Double.parseDouble(r.get(4)));
                        subpointData.setOrbit(r.get(5));
                        subpointData.setUpdown(r.get(6));
                        subPointDataList.add(subpointData);
                    }
                    line++;
                }
                String codemin=code.toLowerCase();
                boolean cj=true;
                if (ShardingAlgorithmTool.getShardingTable(ShardingTableCacheEnum.SUBPOINT,"subpoint_"+codemin)){
                    cj=false;
                    // 删除表中该时间内的信息
                    QueryWrapper<SubPointData> wrapper=new QueryWrapper<>();
                    wrapper.ge("date",startTime);
                    wrapper.le("date",endTime);
                    wrapper.eq("code",code);
                    subPointDataService.remove(wrapper);
                }
                // 遍历星下点信息
                for (int i = 0; i < subPointDataList.size() - 1; i++) {
                    SubPointData subPointThis = subPointDataList.get(i);
                    SubPointData subPointNext = subPointDataList.get(i + 1);
                    Double latThis = subPointThis.getLat();
                    Double latNext = subPointNext.getLat();

                    // 获取前一颗星的Position
                    LatLon latLon = LatLon.fromDegrees(subPointThis.getLat(), subPointThis.getLon());
                    Position positionThis = new Position(latLon, subPointThis.getAlt());
                    //获取下一颗星的position
                    LatLon latLon1 = LatLon.fromDegrees(subPointNext.getLat(), subPointNext.getLon());
                    Position positionNext = new Position(latLon1, subPointNext.getAlt());

                    // 星下点,下个星下点,幅宽,length重叠区域,theta侧摆角
                    FSideAngleSurfaceGrid fSideAngleSurfaceGridR = new FSideAngleSurfaceGrid(positionThis, positionNext, satellitePara.getSWATH_WIDTH() / 2, satellitePara.getOVER_LAP(), satellitePara.getMaxrollangle());
                    FSideAngleSurfaceGrid fSideAngleSurfaceGridStrip = new FSideAngleSurfaceGrid(positionThis, positionNext, satellitePara.getSWATH_WIDTH() / 2, satellitePara.getOVER_LAP(), 0);

                    LatLon data0, data1, dataSt0, dataSt1;
                    if (latThis < latNext) {
                        // 这儿是升轨的时候
                        data1 = fSideAngleSurfaceGridR.getPointSec();
                        data0 = fSideAngleSurfaceGridR.getPointThr();
                        dataSt1 = fSideAngleSurfaceGridStrip.getPointSec();
                        dataSt0 = fSideAngleSurfaceGridStrip.getPointThr();
                    } else {
                        // 不是升轨的时候
                        data0 = fSideAngleSurfaceGridR.getPointSec();
                        data1 = fSideAngleSurfaceGridR.getPointThr();
                        dataSt0 = fSideAngleSurfaceGridStrip.getPointSec();
                        dataSt1 = fSideAngleSurfaceGridStrip.getPointThr();
                    }

                    // 侧摆左点经纬度
                    Double lr_lon = data0.longitude.getDegrees();
                    Double lr_lat = data0.latitude.getDegrees();
                    // 侧摆右点经度
                    Double rr_lon = data1.longitude.getDegrees();
                    Double rr_lat = data1.latitude.getDegrees();
                    // 幅宽左点经度
                    Double ls_lon = dataSt0.longitude.getDegrees();
                    Double ls_lat = dataSt0.latitude.getDegrees();
                    // 幅宽左点经度
                    Double rs_lon = dataSt1.longitude.getDegrees();
                    Double rs_lat = dataSt1.latitude.getDegrees();
                    subPointThis.setLrLon(lr_lon);
                    subPointThis.setLrLat(lr_lat);
                    subPointThis.setRrLon(rr_lon);
                    subPointThis.setRrLat(rr_lat);
                    subPointThis.setLsLon(ls_lon);
                    subPointThis.setLsLat(ls_lat);
                    subPointThis.setRsLon(rs_lon);
                    subPointThis.setRsLat(rs_lat);

                }
/*                if (cj){
                    SubPointData subPointData=subPointDataList.get(0);
                    subPointDataService.save(subPointData);
                    subPointDataList.remove(subPointData);
                }
                subPointDataMapper.batch(subPointDataList,codemin);*/
             /*   for (SubPointData subPointData:subPointDataList){
                    subPointDataService.save(subPointData);
                }*/
                subPointDataService.saveBatch(subPointDataList);
                //发送消息
                log.info("计算完成");
                /*task.getCountDownLatch().countDown();*/
                System.out.println(task);
            }

        }catch (Exception e){
            log.error(e.getMessage(),e);
        }finally {
            task.getCountDownLatch().countDown();
        }

    }
}
