package com.base.orbit.utils;



import com.base.orbit.utils.tool.DateTool;
import com.base.orbit.utils.tool.MyArray;
import com.base.orbit.utils.tool.TeminatorDeal;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.*;


/**
 * @author elqeb
 * Time: 2023/4/14 - 11:10
 */
public class CalcTerminatorUtil {
    /**
     * 计算日出日落时间
     *
     * @param startTime
     * @param endTime
     * @param longitude
     * @param latitude
     * @return List<Date>
     */
    public static List<Date> calcTerminator(Date startTime, Date endTime, double longitude, double latitude) {
        Calendar c1 = Calendar.getInstance();
        HashMap<Integer, Date> so = new HashMap<>(4);
        List<Date> list = new ArrayList<>();
        c1.setTime(startTime);
        String startString = DateTool.DateToString(startTime);
        int dayStart = c1.get(Calendar.DAY_OF_YEAR);
        Calendar c2 = Calendar.getInstance();
        long starttimeLong = startTime.getTime();
        long endtimeLong = endTime.getTime();
        c2.setTime(endTime);
        System.err.println(startTime);
        System.err.println(endTime);
        System.err.println(longitude + "-----------" + latitude);
        int dayEnd = c2.get(Calendar.DAY_OF_YEAR);
        MyArray[] arrays = new MyArray[(dayEnd - dayStart + 1) * 2];
        so = TeminatorDeal.getSunTimeAtDate(startTime, longitude, latitude, startString);
        int i = 0;
        for (; i < 2; i++) {
            arrays[i] = new MyArray();
            arrays[i].setValue(so.get(i));
            arrays[i].setSubscript(i);
        }
        Date flagDate = startTime;
        for (int j = dayStart + 1; j <= dayEnd; j++) {
            try {
                flagDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(DateTool.getDelayOneDay(flagDate, 1));
            } catch (ParseException e) {
                e.printStackTrace();
            }
            String str = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(flagDate);
            String d = str.toString().substring(0, 11);
            so = TeminatorDeal.getSunTimeAtDate(flagDate, longitude, latitude, d);
            int temp = 0;
            for (; temp < 2; temp++) {
                arrays[i] = new MyArray();
                arrays[i].setValue(so.get(temp));
                arrays[i].setSubscript(temp);
                i++;
            }
            temp = 0;
        }
        for (int k = 0; k < arrays.length; k++) {
            if (arrays[k].getValue().getTime() >= starttimeLong && arrays[k].getValue().getTime() <= endtimeLong) {
                list.add(arrays[k].getValue());
            }
        }
        if (list.size() == 0) {
            boolean t = starttimeLong > arrays[0].getValue().getTime() && endtimeLong < arrays[1].getValue().getTime();
            if (starttimeLong > arrays[0].getValue().getTime() && endtimeLong < arrays[1].getValue().getTime()) {
                arrays[0].setSubscript(0);
                arrays[1].setSubscript(1);
            } else {
                arrays[0].setSubscript(1);
                arrays[1].setSubscript(0);
            }
            arrays[0].setValue(startTime);
            arrays[1].setValue(endTime);
            list.add(arrays[0].getValue());
            list.add(arrays[1].getValue());
        }
        for (int k = 0; k < list.size(); k++) {
            System.err.println(list.get(k));
        }
        return list;
    }

    /**
     * 计算太阳高度角
     * @param Longitude
     * @param Latitude
     * @param time
     * @return double
     */
    public static double SunPositionNR(double Longitude, double Latitude, Date time) {
        LocalDateTime localDateTime =time.toInstant().atOffset(ZoneOffset.of("+8")).toLocalDateTime();
        double year =  localDateTime.getYear();
        double month =localDateTime.getMonthValue();
        double day =localDateTime.getDayOfMonth();
        double hour =localDateTime.getHour();
        double minute =localDateTime.getMinute();

        double height;
        double A = year / 4;
        double B = A - Math.floor(A);
        double C = 32.8;
        if (month <= 2) {
            C = 30.6;
        }
        if (B == 0 && month > 2) {
            C = 31.8;
        }
        double G = Math.floor(30.6 * month - C + 0.5) + day;
        double L = Longitude / 15.0;                    //经度修正
        double H = hour - 8 + minute / 60.0;              //时刻修正
        double N = G + (H - L) / 24.0;                      //计算积日
        double theta, NO;     //theta为日角
        NO = 79.6764 + 0.2422 * (year - 1985) - Math.floor((year - 1985) / 4.0);
        theta = 2 * Math.PI * (N - NO) / 365.2422;

        double lat;//赤纬角
        lat = 0.3723 + 23.2567 * Math.sin(theta) + 0.1149 * Math.sin(2 * theta) - 0.1712 * Math.sin(3 * theta) - 0.758 * Math.cos(theta) + 0.3656 * Math.cos(2 * theta) + 0.0201 * Math.cos(3 * theta);
        lat = lat * Math.PI / 180.0;

        double Et;//时差（以分钟为单位）
        Et = 0.0028 - 1.9857 * Math.sin(theta) + 9.9059 * Math.sin(2 * theta) - 7.0924 * Math.cos(theta) - 0.6882 * Math.cos(2 * theta);

        double timeAngle;//时角
        timeAngle = ((hour - 12) + (minute - (120.0 - Longitude) * 4.0 + Et) / 60.0) * 15.0;
        timeAngle = timeAngle * Math.PI / 180.0;

        // 将纬度由角度转换为弧度
        Latitude = Latitude * Math.PI / 180.0;

        // 太阳高度角
        height = Math.sin(Latitude) * Math.sin(lat) + Math.cos(Latitude) * Math.cos(lat) * Math.cos(timeAngle);
        height = Math.asin(height);
        return Math.toDegrees(height);
    }
}
