package com.desfate.chart.ui.old.OTC.datas;


import com.desfate.chart.util.ByteUtils;

import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;

public class HistoryCycle {
	// 单个历史周期数据的长度
    public final static int LENGTH = 36;

	public final static int LENGTHDAY = 40;  //日线是40

//	typedef struct tagCYCLE_DATA
//	{
//		int32_t		iOpen;			// 开盘价
//		int32_t		iHigh;			// 最高价
//		int32_t		iLow;			// 最低价
//		int32_t		iClose;			// 收盘价
//		double		iVolumn;		// 总买量
//		double		iTurnover;		// 总金额
//		int32_t		iTime;			// 时间戳（UTC）
//	int 32 昨结
//	} CYCLE_DATA;

	// 开盘价
	private double opened;
	
	// 最高价
	private double highest;
	
	// 最低价
	private double lowest;
	
	// 收盘价
	private double closed;
	
	// 总量
	private double totleVolume;
	
	// 总额
	private double totleTurnover;
	
	// 开始时间
	private Date startTime;

    //结算价
    private double settlePrice;

	public double getOpened() {
		return opened;
	}

	public void setOpened(double opened) {
		this.opened = opened;
	}

	public double getHighest() {
		return highest;
	}

	public void setHighest(double highest) {
		this.highest = highest;
	}

	public double getLowest() {
		return lowest;
	}

	public void setLowest(double lowest) {
		this.lowest = lowest;
	}

	public double getClosed() {
		return closed;
	}

	public void setClosed(double closed) {
		this.closed = closed;
	}

	public double getTotleVolume() {
		return totleVolume;
	}

	public void setTotleVolume(double totleVolume) {
		this.totleVolume = totleVolume;
	}

	public double getTotleTurnover() {
		return totleTurnover;
	}

	public void setTotleTurnover(double totleTurnover) {
		this.totleTurnover = totleTurnover;
	}

	public Date getStartTime() {
		return startTime;
	}

	public void setStartTime(Date startTime) {
		this.startTime = startTime;
	}

    public double getSettlePrice() {
        return settlePrice;
    }

    public void setSettlePrice(double settlePrice) {
        this.settlePrice = settlePrice;
    }

	/**
	 * 将历史数据报文转换为周期数据list
	 * @param message
	 * @return
	 */
    public static ArrayList<HistoryCycle> toObject(HistoryQuoteResponse message){
        if(message == null){
            return null;
        }

        byte[] content = message.getContent();
        if(content == null){
            return null;
        }

        // 如果长度错误， 返回null
        if(content.length != LENGTH * message.getCount()){
            return null;
        }
        try {
            int index = 0;
            ArrayList<HistoryCycle> list = new ArrayList<HistoryCycle>();
            for (int i = 0; i < message.getCount(); i += 1) {
                HistoryCycle item = new HistoryCycle();
                // 服务端返回的是大端数据，统一使用大端处理
                int opened = ByteUtils.bytesToInt(content, index, ByteOrder.BIG_ENDIAN);
                index += 4;
                // 原始数据 再用上小数位才是最终数据
                item.setOpened(opened / Math.pow(10, message.getDecimalPlace()));
                int highest = ByteUtils.bytesToInt(content, index, ByteOrder.BIG_ENDIAN);
                index += 4;
                item.setHighest(highest / Math.pow(10, message.getDecimalPlace()));
                int lowest = ByteUtils.bytesToInt(content, index, ByteOrder.BIG_ENDIAN);
                index += 4;
                item.setLowest(lowest / Math.pow(10, message.getDecimalPlace()));
                int closed = ByteUtils.bytesToInt(content, index, ByteOrder.BIG_ENDIAN);
                index += 4;
                item.setClosed(closed / Math.pow(10, message.getDecimalPlace()));
                double totleVolume = ByteUtils.bytesToDouble(content, index, ByteOrder.LITTLE_ENDIAN);
                index += 8;
                item.setTotleVolume(totleVolume);
                // 注意这里double的处理，服务端没有转为大端数据，服务默认为
                // 小端（double数据一般都遵循固定格式，不强调大小端）
                double totleTurnover = ByteUtils.bytesToDouble(content, index, ByteOrder.LITTLE_ENDIAN);
                index += 8;
                item.setTotleTurnover(totleTurnover);
                long utcSeconds = ByteUtils.bytesToInt(content, index, ByteOrder.BIG_ENDIAN);
                index += 4;
                Calendar calendar = Calendar.getInstance();
                // 这里一定要使用long，否则int不够会导致数据溢出
                calendar.setTimeInMillis(utcSeconds * 1000);
                item.setStartTime(calendar.getTime());
                list.add(item);
            }

            //
            list = filterRepeat(list);
            return list;
        } catch (Exception e) {
            int a = 1 + 2;
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 将历史数据报文转换为周期数据list
     *
     * @param message
     * @return
     */
    public static ArrayList<HistoryCycle> toDayObject(HistoryQuoteResponse message) {
        if (message == null) {
            return null;
        }

        byte[] content = message.getContent();
        if (content == null) {
            return null;
        }

        // 如果长度错误， 返回null
		if (content.length != LENGTHDAY * message.getCount()) {
			return null;
        }
        try {
            int index = 0;
            ArrayList<HistoryCycle> list = new ArrayList<HistoryCycle>();
            for (int i = 0; i < message.getCount(); i += 1) {
                HistoryCycle item = new HistoryCycle();
                // 服务端返回的是大端数据，统一使用大端处理
                int opened = ByteUtils.bytesToInt(content, index, ByteOrder.BIG_ENDIAN);
                index += 4;
                // 原始数据 再用上小数位才是最终数据
                item.setOpened(opened / Math.pow(10, message.getDecimalPlace()));
                int highest = ByteUtils.bytesToInt(content, index, ByteOrder.BIG_ENDIAN);
                index += 4;
                item.setHighest(highest / Math.pow(10, message.getDecimalPlace()));
                int lowest = ByteUtils.bytesToInt(content, index, ByteOrder.BIG_ENDIAN);
                index += 4;
                item.setLowest(lowest / Math.pow(10, message.getDecimalPlace()));
                int closed = ByteUtils.bytesToInt(content, index, ByteOrder.BIG_ENDIAN);
                index += 4;
                item.setClosed(closed / Math.pow(10, message.getDecimalPlace()));
                double totleVolume = ByteUtils.bytesToDouble(content, index, ByteOrder.LITTLE_ENDIAN);
                index += 8;
                item.setTotleVolume(totleVolume);
                // 注意这里double的处理，服务端没有转为大端数据，服务默认为
                // 小端（double数据一般都遵循固定格式，不强调大小端）
                double totleTurnover = ByteUtils.bytesToDouble(content, index, ByteOrder.LITTLE_ENDIAN);
                index += 8;
                item.setTotleTurnover(totleTurnover);
                long utcSeconds = ByteUtils.bytesToInt(content, index, ByteOrder.BIG_ENDIAN);
                index += 4;
                Calendar calendar = Calendar.getInstance();
                // 这里一定要使用long，否则int不够会导致数据溢出
                calendar.setTimeInMillis(utcSeconds * 1000);
                item.setStartTime(calendar.getTime());

				double price = ByteUtils.bytesToInt(content, index, ByteOrder.LITTLE_ENDIAN);
				index += 4;
				item.setSettlePrice(price / Math.pow(10, message.getDecimalPlace()));

				list.add(item);
			}

            //
            list = filterRepeat(list);
            return list;
        } catch (Exception e) {
            int a = 1+2;
            e.printStackTrace();
            return null;
        }
    }

	/**
	 * 过滤重复数据，规律，如果不是最新的，那就取最新的一条；如果是最新的几条数据重复了，就需要合并到最老的一条数据
	 */
	public static ArrayList<HistoryCycle> filterRepeat(ArrayList<HistoryCycle> list) {
		// 先处理尾部的重复
		ArrayList<HistoryCycle> end = new ArrayList<>();
		for (int a = list.size() - 1; a >= 0; a--) {
			if (a == list.size() - 1) {
				end.add(list.get(a));
			} else {
				if (end.get(end.size() - 1).getStartTime()
						.compareTo(list.get(a).getStartTime()) == 0) {// 如果相等，就添加到备份数据集合里
					end.add(list.get(a));
				} else {// 时间不同，就跳出
					break;
				}
			}
		}

		if (end.size() > 1) {// 如果有重复，需要处理
			// 移除元数据中的尾部重复的几条数据
			list.subList(0, list.size() - end.size());

			// 合并为一条
			HistoryCycle historyCycle = new HistoryCycle();
			for (int a = 0; a < end.size(); a++) {// 最新的一条数据在index处
				double closed = end.get(a).getClosed();
				double opened = end.get(a).getOpened();
				double lowest = end.get(a).getLowest();
				double highest = end.get(a).getHighest();
				if (a == end.size() - 1) {// 最老一个
					historyCycle.setOpened(opened);
					historyCycle.setStartTime(end.get(a).getStartTime());
				}
				if (a == 0) {// 最新的一条数据
					historyCycle.setClosed(closed);
				}
				if (historyCycle.getHighest() == 0 || historyCycle.getHighest() < highest) {
					historyCycle.setHighest(highest);
				}
				if (historyCycle.getLowest() == 0 || historyCycle.getLowest() > lowest) {
					historyCycle.setLowest(lowest);
				}
			}
		}

		// 再过滤中间的
		ArrayList<HistoryCycle> tem = new ArrayList<>();
		for (int a = 0; a < list.size(); a++) {
			if (tem.isEmpty()) {// 空时，直接加入
				tem.add(list.get(a));
			} else {
				if (list.get(a).getStartTime().compareTo(tem.get(tem.size() - 1).getStartTime()) == 0) {// 如果原数据中当前位置和目标中一致，说明有问题，需要替换掉目标中的一个
					tem.set(tem.size() - 1, list.get(a));
				} else {
					tem.add(list.get(a));
				}
			}
		}
		return tem;
	}


}
