"""Portfolio and Account Balance Manager."""
from __future__ import annotations

from decimal import Decimal
from typing import Any, Optional

from backend.app.audit.logger import audit_logger
from backend.app.config.settings import settings
from backend.app.database.session import db_manager
from backend.app.market_data.feed_manager import feed_manager
from backend.app.schemas.risk import AccountState


class PortfolioManager:
    """Tracks account equity, open positions, daily PnL, and maximum drawdowns."""

    def __init__(self, initial_equity: float = 10000.0) -> None:
        self.initial_equity = Decimal(str(initial_equity))
        self.peak_equity = self.initial_equity
        self.starting_day_equity = self.initial_equity

    def get_account_state(self) -> AccountState:
        # Fetch open positions from DB
        open_positions = db_manager.execute_read_all(
            "SELECT * FROM positions WHERE is_open = 1"
        )
        unrealized_pnl = Decimal("0.0")

        # Mark-to-market unrealized PnL
        for pos in open_positions:
            try:
                sym = pos["symbol"]
                qty = Decimal(pos["quantity"])
                entry_p = Decimal(pos["entry_price"])
                side = pos["side"]

                ticker = feed_manager.fetch_ticker(sym)
                curr_p = ticker.last_price

                pnl = (curr_p - entry_p) * qty if side == "LONG" else (entry_p - curr_p) * qty
                unrealized_pnl += pnl

                # Update mark-to-market in DB
                db_manager.execute_write(
                    "UPDATE positions SET current_price = ?, unrealized_pnl = ? WHERE id = ?",
                    (str(curr_p), str(pnl), pos["id"]),
                )
            except Exception as e:
                audit_logger.warning("Error marking position %s to market: %s", pos["id"], str(e))

        current_equity = self.initial_equity + unrealized_pnl
        if current_equity > self.peak_equity:
            self.peak_equity = current_equity

        return AccountState(
            equity=current_equity,
            available_balance=current_equity,
            starting_day_equity=self.starting_day_equity,
            peak_equity=self.peak_equity,
            open_positions_count=len(open_positions),
            current_leverage=Decimal("1.0"),
            realized_daily_pnl=Decimal("0.0"),
            unrealized_daily_pnl=unrealized_pnl,
        )

    def get_positions(self) -> list[dict[str, Any]]:
        """List open and historical positions."""
        return db_manager.execute_read_all("SELECT * FROM positions ORDER BY opened_at DESC LIMIT 50")

    def flatten_all_positions(self, authorized_by: str = "ADMIN") -> dict[str, Any]:
        """Emergency action: Close all open positions immediately."""
        open_positions = db_manager.execute_read_all(
            "SELECT * FROM positions WHERE is_open = 1"
        )
        count = len(open_positions)
        now = db_manager.execute_read_one("SELECT datetime('now') as now")["now"]

        db_manager.execute_write(
            "UPDATE positions SET is_open = 0, closed_at = ? WHERE is_open = 1",
            (now,),
        )
        audit_logger.critical("FLATTENED ALL POSITIONS: Closed %d positions by %s", count, authorized_by)
        return {"closed_count": count, "message": f"Successfully flattened {count} open positions."}


portfolio_manager = PortfolioManager()
