# core/portfolio.py
import streamlit as st
import pandas as pd
import json
import re
import decimal

from py_clob_client.client import ClobClient
from py_clob_client.order_builder.constants import BUY, SELL
from py_clob_client.clob_types import OrderArgs, MarketOrderArgs, OrderType, TickSize, CreateOrderOptions

from config import PRIVATE_KEY, WALLET_ADDRESS, SESSION
from utils.helpers import normalize_bucket
from utils.polymarket_fetch import fetch_event


@st.cache_resource
def get_clob_client():
    if not PRIVATE_KEY or not WALLET_ADDRESS:
        return None
    client = ClobClient(
        host="https://clob.polymarket.com",
        key=PRIVATE_KEY,
        chain_id=137,
        signature_type=1,
        funder=WALLET_ADDRESS
    )
    client.set_api_creds(client.create_or_derive_api_creds())
    return client


def get_user_positions():
    if not WALLET_ADDRESS:
        return {}
    url = f"https://data-api.polymarket.com/positions?sizeThreshold=1&limit=100&sortBy=TOKENS&sortDirection=DESC&user={WALLET_ADDRESS}"
    try:
        r = SESSION.get(url, timeout=15)
        r.raise_for_status()
        data = r.json()
        positions = data.get("data", []) if isinstance(data, dict) else data
        #print(positions)
        return positions
    except Exception as e:
        st.warning(f"Portfolio fetch failed: {e}")
        return {}

def get_user_positions_by_token():
    positions=get_user_positions()
    tp={}
    for p in positions:
        tp[p["asset"]]=p
    return tp

def place_market_order(token_id: str, side: str, size: float, dry_run: bool = True):
    clob = get_clob_client()
    if not clob or not token_id:
        print("❌ Kein CLob-Client oder Token-ID")
        return False

    if dry_run:
        return f"🔍 DRY-RUN: {side} {amount} {token_id[:8]}..."

    try:
        mo = MarketOrderArgs(
            token_id=token_id,
            amount=size,
            side=BUY if side=="BUY" else SELL,
            order_type=OrderType.FOK
        )
        o = CreateOrderOptions(tick_size=clob.get_tick_size(token_id),neg_risk=clob.get_neg_risk(token_id))
        signed = clob.create_market_order(mo,options=o)
        result=clob.post_order(signed, OrderType.FOK)
        #print(result)
        return result.get("success")
        if not clob or not token_id:
            print("❌ Kein CLob-Client oder Token-ID")
            return False

    except Exception as e:
        print(f"❌ Order-Fehler: {str(e)}")
        return False

def place_limit_order(token_id: str, side: str, size: float, lim: float, dry_run: bool = True):
    clob = get_clob_client()
    if not clob or not token_id:
        print("❌ Kein CLob-Client oder Token-ID")
        return False

    if dry_run:
        return f"🔍 DRY-RUN: {side} {amount} {token_id[:8]}..."

    try:
        decs=abs(decimal.Decimal(clob.get_tick_size(token_id)).as_tuple().exponent)
        mo = OrderArgs(
            token_id=token_id,
            size=size,
            price=round(lim,decs),
            side=BUY if side=="BUY" else SELL
        )
        o = CreateOrderOptions(tick_size=clob.get_tick_size(token_id),neg_risk=clob.get_neg_risk(token_id))
        signed = clob.create_order(mo,options=o)
        result=clob.post_order(signed, OrderType.GTC)
        #print(result)
        return result.get("success")
        if not clob or not token_id:
            print("❌ Kein CLob-Client oder Token-ID")
            return False

    except Exception as e:
        print(f"❌ Order-Fehler: {str(e)}")
        return False


def display_live_portfolio(wallet=None, meta=None, matrix=None, selected_slug=None):
    """Revised Portfolio Layout — clean, modern, no duplicate keys"""
    st.subheader("📊 Live Polymarket Portfolio")

    if not wallet:
        st.error("❌ WALLET_ADDRESS not set!")
        return

    pos_dict = get_user_positions()
    if not pos_dict:
        st.info("✅ No open positions detected.")
        if st.button("🔄 Reload Portfolio", key=f"portfolio_empty_{id(wallet)}"):
            st.rerun()
        return

    # Build rows
    rows = []

    for p in pos_dict:
        label = p.get("slug").replace("elon-musk-of-tweets-","")
        size = p.get("size")
        side = p.get("outcome")
        curP = float(p.get("curPrice"))
        avgP = float(p.get("avgPrice"))
        pPNL = float(p.get("percentPnl"))
        cPNL = float(p.get("cashPnl"))
        value = abs(size) * curP

        rows.append({
            "Bucket": label,
            "Side": side,
            "Size": round(size, 2),
            "Price": round(curP, 4),
            "Value": round(value, 2),
            "P/L": round(cPNL, 2)
        })

    df_port = pd.DataFrame(rows)

    # === MODERN REVISED LAYOUT ===
    st.dataframe(
        df_port.style.apply(
            lambda x: ["color: lime" if v > 0 else "color: red" for v in x],
            subset=["P/L"]
        ),
        width="stretch",                    # modern replacement for use_container_width
        hide_index=True,
        height=340
    )

    total_value = df_port["Value"].sum()
    total_pnl = df_port["P/L"].sum()
    st.metric("Total Value", f"${total_value:,.2f} USDC")
    st.metric("Total P/L", f"{total_pnl:+.2f} USDC", delta_color="normal")

    # Truly unique key (uses selected_slug when available)
    unique_key = f"portfolio_reload_main_{selected_slug or 'global'}"
    if st.button("🔄 Reload Portfolio Now", type="primary", key=unique_key):
        st.rerun()
