"""
Dummy QMT 模拟器 - 用于在非 Windows 环境下模拟 QMT 交易功能
"""
import datetime
import threading
import time
import random
import config
import core.eventbus as eBus
from core.logger import LogLevel, PrintLog

class DummyPosition:
    """模拟持仓"""
    def __init__(self, stock_code, stock_name, volume, yesterday_vol=0):
        self.stock_code = stock_code
        self.stock_name = stock_name
        self.volume = volume
        self.can_use_volume = volume
        self.yesterday_volume = yesterday_vol

class DummyOrder:
    """模拟订单"""
    def __init__(self, stock_code, order_id, status, price, volume):
        self.stock_code = stock_code
        self.order_id = order_id
        self.order_status = status
        self.order_price = price
        self.volume = volume

class DummyTrade:
    """模拟成交"""
    def __init__(self, stock_code, trade_id, price, volume, strategy_name):
        self.stock_code = stock_code
        self.trade_id = trade_id
        self.trade_price = price
        self.trade_volume = volume
        self.strategy_name = strategy_name

class DummyOrderResponse:
    """模拟下单响应"""
    def __init__(self, order_id, stock_code, seq, error_msg, strategy_name):
        self.order_id = order_id
        self.stock_code = stock_code
        self.seq = seq
        self.error_msg = error_msg
        self.strategy_name = strategy_name

class DummyQmtV:
    """
    Dummy QMT 模拟器
    模拟 QmtV 类的接口，用于在没有 miniQMT 的环境下运行和测试
    """
    def __init__(self) -> None:
        self.inited = False
        self.details = {}
        self.lastMarketDataUpdateTimestamp = time.time()
        self.isMarketActive = True
        self.connected = False
        self.account = None
        self._positions = {}
        self._pending_orders = []
        self._market_data_thread = None
        self._counter = 0

    def getTrader(self):
        return self

    def init_qmtv(self):
        """初始化交易器"""
        PrintLog(LogLevel.INFO, f'- [模拟] QMT 交易器初始化')
        self.connected = True
        self.inited = True

    def connect(self) -> bool:
        """连接 QMT (模拟总是成功)"""
        PrintLog(LogLevel.INFO, f'- [成功] 市场交易连接 (模拟模式)')

        # 创建模拟账号
        try:
            from xtquant.xttype import StockAccount
            self.account = StockAccount(config.account_no, 'STOCK')
        except ImportError:
            self.account = type('StockAccount', (), {'account_id': config.account_no})()
        PrintLog(LogLevel.INFO, f'- [成功] 交易账号: {config.account_no}')

        self._init_dummy_positions()
        self.startMarketDataSubscription()

        return self.inited

    def _init_dummy_positions(self):
        """初始化模拟持仓数据"""
        dummy_stocks = [
            ('600519', '贵州茅台', 100, 2800.0),
            ('000858', '五粮液', 200, 180.0),
            ('600036', '招商银行', 500, 42.0),
            ('000001', '平安银行', 300, 13.5),
        ]
        for code, name, volume, price in dummy_stocks:
            self._positions[code] = {
                'stock_code': code,
                'stock_name': name,
                'volume': volume,
                'can_use_volume': volume,
                'open_cost': price,
                'market_value': volume * price
            }
        PrintLog(LogLevel.INFO, f'- [模拟] 已加载 {len(self._positions)} 个持仓')

    def getAllPositions(self) -> dict:
        """获取全部持仓，返回 {stock_code: position_object}"""
        result = {}
        for code, pos_data in self._positions.items():
            result[code] = type('DummyPos', (), pos_data)()
        return result

    def getStockPosition(self, stock_code: str):
        """获取持仓 (模拟)"""
        if stock_code in self._positions:
            pos = self._positions[stock_code]
            return type('DummyPos', (), pos)()
        return None

    def queryPendingOrder(self, stock_code: str, tag: str) -> list:
        """查询挂单"""
        return [o for o in self._pending_orders
                if o.stock_code == stock_code and
                (tag is None or getattr(o, 'strategy_name', None) == tag)]

    def orderAsync(self, stock_code, orderVolume, orderType, orderPrice, priceType, orderRemark, strategy_name):
        """异步下单 (模拟)"""
        self._counter += 1
        order_id = f"DUMMY{self._counter:06d}"
        seq = self._counter

        order = DummyOrder(
            stock_code=stock_code,
            order_id=order_id,
            status='reported',
            price=orderPrice,
            volume=orderVolume
        )
        order.strategy_name = strategy_name
        order.order_remark = orderRemark
        self._pending_orders.append(order)

        response = DummyOrderResponse(
            order_id=order_id,
            stock_code=stock_code,
            seq=seq,
            error_msg='成功',
            strategy_name=strategy_name
        )
        response.order_remark = orderRemark

        eBus.event_bus.publish(eBus.MarketOrderCreated, response)
        PrintLog(LogLevel.INFO, f'- [模拟下单] {stock_code} 数量:{orderVolume} 价格:{orderPrice} 订单号:{order_id}')

        # 模拟成交 (80% 概率)
        if random.random() > 0.2:
            threading.Timer(random.uniform(0.5, 3.0), self._simulate_trade,
                          args=(stock_code, order_id, orderPrice, orderVolume, strategy_name)).start()

        return 0

    def _simulate_trade(self, stock_code, order_id, price, volume, strategy_name):
        """模拟成交"""
        trade = DummyTrade(
            stock_code=stock_code,
            trade_id=f"TRADE{self._counter:06d}",
            price=price,
            volume=volume,
            strategy_name=strategy_name
        )
        trade.trade_time = int(time.strftime('%H%M%S'))
        trade.order_remark = stock_code

        if stock_code in self._positions:
            self._positions[stock_code]['volume'] += volume
            self._positions[stock_code]['can_use_volume'] += volume

        eBus.event_bus.publish(eBus.MarketOrderTraded, trade)
        PrintLog(LogLevel.INFO, f'- [模拟成交] {stock_code} 数量:{volume} 价格:{price}')

    def cacheStockDetail(self, stock_code: str):
        """获取股票详情 (模拟)"""
        if stock_code not in self.details:
            self.details[stock_code] = {
                'InstrumentName': self._get_dummy_name(stock_code),
                'UpStopPrice': 0,
                'DownStopPrice': 0
            }
        return self.details[stock_code]

    def _get_dummy_name(self, stock_code: str) -> str:
        """获取模拟股票名称"""
        names = {
            '600519': '贵州茅台', '000858': '五粮液', '600036': '招商银行',
            '000001': '平安银行', '000002': '万科A', '600000': '浦发银行'
        }
        return names.get(stock_code, f'股票{stock_code}')

    def getInstrumentName(self, stock_code: str) -> str:
        """获取股票名称"""
        return self.cacheStockDetail(stock_code)['InstrumentName']

    def dailyUpStop(self, stock_code: str):
        """获取涨停价 (模拟)"""
        cacheStock = self.cacheStockDetail(stock_code)
        PrintLog(LogLevel.INFO, f'- [模拟] 获取股票详情: {stock_code} {cacheStock["InstrumentName"]} 涨停价: 0')
        return 0.0

    def dailyDownStop(self, stock_code: str):
        """获取跌停价 (模拟)"""
        return 0.0

    def getLastPrice(self, stock_code: str) -> float:
        """主动获取最新市价（模拟）"""
        if stock_code in self._positions:
            return float(self._positions[stock_code].get('open_cost', 10.0))
        # 给一个合理模拟价
        return 10.0 + hash(stock_code) % 100

    def startMarketDataSubscription(self):
        """启动市场数据订阅 (模拟)"""
        try:
            self._market_data_thread = threading.Thread(target=self._generate_market_data, daemon=True)
            self._market_data_thread.start()
            PrintLog(LogLevel.INFO, f'- [市场数据订阅成功-模拟]')
        except Exception as e:
            PrintLog(LogLevel.ERROR, f'- [市场数据订阅失败-{e}]')

    def stopMarketDataSubscription(self):
        """停止市场数据订阅"""
        PrintLog(LogLevel.INFO, '- 停止市场数据订阅 (模拟)')

    def _generate_market_data(self):
        """生成模拟市场数据"""
        stocks = ['600519', '000858', '600036', '000001', '000002', '600000']
        base_prices = [2800.0, 180.0, 42.0, 13.5, 10.0, 10.0]

        while True:
            try:
                for i, stock in enumerate(stocks):
                    data = {
                        'stock_code': stock,
                        'last_price': base_prices[i] + random.uniform(-1, 1),
                        'open_price': base_prices[i],
                        'high_price': base_prices[i] + random.uniform(0, 2),
                        'low_price': base_prices[i] - random.uniform(0, 2),
                        'volume': random.randint(1000, 10000),
                        'timestamp': time.time()
                    }
                    eBus.event_bus.publish(eBus.MarketDataUpdate, data)
                    base_prices[i] = data['last_price']

                self.lastMarketDataUpdateTimestamp = time.time()
                self.isMarketActive = True
                eBus.event_bus.publish(eBus.EventMarketActiveSwitch, True)

                time.sleep(3)

            except Exception as e:
                PrintLog(LogLevel.ERROR, f'- [市场数据模拟异常-{e}]')
                time.sleep(1)

    def on_connected(self):
        print(datetime.datetime.now(), '模拟连接成功')

    def on_disconnected(self):
        print(datetime.datetime.now(), '模拟连接断开')

    def on_stock_order(self, order):
        pass

    def on_stock_trade(self, trade):
        eBus.event_bus.publish(eBus.MarketOrderTraded, trade)

    def on_order_stock_async_response(self, response):
        eBus.event_bus.publish(eBus.MarketOrderCreated, response)

    def on_order_error(self, order_error):
        print(f"\n模拟委托报错回调: order_id={order_error.order_id}, error_id={order_error.error_id}, error_msg={order_error.error_msg}, remark={order_error.order_remark}")
        eBus.event_bus.publish(eBus.MarketOrderError, order_error)

    def on_account_status(self, status):
        print(datetime.datetime.now(), status)


qmtv = DummyQmtV()