# auto generated by update_py.py
import datetime
import json

from sqlalchemy import (CHAR, JSON, BigInteger, Boolean, Column, DateTime, String, BIGINT,
                        Integer, UniqueConstraint)
from sqlalchemy.dialects.mysql import DOUBLE
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()


class Account(Base):

    __tablename__ = 'accounts'

    id = Column(Integer, primary_key=True)

    acc_tag = Column(CHAR(100), unique=True)
    acc_config = Column(JSON)
    key_name = Column(CHAR(100))

    create_time = Column(DateTime)
    update_time = Column(DateTime)

    def get_decrypted_acc_config(self):
        from linker import rsa_encrypter as rsa
        from ..helpers import KeyHelper

        config = self.acc_config.copy()
        # to decrypt
        if self.key_name is not None:
            assert KeyHelper.key_exists(self.key_name), 'failed to decrypt, key "{}" missing'.format(self.key_name)
            private_key_path, _ = KeyHelper.get_key_paths(self.key_name)
            for field in ['secret_key', 'password']:
                encrypted_data = config.get(field)
                if encrypted_data is not None:
                    data = rsa.decode_msg(encrypted_data, private_pem_file=private_key_path)
                    if data is None:
                        raise RuntimeError("[decrypt_acc] failed to decrypt account config, possibly caused by a wrong key")
                    config[field] = data

        return config

    def set_update_time(self):
        self.update_time = datetime.datetime.now()

    def set_create_time(self):
        self.create_time = datetime.datetime.now()


class Order(Base):
    __tablename__ = 'orders'

    id = Column(Integer, primary_key=True)

    exchange = Column(Integer)
    ticker = Column(CHAR(50))
    source = Column(CHAR(50))
    price = Column(DOUBLE(asdecimal=False))
    volume = Column(DOUBLE(asdecimal=False))
    asset_type = Column(Integer)
    order_type = Column(Integer)
    direction = Column(Integer)
    offset_flag = Column(Integer)
    tg_name = Column(CHAR(50))
    order_id = Column(BIGINT)
    parent_id = Column(BIGINT)
    order_ref = Column(CHAR(50))
    client_name = Column(CHAR(50))
    order_status = Column(Integer)
    volume_traded = Column(DOUBLE(asdecimal=False))
    turnover = Column(DOUBLE(asdecimal=False))
    err_id = Column(Integer)
    err_msg = Column(CHAR(250))
    cancel_err_id = Column(Integer)
    cancel_err_msg = Column(CHAR(250))
    timestamp = Column(BIGINT)
    extra_info = Column(String(1000))
    margin_mode = Column(Integer)
    lever_rate = Column(BIGINT)


class RtnOrder(Base):
    __tablename__ = 'rtn_orders'

    id = Column(Integer, primary_key=True)

    tg_name = Column('tg_name', CHAR(50))
    exchange = Column('exchange', Integer)
    ticker = Column('ticker', CHAR(50))
    order_status = Column(Integer)
    volume_traded = Column(DOUBLE(asdecimal=False))
    order_id = Column(BIGINT)
    order_ref = Column(CHAR(50))
    order_type = Column(Integer)
    timestamp = Column(BIGINT)


class RtnTrade(Base):
    __tablename__ = 'rtn_trades'

    id = Column(Integer, primary_key=True)

    tg_name = Column('tg_name', CHAR(50))
    exchange = Column('exchange', Integer)
    ticker = Column('ticker', CHAR(50))
    price = Column('price', DOUBLE(asdecimal=False))
    volume = Column('volume', DOUBLE(asdecimal=False))
    turnover = Column('turnover', DOUBLE(asdecimal=False))
    commission = Column('commission', DOUBLE(asdecimal=False))
    exec_role = Column('exec_role', Integer)
    asset_type = Column('asset_type', Integer)
    order_type = Column('order_type', Integer)
    direction = Column('direction', Integer)
    offset_flag = Column('offset_flag', Integer)
    trade_id = Column('trade_id', CHAR(50))
    trade_time = Column('trade_time', BigInteger)
    trading_day = Column('trading_day', CHAR(9))
    order_id = Column('order_id', BigInteger)
    order_ref = Column('order_ref', CHAR(50))
    timestamp = Column('timestamp', BigInteger)


class Trade(Base):
    __tablename__ = 'history_trades'

    id = Column(Integer, primary_key=True)

    tg_name = Column('tg_name', CHAR(50))
    exchange = Column('exchange', Integer)
    ticker = Column('ticker', CHAR(50))
    price = Column('price', DOUBLE(asdecimal=False))
    volume = Column('volume', DOUBLE(asdecimal=False))
    commission = Column('commission', DOUBLE(asdecimal=False))
    exec_role = Column('exec_role', Integer)
    asset_type = Column('asset_type', Integer)
    order_type = Column('order_type', Integer)
    direction = Column('direction', Integer)
    offset_flag = Column('offset_flag', Integer)
    trade_id = Column('trade_id', CHAR(50))
    trade_time = Column('trade_time', BigInteger)
    trading_day = Column('trading_day', CHAR(9))
    order_id = Column('order_id', BigInteger)
    order_ref = Column('order_ref', CHAR(50))
    timestamp = Column('timestamp', BigInteger)

    trd_constraint = UniqueConstraint('tg_name', 'trade_id', 'trade_constraint')


class ExchPos(Base):
    __tablename__ = 'exch_pos'

    id = Column(Integer, primary_key=True)

    tg_name = Column(CHAR(50))
    exchange = Column(Integer)
    ticker = Column(CHAR(50))
    source = Column(CHAR(50))
    margin_mode = Column(Integer)
    asset_type = Column(Integer)
    posi_direction = Column(Integer)
    position = Column(DOUBLE(asdecimal=False))
    yd_position = Column(DOUBLE(asdecimal=False))
    position_cost = Column(DOUBLE(asdecimal=False))
    frozen = Column(DOUBLE(asdecimal=False))
    yd_frozen = Column(DOUBLE(asdecimal=False))
    available = Column(DOUBLE(asdecimal=False))
    borrowed = Column(DOUBLE(asdecimal=False))
    interest = Column(DOUBLE(asdecimal=False))
    liquidation_price = Column(DOUBLE(asdecimal=False))
    equity = Column(DOUBLE(asdecimal=False))
    risk_rate = Column(DOUBLE(asdecimal=False))
    update_time = Column(DateTime)
    pnl = Column(DOUBLE(asdecimal=False))
    realized_pnl = Column(DOUBLE(asdecimal=False))
    unrealized_pnl = Column(DOUBLE(asdecimal=False))

    pos_constraint = UniqueConstraint('tg_name', 'exchange', 'ticker', 'source', 'margin_mode', 'asset_type', 'posi_direction')


class AccPos(Base):
    __tablename__ = 'acc_pos'

    id = Column(Integer, primary_key=True)

    tg_name = Column(CHAR(50))
    exchange = Column(Integer)
    ticker = Column(CHAR(50))
    source = Column(CHAR(50))
    margin_mode = Column(Integer)
    asset_type = Column(Integer)
    posi_direction = Column(Integer)
    position = Column(DOUBLE(asdecimal=False))
    yd_position = Column(DOUBLE(asdecimal=False))
    position_cost = Column(DOUBLE(asdecimal=False))
    frozen = Column(DOUBLE(asdecimal=False))
    yd_frozen = Column(DOUBLE(asdecimal=False))
    available = Column(DOUBLE(asdecimal=False))
    borrowed = Column(DOUBLE(asdecimal=False))
    interest = Column(DOUBLE(asdecimal=False))
    liquidation_price = Column(DOUBLE(asdecimal=False))
    equity = Column(DOUBLE(asdecimal=False))
    risk_rate = Column(DOUBLE(asdecimal=False))
    update_time = Column(DateTime)
    pnl = Column(DOUBLE(asdecimal=False))
    realized_pnl = Column(DOUBLE(asdecimal=False))
    unrealized_pnl = Column(DOUBLE(asdecimal=False))

    pos_constraint = UniqueConstraint('tg_name', 'exchange', 'ticker', 'source', 'margin_mode', 'asset_type', 'posi_direction')


class FeeInfo(Base):
    __tablename__ = 'fee_info'

    id = Column(Integer, primary_key=True)

    tg_name = Column(CHAR(50))
    ticker = Column(CHAR(50))
    asset_type = Column(Integer)
    fee_type = Column(Integer)
    min_fee = Column(DOUBLE(asdecimal=False))
    buy_fee_rate = Column(DOUBLE(asdecimal=False))
    sell_fee_rate = Column(DOUBLE(asdecimal=False))
    contract_multiplier = Column(Integer)
    open_fee_rate = Column(DOUBLE(asdecimal=False))
    close_fee_rate = Column(DOUBLE(asdecimal=False))
    close_today_fee_rate = Column(DOUBLE(asdecimal=False))
    close_yesterday_fee_rate = Column(DOUBLE(asdecimal=False))


class PnlInfo(Base):
    __tablename__ = 'pnl_info'

    id = Column(Integer, primary_key=True)

    tg_name = Column(CHAR(50))
    ticker = Column(CHAR(50))
    unrealized_pnl = Column(DOUBLE(asdecimal=False))
    realized_pnl = Column(DOUBLE(asdecimal=False))
    total_pnl = Column(DOUBLE(asdecimal=False))
    paid_fees = Column(DOUBLE(asdecimal=False))
    total_long_cost = Column(DOUBLE(asdecimal=False))
    ystd_long_cost = Column(DOUBLE(asdecimal=False))
    total_short_cost = Column(DOUBLE(asdecimal=False))
    ystd_short_cost = Column(DOUBLE(asdecimal=False))
    last_price = Column(DOUBLE(asdecimal=False))
    pre_settlement_price = Column(DOUBLE(asdecimal=False))
    pre_close_price = Column(DOUBLE(asdecimal=False))

    pnl_constraint = UniqueConstraint('tg_name', 'ticker')


class Indicator(Base):
    __tablename__ = 'indicators'

    id = Column(Integer, primary_key=True)

    indicator_name = Column(CHAR(50))   # spot risk degree
    account_id = Column(CHAR(50))   # account id, e.g. pyhuobi
    item_name = Column(CHAR(50))    # item name, e.g. btc
    value = Column(DOUBLE(asdecimal=False))
    update_time = Column(DateTime)
