from logger_config import get_logger
from trade_constants import (
    TRADE_TYPE_SIMULATION,
    ORDER_DIRECTION_BUY,
    ORDER_DIRECTION_SELL,
    ORDER_STATUS_COMPLETED,
    ORDER_STATUS_CANCELLED,
)
from position_manager import PositionManager
from base_trader import BaseTrader
import random
from typing import Dict
from local_position import LocalPosition


class SimulationTrader(BaseTrader):
    def __init__(self):
        super().__init__(get_logger("simulation_trader"))
        # 模拟资金账户信息
        self.sim_balance = {"account_id": "simulation", "cash": 1000000.00, "frozen": 0.00, "total": 1000000.00}

    def is_logged_in(self):
        """检查交易系统是否已经登录

        Returns:
            bool: True表示已登录，模拟交易系统总是返回已登录状态
        """
        return True

    def login(self):
        self.logger.info("模拟交易：登录成功")
        return True

    def logout(self):
        self.logger.info("模拟交易：登出成功")
        return True

    def buy(self, code, price, amount, strategy_name="default_strategy"):
        message = f"模拟买入 - 代码: {code}, 价格: {price}, 数量: {amount}, 策略: {strategy_name}"
        self.logger.info(message)

        # 计算交易成本
        cost = price * amount

        # 检查余额是否足够
        if self.sim_balance["cash"] < cost:
            message = f"模拟买入失败 - 代码: {code}, 资金不足"
            self.logger.warning(message)
            return {"order_id": None, "message": message, "success": False}

        # 更新资金
        self.sim_balance["cash"] -= cost

        # 更新持仓管理器
        position_manager = self.get_position_manager(strategy_name)
        position_manager.update_position(
            code, ORDER_DIRECTION_BUY, amount
        )
        order_id = random.randint(1, 999999)  # 使用随机函数生成小于1000000的随机整数
        position_manager.add_pending_order(
            order_id, code, price, amount, ORDER_DIRECTION_BUY
        )
        # 假设立刻全部成交
        position_manager.update_order_status(order_id, amount, ORDER_STATUS_COMPLETED)

        # 更新总资产
        self._update_total_assets()

        return {"order_id": order_id, "message": message, "success": True}

    def sell(self, code, price, amount, strategy_name="default_strategy"):
        message = f"模拟卖出 - 代码: {code}, 价格: {price}, 数量: {amount}, 策略: {strategy_name}"
        self.logger.info(message)

        # 获取策略持仓
        position_manager = self.get_position_manager(strategy_name)
        strategy_positions = position_manager.get_positions()

        # 检查持仓是否足够
        if (
            code not in strategy_positions
            or strategy_positions[code].closeable_amount < amount
        ):
            message = f"模拟卖出失败 - 代码: {code}, 可用数量不足"
            self.logger.warning(message)
            return {"order_id": None, "message": message, "success": False}

        # 更新资金
        proceeds = price * amount
        self.sim_balance["cash"] += proceeds

        # 更新持仓管理器
        position_manager.update_position(
            code, ORDER_DIRECTION_SELL, amount
        )
        order_id = random.randint(1, 999999)  # 使用随机函数生成小于1000000的随机整数
        position_manager.add_pending_order(
            order_id, code, price, amount, ORDER_DIRECTION_SELL
        )
        # 假设立刻全部成交
        position_manager.update_order_status(order_id, amount, ORDER_STATUS_COMPLETED)

        # 更新总资产
        self._update_total_assets()

        return {"order_id": order_id, "message": message, "success": True}

    def _update_total_assets(self):
        """更新总资产"""
        # 此处简化处理，在实际情况中应该计算所有持仓的市值
        self.sim_balance["total"] = self.sim_balance["cash"]

    def cancel(self, order_id):
        message = f"模拟撤单 - 委托号: {order_id}"
        self.logger.info(message)
        position_managers = self.get_all_position_managers()
        for position_manager in position_managers.values():
            if order_id in position_manager.pending_orders:
                position_manager.update_order_status(order_id, 0, ORDER_STATUS_CANCELLED)
                return {"order_id": "order_id", "message": message, "success": True}
            else:
                return {"order_id": None, "message": "订单不存在", "success": False}

    def get_balance(self):
        message = "模拟交易：查询余额"
        self.logger.info(message)
        return self.sim_balance

    def get_positions(self):
        message = "模拟交易：查询持仓"
        self.logger.info(message)

        position_managers = self.get_all_position_managers()
        positions: Dict[str, LocalPosition] = {}
        for position_manager in position_managers.values():
            positions.update(position_manager.get_positions())
        # convert to json list
        return [{"account_id": "simulation", "code": position.code, "total_amount": position.total_amount, "closeable_amount": position.closeable_amount} for position in positions.values()]

    def get_today_trades(self):
        message = "模拟交易：查询今日成交"
        self.logger.info(message)
        return {"message": "模拟交易：查询今日成交未实现", "success": True}

    def get_today_orders(self):
        message = "模拟交易：查询今日委托"
        self.logger.info(message)
        return {"message": "模拟交易：查询今日委托未实现", "success": True}

    
    def get_position(self, stock_code, strategy_name="default_strategy"):
        """查询指定股票代码的持仓信息
        Args:
            stock_code: 股票代码，例如 "600000.SH"
            strategy_name: 策略名称，默认为"default_strategy"
        Returns:
            dict: 持仓详情，如果未持有则返回None
        """
        position_manager = self.get_position_manager(strategy_name)
        positions = position_manager.get_positions()
        if stock_code in positions:
            position_info = positions[stock_code]
            return {
                "account_id": "simulation",
                "code": stock_code,
                "strategy_name": strategy_name,
                "total_amount": position_info.total_amount,
                "closeable_amount": position_info.closeable_amount,
            }
        return None

    def get_order(self, order_id):
        position_managers = self.get_all_position_managers()
        for position_manager in position_managers.values():
            if order_id in position_manager.pending_orders:
                order_info = position_manager.pending_orders[order_id]
                return {
                    "order_id": order_id,
                    "stock_code": order_info.stock_code,
                    "price": order_info.price,
                    "amount": order_info.amount,
                    "direction": order_info.direction,
                    "status": order_info.status,
                    "strategy_name": order_info.strategy_name,
                }
        return None

   
