from dataclasses import dataclass
from datetime import datetime, timedelta
from decimal import Decimal

from .database import db
from .telegram_alert import send_telegram


@dataclass
class PumpTracker:
    event_id: int
    slot: dict
    symbol: str
    start_price: Decimal
    high_price: Decimal
    pump_pct: Decimal
    detected_at: datetime
    expires_at: datetime | None

    def expired(self, now: datetime) -> bool:
        return self.expires_at is not None and now > self.expires_at


class HighestPriceTracker:
    def __init__(self) -> None:
        self.active: dict[tuple[int, str], PumpTracker] = {}

    def add_or_update(
        self,
        slot: dict,
        symbol: str,
        start_price: Decimal,
        current_price: Decimal,
        pump_pct: Decimal,
        now: datetime,
    ) -> PumpTracker:
        key = (int(slot["id"]), symbol)
        tracking_seconds = slot.get("high_tracking_seconds")
        expires_at = None if tracking_seconds is None else now + timedelta(seconds=int(tracking_seconds))
        tracker = self.active.get(key)

        if tracker is None:
            event_id = db.execute(
                """
                INSERT INTO pump_events
                  (slot_id, symbol, pump_start_price, pump_high_price, pump_pct, detected_at, expires_at)
                VALUES (%s,%s,%s,%s,%s,%s,%s)
                """,
                (slot["id"], symbol, start_price, current_price, pump_pct, now, expires_at),
            )
            tracker = PumpTracker(
                event_id=event_id,
                slot=slot,
                symbol=symbol,
                start_price=start_price,
                high_price=current_price,
                pump_pct=pump_pct,
                detected_at=now,
                expires_at=expires_at,
            )
            self.active[key] = tracker
            db.log_trade_event(
                "Pump detected",
                pump_event_id=event_id,
                context={"symbol": symbol, "slot_id": slot["id"], "pump_pct": pump_pct},
            )
            send_telegram(f"Pump detected: {symbol} | Slot {slot['slot_name']} | {pump_pct:.2f}%")
            return tracker

        if not tracker.expired(now) and current_price > tracker.high_price:
            tracker.high_price = current_price
            db.execute(
                "UPDATE pump_events SET pump_high_price = %s, pump_pct = %s WHERE id = %s",
                (current_price, pump_pct, tracker.event_id),
            )
            db.log_trade_event(
                "Highest price updated",
                pump_event_id=tracker.event_id,
                context={"symbol": symbol, "high_price": current_price, "pump_pct": pump_pct},
            )
            send_telegram(f"Highest price updated: {symbol} | {current_price}")
        return tracker

    def expire_old(self, now: datetime) -> None:
        for key, tracker in list(self.active.items()):
            if tracker.expired(now):
                db.execute("UPDATE pump_events SET status = 'expired' WHERE id = %s", (tracker.event_id,))
                db.log_trade_event("Pump signal expired", pump_event_id=tracker.event_id)
                del self.active[key]

    def remove(self, tracker: PumpTracker) -> None:
        self.active.pop((int(tracker.slot["id"]), tracker.symbol), None)


highest_price_tracker = HighestPriceTracker()

