from __future__ import annotations

import logging
import threading
import uuid
from dataclasses import dataclass, field
from datetime import datetime, timezone

logger = logging.getLogger(__name__)


@dataclass
class OpenTrade:
    id: str
    symbol: str
    action: str        # "BUY" | "SELL"
    quantity: float
    entry_price: float
    take_profit: float
    stop_loss: float
    opened_at: datetime = field(default_factory=lambda: datetime.now(timezone.utc))
    pnl_pct: float = 0.0

    def to_dict(self) -> dict:
        return {
            "id": self.id,
            "symbol": self.symbol,
            "action": self.action,
            "quantity": self.quantity,
            "entry_price": self.entry_price,
            "take_profit": self.take_profit,
            "stop_loss": self.stop_loss,
            "opened_at": self.opened_at.isoformat(),
            "pnl_pct": round(self.pnl_pct, 4),
        }


class TradeTracker:
    """تخزين الصفقات المفتوحة في الذاكرة مع حماية متعددة الخيوط."""

    def __init__(self) -> None:
        self._lock = threading.Lock()
        self._trades: dict[str, OpenTrade] = {}  # مفتاح: trade.id

    def open_trade(
        self,
        symbol: str,
        action: str,
        quantity: float,
        entry_price: float,
        take_profit: float,
        stop_loss: float,
    ) -> OpenTrade:
        trade = OpenTrade(
            id=str(uuid.uuid4()),
            symbol=symbol,
            action=action,
            quantity=quantity,
            entry_price=entry_price,
            take_profit=take_profit,
            stop_loss=stop_loss,
        )
        with self._lock:
            self._trades[trade.id] = trade
        logger.info(
            f"صفقة مفتوحة: {action} {quantity} {symbol} @ {entry_price} "
            f"| TP={take_profit} SL={stop_loss} id={trade.id}"
        )
        return trade

    def close_trade(self, trade_id: str, exit_price: float) -> OpenTrade | None:
        with self._lock:
            trade = self._trades.pop(trade_id, None)
        if trade is None:
            logger.warning(f"محاولة إغلاق صفقة غير موجودة: {trade_id}")
            return None

        if trade.action == "BUY":
            pnl_pct = (exit_price - trade.entry_price) / trade.entry_price * 100
        else:
            pnl_pct = (trade.entry_price - exit_price) / trade.entry_price * 100

        trade.pnl_pct = pnl_pct
        result = "WIN" if pnl_pct > 0 else "LOSS"
        logger.info(
            f"صفقة مغلقة: {trade.action} {trade.symbol} "
            f"دخول={trade.entry_price} خروج={exit_price} "
            f"PnL={pnl_pct:+.2f}% [{result}]"
        )
        return trade

    def get_open_trades(self) -> list[OpenTrade]:
        with self._lock:
            return list(self._trades.values())

    def get_open_trade_by_symbol(self, symbol: str) -> OpenTrade | None:
        with self._lock:
            for trade in self._trades.values():
                if trade.symbol == symbol:
                    return trade
        return None

    def has_open_trade(self, symbol: str) -> bool:
        return self.get_open_trade_by_symbol(symbol) is not None

    @property
    def count(self) -> int:
        with self._lock:
            return len(self._trades)


trade_tracker = TradeTracker()
