# -*- coding: utf-8 -*-

from openerp.osv import fields, osv
from logbook import Logger, StreamHandler
from utils import cons
import logbook
import tushare as ts
import sys
import os
import urllib
import string

logbook.set_datetime_format('local')
StreamHandler(sys.stdout).push_application()
log = Logger(os.path.basename(__file__))


class StockBasics(osv.osv):
    """
    沪深上市公司股票
    """

    def _code_to_symbol(self, code):
        """
            生成symbol代码标志 @ tushare
        """
        if code in cons.INDEX_LABELS:
            return cons.INDEX_LIST[code]
        else:
            if len(code) != 6:
                return ''
            else:
                return 'sh%s' % code if code[:1] in ['5', '6', '9'] else 'sz%s' % code

    def _get_stock_current_price(self, cr, uid, ids, field_names, arg, context=None):
        result = {}
        for id in ids:
            result[id] = {}
            position_obj = self.browse(cr, uid, id, context=context)
            result[id] = self.get_stock_now_price(position_obj.code)
        return result

    _name = "stock.basics"
    _columns = {
        'name': fields.char(u"名称", required=True),
        'code': fields.char(u"代码", required=True),
        'industry': fields.char(u"所属行业"),
        'area': fields.char(u"地区"),
        'pe': fields.float(u"市盈率"),
        'pb': fields.float(u"市净率"),
        'current_price': fields.function(_get_stock_current_price, type='float', method=True, help=u"当前价格"),
        'outstanding': fields.float(u"流通股本"),
        'totals': fields.float(u"总股本(万)"),
        'total_assets': fields.float(u"总资产(万)"),
        'liquid_assets': fields.float(u"流动资产"),
        'fixed_assets': fields.float(u"固定资产"),
        'reserved': fields.float(u"公积金"),
        'reserved_per_share': fields.float(u"每股公积金"),
        'eps': fields.float(u"每股收益"),
        'bvps': fields.float(u"每股净资资产"),
        'time_to_market': fields.date(u"上市日期"),
        'line_ids': fields.one2many('stock.basics.day.line', 'stock_id', u'股票日K数据', help=u'股票日K数据'),
    }

    def get_stock_now_price(self, stock_code):
        """
        获取股票的当前价格
        :param stock_id: 股票id
        :return:
        """
        code = self._code_to_symbol(stock_code)
        data = urllib.urlopen("http://hq.sinajs.cn/list=" + code).read().decode('gb2312')
        stockInfo = data.split(',')
        currentPrice = string.atof(stockInfo[3])
        return float(currentPrice)

    def get_yesterday_price(self, stock_code):
        """
        获取股票昨日收盘价格
        :param stock_code:
        :return:
        """
        code = self._code_to_symbol(stock_code)
        data = urllib.urlopen("http://hq.sinajs.cn/list=" + code).read().decode('gb2312')
        stockInfo = data.split(',')
        currentPrice = string.atof(stockInfo[2])
        return float(currentPrice)

    def get_stock_code(self, cr, uid, id, context=None):
        basics_obj = self.pool.get('stock.basics')
        stock = basics_obj.browse(cr, uid, id, context=context)
        return stock.code

    def get_stock_by_code(self, cr, uid, code, context=None):
        basics_obj = self.pool.get('stock.basics')
        ids = basics_obj.search(cr, uid, [('code', '=', code)])
        if len(ids) > 0:
            stock = basics_obj.browse(cr, uid, ids[0], context=context)
            return stock
        return None

    def run_get_stock_base_data(self, cr, uid, mail=[], context=None):
        """更新数据定时任务
        """

        log.debug("----------->执行定时任务")

        # 更新股票列表 ------------------------------------------------
        stock_basics_list = ts.get_stock_basics()
        log.debug("----------->查询到总共:" + str(stock_basics_list.shape[0]) + "股票")

        basics_obj = self.pool.get('stock.basics')
        ids = basics_obj.search(cr, uid, [])
        res = basics_obj.read(cr, uid, ids, ['name', 'code', 'id'], context)
        res = [(r['name'], r['code'], r['id']) for r in res]

        basics_local_list = []
        for basics in res:
            basics_local_list.append(basics[1])

        i = 0
        while i < stock_basics_list.shape[0]:
            s_data = stock_basics_list[i:i + 1]
            s_code = s_data.index.values[0]
            s_name = s_data.name.values[0]
            s_industry = s_data.industry.values[0]
            s_area = s_data.area.values[0]
            s_pe = s_data.pe.values[0]
            s_pb = s_data.pb.values[0]
            s_outstanding = s_data.outstanding.values[0]
            s_totals = s_data.totals.values[0]
            s_total_assets = s_data.totalAssets.values[0]
            s_liquid_assets = s_data.liquidAssets.values[0]
            s_fixed_assets = s_data.fixedAssets.values[0]
            s_reserved = s_data.reserved.values[0]
            s_reserved_per_share = s_data.reservedPerShare.values[0]
            s_eps = s_data.esp.values[0]
            s_bvps = s_data.bvps.values[0]
            s_time_to_market = s_data.timeToMarket.values[0]

            #
            # basics_ids = basics_obj.search(cr, uid, [('code', '=', s_code)])

            i += 1

            if not s_code in basics_local_list:
                # log.debug("----------->该股票不存在,创建~" + str(s_code))
                basics_obj.create(cr, uid, {
                    'name': str(s_name),
                    'code': str(s_code),
                    'industry': str(s_industry),
                    'area': str(s_area),
                    'pe': float(s_pe),
                    'pb': float(s_pb),
                    'outstanding': float(s_outstanding),
                    'totals': float(s_totals),
                    'total_assets': float(s_total_assets),
                    'liquid_assets': float(s_liquid_assets),
                    'fixed_assets': float(s_fixed_assets),
                    'reserved': float(s_reserved),
                    'reserved_per_share': float(s_reserved_per_share),
                    'eps': float(s_eps),
                    'bvps': float(s_bvps),
                    'time_to_market': s_time_to_market,
                }, context=context)
                cr.commit()
            else:
                # log.debug("----------->该股票已经存在,更新数据" + str(s_code))
                write_ids = basics_obj.search(cr, uid, [('code', '=', str(s_code))])
                basics_obj.write(cr, uid, write_ids, {
                    'name': str(s_name),
                    'industry': str(s_industry),
                    'area': str(s_area),
                    'pe': float(s_pe),
                    'pb': float(s_pb),
                    'outstanding': float(s_outstanding),
                    'totals': float(s_totals),
                    'total_assets': float(s_total_assets),
                    'liquid_assets': float(s_liquid_assets),
                    'fixed_assets': float(s_fixed_assets),
                    'reserved': float(s_reserved),
                    'reserved_per_share': float(s_reserved_per_share),
                    'eps': float(s_eps),
                    'bvps': float(s_bvps),
                    'time_to_market': s_time_to_market,
                }, context=context)
                cr.commit()

        # TODO 暂时注释掉更新日K数据
        return

        # 更新日K数据 ------------------------------------------------
        log.debug("----------->更新日K数据")
        basics_obj = self.pool.get('stock.basics')
        ids = basics_obj.search(cr, uid, [])
        res = basics_obj.read(cr, uid, ids, ['name', 'code', 'id'], context)
        res = [(r['name'], r['code'], r['id']) for r in res]

        num = 0
        for stock in res:
            num += 1
            id = stock[2]  # id
            log.debug("----------->进度:(" + str(num) + "/" + str(len(res)) + ")")
            code = stock[1]  # 股票代码

            day_line_obj = self.pool.get('stock.basics.day.line')
            ids = day_line_obj.search(cr, uid, [('stock_id.id', '=', id)])

            if len(ids) > 0:
                log.debug("----------->不是第一次更新数据" + str(id))
                last_day = day_line_obj.read(cr, uid, ids[0], ['date'], context)
                log.debug("----------->最后更新日期:" + str(last_day['date']))
                # TODO 没写完
            else:
                # log.debug("----------->没有日数据" + str(id))
                day_data_list = ts.get_hist_data(code)
                i = 0
                while i < day_data_list.shape[0]:
                    s_data = day_data_list[i:i + 1]
                    s_date = s_data.index.values[0]
                    # 涨跌趋势
                    if s_data.p_change.values[0] > 0:
                        trend = "↑"
                    elif s_data.p_change.values[0] < 0:
                        trend = "↓"
                    else:
                        trend = '-'

                    day_line_obj.create(cr, uid, {
                        'date': s_date,
                        'high': s_data.high.values[0],
                        'close': s_data.close.values[0],
                        'low': s_data.low.values[0],
                        'volume': s_data.volume.values[0],
                        'price_change': s_data.price_change.values[0],
                        'p_change': s_data.p_change.values[0],
                        'p_change_str': str("%.2f" % (s_data.p_change.values[0])) + "%",
                        'ma5': s_data.ma5.values[0],
                        'ma10': s_data.ma10.values[0],
                        'ma20': s_data.ma20.values[0],
                        'v_ma5': s_data.v_ma5.values[0],
                        'v_ma10': s_data.v_ma10.values[0],
                        'v_ma20': s_data.v_ma20.values[0],
                        'turnover': s_data.turnover.values[0],
                        'trend': trend,
                        'stock_id': id,
                    }, context=context)
                    cr.commit()
                    i += 1


class StockBasicsDayLine(osv.osv):
    """
    股票日K数据
    """

    _name = "stock.basics.day.line"
    _order = "date desc"

    _columns = {
        "date": fields.date(u"日期"),
        'high': fields.float(u"最高价"),
        'close': fields.float(u"收盘价"),
        'low': fields.float(u"最低价"),
        'volume': fields.float(u"成交量"),
        'price_change': fields.float(u"价格变动"),
        'p_change': fields.float(u"涨跌幅"),
        'p_change_str': fields.char(u"涨跌幅"),
        'ma5': fields.float(u"5日均价"),
        'ma10': fields.float(u"10日均价"),
        'ma20': fields.float(u"20日均价"),
        'v_ma5': fields.float(u"5日均量"),
        'v_ma10': fields.float(u"10日均量"),
        'v_ma20': fields.float(u"20日均量"),
        'turnover': fields.float(u"换手率"),
        'trend': fields.char(u"涨跌趋势"),
        'stock_id': fields.many2one('stock.basics', u'股票', required=True, ondelete="cascade"),
    }
