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


import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;


/**
 * 做市行情盘面,做市的商品盘面数据
 * 主要特点：1.没有量，换手率
 *
 * @author yongzq
 */
public class MMQuoteDay extends QuoteDayBase {

    private MMQuoteDay() {

    }

    // 前一口价，用来判断涨跌的方向和数值
    private String prePrice;

    // 价格升降标志，和上一口比较
    private int raisedFlag = -1;

    // 涨跌标志，和昨收比
    private int upDown = -1;

    // 交易日
    private String exchangeTime;

    /**
     * 构造方法
     *
     * @param exchangeCode 交易所代码
     * @param goodsCode    商品goodsdcode
     */
    public MMQuoteDay(int exchangeCode, String goodsCode) {
        this.setExchangeCode(exchangeCode);
        this.setGoodsCode(goodsCode);
    }


    @Override
    public int getRaisedFlag() {
        return this.raisedFlag;
    }

    @Override
    public int getUpDown() {
        return this.upDown;
    }

    public void setUpDown(int upDown) {
        this.upDown = upDown;
    }

    public String getExchangeTime() {
        return exchangeTime;
    }

    public void setExchangeTime(String exchangeTime) {
        this.exchangeTime = exchangeTime;
    }

    /**
     * 从quotetik更新一些字段
     *
     * @param tik
     */
    private void updateFromTik(QuoteTik tik) {
        HashMap<Byte, Object> fields = tik.getFields();
        Iterator<Byte> item = fields.keySet().iterator();
        while (item.hasNext()) {
            String value;
            Byte keyB = item.next();
            byte key = keyB.byteValue();
            switch (key) {
                case QuoteTikPart.Ask:// 卖价
                    value = fields.get(keyB).toString();
                    setAsk(value);
                    break;

                case QuoteTikPart.Bid:// 买价
                    value = fields.get(keyB).toString();
                    setBid(value);
                    break;

                case QuoteTikPart.Last:// 现价
                    value = fields.get(keyB).toString();
                    if (value != null && !value.equals("") && Double.parseDouble(value) > 0) {
                        setPrice(value);
                    }
                    break;

                case QuoteTikPart.DecimalPlace:// 小数位
                    int decimalPlace = Integer.parseInt(fields.get(keyB).toString());
                    if (decimalPlace >= 0) {
                        setDecimalPlace(decimalPlace);
                    }
                    break;
                case QuoteTikPart.ExchangeTime: {
                    String time = (String) fields.get(keyB);
                    setExchangeTime(time);
                    break;
                }
                default:
                    break;
            }
        }
    }

    /**
     * 使用现价更新一系列数据
     */
    private void updateByLast() {
        try {
            if (getPrice().equals("0")) {
                return;
            }

            if (this.prePrice == null) {
                this.prePrice = getPrice();
            } else {
                // 设置价格变动方向
                if (Double.parseDouble(this.prePrice) < Double.parseDouble(getPrice())) {
                    this.raisedFlag = 1;
                } else if (Double.parseDouble(this.prePrice) > Double.parseDouble(getPrice())) {
                    this.raisedFlag = 2;
                } else {
                    this.raisedFlag = 0;
                }

                this.prePrice = getPrice();
            }

            // 设置涨跌
            if (getPreClose() != null) {
                if (Double.parseDouble(getPrice()) > Double.parseDouble(getPreClose())) {
                    this.upDown = 1;
                } else if (Double.parseDouble(getPrice()) < Double.parseDouble(getPreClose())) {
                    this.upDown = 2;
                } else {
                    this.upDown = 0;
                }
            }
            double price = Double.parseDouble(getPrice());
            if (canUseQuote()) {
                if (getOpened() == null || getOpened().isEmpty() || Double.parseDouble(getOpened()) == 0) {
                    setOpened(this.getPrice());
                }

                if (getHighest() == null || getHighest().isEmpty() || Double.parseDouble(getHighest()) == 0) {
                    setHighest(this.getPrice());
                }
                if (getLowest() == null || getLowest().isEmpty() || Double.parseDouble(getLowest()) == 0) {
                    setLowest(this.getPrice());
                }
                if (price > 0) {
                    setHighest(price > Double.parseDouble(getHighest()) ? getPrice() : getHighest());
                    setLowest(price < Double.parseDouble(getLowest()) ? getPrice() : getLowest());
                }

            }

            // 计算涨跌和涨幅
            if (getPrice() != null && !getPrice().isEmpty() && getPreClose() != null && !getPreClose().isEmpty()) {
                double preClose = Double.parseDouble(getPreClose());// 涨跌幅用昨结计算);
                if (price == 0 || preClose == 0) {
                    setUpDownValue("--");
                    setUpDownRange("--");
                } else {
                    setUpDownValue(price - preClose + "");
                    setUpDownRange(((price - preClose) * 100) / preClose + "");
                }
            }

            // 计算振幅
            if (getHighest() != null && !getHighest().isEmpty() &&
                    getLowest() != null && !getLowest().isEmpty() &&
                    getPreClose() != null && !getPreClose().isEmpty()
                    && Double.parseDouble(getPreClose()) > 0) {
                double highest = Double.parseDouble(getHighest());
                double lowest = Double.parseDouble(getLowest());
                double preClose = Double.parseDouble(getPreClose());
                if (preClose == 0) {
                    setAmplitude("--");
                } else {
                    setAmplitude(((highest - lowest) * 100) / preClose + "");
                }
            } else {
                setAmplitude("--");
            }
        } catch (NumberFormatException e) {
//            LogUtils.e("quote", "MMQuoteDay updateByLast error");
            e.printStackTrace();
        }
    }

    /**
     * 更新时间等数据
     *
     * @param atTime
     */
    private void updateTime(Date atTime) {
        if (getLastTime().before(atTime)) {
            setLastTime(atTime);
        }

        if (getOpenTime() == null) {
            setOpenTime(atTime);
        }
    }

    /**
     * 暂时不用，直接返回true
     *
     * @param atTime
     * @return
     */
    private boolean inRang(Date atTime) {
        return true;
    }


    /**
     * 合并盘面,当查询到盘面数据后，和现有的数据进行合并
     */
    @Override
    public void inputDayQuote(QuoteTik tik) {
        MMQuoteDay quoteDay = toDayQuote(tik);
        double price = Double.parseDouble(getPrice());
        if (quoteDay.getLastTime() != null && getLastTime() != null && quoteDay.getLastTime().before(getLastTime())) {
            // 如果刚登陆并且行情很快的情况下，这时候请求盘面回来，盘面时间可能比行情时间早，要赋值最高最低等价格
            if (quoteDay.getHighest() != null) {
                double preHighest = Double.parseDouble(quoteDay.getHighest());
                double cruHighest = Double.parseDouble(getHighest());
                setHighest((cruHighest > preHighest ? cruHighest : preHighest) + "");
            }
            if (quoteDay.getLowest() != null) {
                double preLowest = Double.parseDouble(quoteDay.getLowest());
                double cruLowest = Double.parseDouble(quoteDay.getLowest());
                setLowest((cruLowest < preLowest ? cruLowest : preLowest) + "");
            }

            if (quoteDay.getOpened() != null) {
                setOpened(quoteDay.getOpened());
            }

            if (quoteDay.getOpenTime() != null) {
                setOpenTime(quoteDay.getOpenTime());
            }

            setPreSettle(quoteDay.getPreSettle());
            setStrPctChange(quoteDay.getStrPctChange());
            double preSettle = 0;
            try {
                preSettle = Double.parseDouble(quoteDay.getPreSettle());
            } catch (Exception e) {
                // TODO: handle exception
            }

            if (preSettle > 0) {
                setPreClose(quoteDay.getPreSettle());
            } else {
                setPreClose(quoteDay.

                        getPreClose());
            }

            setSettle(quoteDay.getSettle());

            // 计算涨跌和涨幅  要在昨收赋值后做
            if (getPrice() != null && !getPrice().isEmpty() && getPreClose() != null && !getPreClose().isEmpty()) {
                double preClose = Double.parseDouble(getPreClose());// 涨跌幅用昨结计算
                if (price == 0 || preClose == 0) {
                    setUpDownValue("--");
                    setUpDownRange("--");
                } else {
                    setUpDownValue(price - preClose + "");
                    setUpDownRange(((price - preClose) * 100) / preClose + "");
                }
            }

            // 计算振幅
            if (getHighest() != null && !getHighest().isEmpty() &&
                    getLowest() != null && !getLowest().isEmpty() &&
                    getPreClose() != null && !getPreClose().isEmpty()) {
                double highest = Double.parseDouble(getHighest());
                double lowest = Double.parseDouble(getLowest());
                double preClose = Double.parseDouble(getPreClose());
                if (preClose == 0) {
                    setAmplitude("--");
                } else {
                    setAmplitude(((highest - lowest) * 100) / preClose + "");
                }
            } else {
                setAmplitude("--");
            }
            return;
        }
        // 正常情况下，更新以下字段
        if (quoteDay.getOpened() != null) {
            setOpened(quoteDay.getOpened());
        }

        if (quoteDay.getOpenTime() != null) {
            setOpenTime(quoteDay.getOpenTime());
        }

        if (quoteDay.getPrice() != null) {
            setPrice(quoteDay.getPrice());
        }

        if (quoteDay.getAsk() != null) {
            setAsk(quoteDay.getAsk());
        }

        if (quoteDay.getBid() != null) {
            setBid(quoteDay.getBid());
        }

        if (quoteDay.getHighest() != null) {
            double preHighest = Double.parseDouble(quoteDay.getHighest());
            double cruHighest = Double.parseDouble(getHighest());
            setHighest((cruHighest > preHighest ? cruHighest : preHighest) + "");
        }
        if (quoteDay.getLowest() != null) {
            double preLowest = Double.parseDouble(quoteDay.getLowest());
            double cruLowest = Double.parseDouble(quoteDay.getLowest());
            setLowest((cruLowest < preLowest ? cruLowest : preLowest) + "");
        }

        if (quoteDay.getLastTime() != null) {
            if (getLastTime() == null || quoteDay.getLastTime().after(getLastTime())) {
                setLastTime(quoteDay.getLastTime());
            }
        }

        // 计算涨跌和涨幅
        if (getPrice() != null && !getPrice().isEmpty() && getPreClose() != null && !getPreClose().isEmpty()) {
            double preClose = Double.parseDouble(getPreClose());// 涨跌幅用昨结计算
            if (price == 0 || preClose == 0) {
                setUpDownValue("--");
                setUpDownRange("--");
            } else {
                setUpDownValue(price - preClose + "");
                setUpDownRange(((price - preClose) * 100) / preClose + "");
            }
        }

        // 计算振幅
        if (getHighest() != null && !getHighest().isEmpty() &&
                getLowest() != null && !getLowest().isEmpty() &&
                getPreClose() != null && !getPreClose().isEmpty()
                && Double.parseDouble(getPreClose()) > 0) {
            double highest = Double.parseDouble(getHighest());
            double lowest = Double.parseDouble(getLowest());
            double preClose = Double.parseDouble(getPreClose());
            if (preClose == 0) {
                setAmplitude("--");
            } else {
                setAmplitude(((highest - lowest) * 100) / preClose + "");
            }
        } else {
            setAmplitude("--");
        }
        setPreSettle(quoteDay.getPreSettle());
        setStrPctChange(quoteDay.getStrPctChange());
        double preSettle = 0;
        try {
            preSettle = Double.parseDouble(quoteDay.getPreSettle());
        } catch (Exception e) {
            // TODO: handle exception
        }

        if (preSettle > 0) {
            setPreClose(quoteDay.getPreSettle());
        } else {
            setPreClose(quoteDay.getPreClose());
        }


        setSettle(quoteDay.getSettle());
    }

    /**
     * 将tik数据转换为盘面对象
     *
     * @param tik
     * @return
     */
    public static MMQuoteDay toDayQuote(QuoteTik tik) {
//		if(tik.getAtTime() == null){// FIXME: 2018/1/11 只要是服务端下发的，值都有效
//			return null;
//		}

        MMQuoteDay quoteDay = new MMQuoteDay();
        quoteDay.setAsk(tik.getAsk());
        quoteDay.setBid(tik.getBid());
        quoteDay.setLastTime(tik.getAtTime());
        quoteDay.setOpenTime(tik.getAtTime());
        quoteDay.setDecimalPlace(tik.getDecimalPlace());
        quoteDay.setExchangeCode(tik.getExchangeCode());
        quoteDay.setGoodsCode(tik.getGoodsCode());
        quoteDay.setHighest(tik.getValue((byte) QuoteTikPart.Highest));
        quoteDay.setGoodsCode(tik.getGoodsCode());
        quoteDay.setLowest(tik.getValue((byte) QuoteTikPart.Lowest));
        quoteDay.setOpened(tik.getValue((byte) QuoteTikPart.Opened));
        quoteDay.setPrice(tik.getValue(QuoteTikPart.Last));
        quoteDay.setExchangeTime(tik.getValue(QuoteTikPart.ExchangeTime));
        // 昨收用昨结算赋值
        double preSettle = 0;
        try {
            preSettle = Double.parseDouble(quoteDay.getPreSettle());
        } catch (Exception e) {
            // TODO: handle exception
        }

        if (preSettle > 0) {
            quoteDay.setPreClose(preSettle + "");
        } else {
            quoteDay.setPreClose(tik.getValue((byte) QuoteTikPart.PreClose));
        }
        quoteDay.setPreSettle(tik.getValue(QuoteTikPart.PreSettle));
        quoteDay.setStrPctChange(tik.getValue(QuoteTikPart.ChangePercent));
        quoteDay.setSettle(tik.getValue(QuoteTikPart.Settle));
        if (quoteDay.getPreClose() != null && quoteDay.getPrice() != null) {
            // 跌
            if (Double.parseDouble(quoteDay.getPreClose()) > Double.parseDouble(quoteDay.getPrice())) {
                quoteDay.setUpDown(2);
            }
            // 涨
            if (Double.parseDouble(quoteDay.getPreClose()) < Double.parseDouble(quoteDay.getPrice())) {
                quoteDay.setUpDown(1);
            }
        }
        double price = Double.parseDouble(quoteDay.getPrice());
        if (quoteDay.getPrice() != null && !quoteDay.getPrice().isEmpty() && quoteDay.getPreClose() != null && !quoteDay.getPreClose().isEmpty()) {
            double preClose = Double.parseDouble(quoteDay.getPreSettle()); // 涨跌幅用昨结计算
            if (price == 0 || preClose == 0) {
                quoteDay.setUpDownValue("--");
                quoteDay.setUpDownRange("--");
            } else {
                quoteDay.setUpDownValue(price - preClose + "");
                quoteDay.setUpDownRange(((price - preClose) * 100) / preClose + "");
            }
        }

        // 计算振幅
        if (quoteDay.getHighest() != null && !quoteDay.getHighest().isEmpty() &&
                quoteDay.getLowest() != null && !quoteDay.getLowest().isEmpty() &&
                quoteDay.getPreClose() != null && !quoteDay.getPreClose().isEmpty()
                && Double.parseDouble(quoteDay.getPreClose()) > 0) {
            double highest = Double.parseDouble(quoteDay.getHighest());
            double lowest = Double.parseDouble(quoteDay.getLowest());
            double preClose = Double.parseDouble(quoteDay.getPreClose());
            if (preClose == 0) {
                quoteDay.setAmplitude("--");
            } else {
                quoteDay.setAmplitude(((highest - lowest) * 100) / preClose + "");
            }
        } else {
            quoteDay.setAmplitude("--");
        }
        return quoteDay;
    }

    /**
     * 使用实时行情更新盘面数据
     */
    @Override
    public void inputQuote(QuoteTik quote) {
//		if (!quote.getSymbol().equals(this.getSymbol())) {
//			LogUtils.e("Quote", "input quote error!");
//			return;
//		}

        boolean settlementPlanValid = true;

        // 这里需不需要根据结算计划判断是否累积盘面有待考虑
        // 如果依赖结算计划时间，可能存在结算计划取不到的情况
        // 如果不依赖结算计划，不能完全保证当前的行情是在正确的时间范围内
        if (!settlementPlanValid) {
            return;
        }

        if (inRang(quote.getAtTime())) {
            if (getLastTime() == null) {
                setLastTime(quote.getAtTime());
            }
            if (!getLastTime().after(quote.getAtTime())) {
                // 如果实时行情数据比当前盘面要早，不处理
                updateFromTik(quote);
                updateTime(quote.getAtTime());
                updateByLast();
            }
        } else {
            // to do
        }
//		LogUtils.e("DayQuote", this.toString());
    }


    @Override
    public String toString() {
        return "MMQuoteDay [getExchangeCode()=" + getExchangeCode() + ", getGoodsCode()=" + getGoodsCode()
                + ", getSymbol()=" + getSymbol() + ", getLastTime()=" + getLastTime() + ", getPrice()=" + getPrice()
                + ", getBid()=" + getBid() + ", getAsk()=" + getAsk() + ", getOpened()=" + getOpened()
                + ", getHighest()=" + getHighest() + ", getLowest()=" + getLowest() + ", getDecimalPlace()="
                + getDecimalPlace() + ", getOpenTime()=" + getOpenTime() + ", toString()=" + super.toString() + "]";
    }
}
