from flask import Flask, render_template, request, redirect, session, jsonify, render_template_string, send_from_directory
from requests_oauthlib import OAuth2Session
import sqlite3
import random
import time
import os
from dotenv import load_dotenv
from werkzeug.middleware.proxy_fix import ProxyFix
import requests # For downloading avatars

os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '0'
load_dotenv()

app = Flask(__name__)
app.secret_key = "super_secret_key_xorgus_cards_123" 

app.config['SESSION_COOKIE_SECURE'] = True
app.config['SESSION_COOKIE_HTTPONLY'] = True
app.config['SESSION_COOKIE_SAMESITE'] = 'Lax'

app.wsgi_app = ProxyFix(app.wsgi_app, x_proto=1, x_host=1)

# --- CONFIG ---
CLIENT_ID = os.getenv("DISCORD_CLIENT_ID")
CLIENT_SECRET = os.getenv("DISCORD_CLIENT_SECRET")
REDIRECT_URI = "https://xorgus.ddns.net/callback"
API_BASE_URL = "https://discord.com/api"
AUTHORIZATION_BASE_URL = API_BASE_URL + "/oauth2/authorize"
TOKEN_URL = API_BASE_URL + "/oauth2/token"

DB_PATH = os.path.join(app.root_path, "economy.db")

def get_db():
    conn = sqlite3.connect(DB_PATH)
    conn.row_factory = sqlite3.Row
    return conn

@app.route('/favicon.svg')
def favicon():
    return send_from_directory(os.path.join(app.root_path), 'favicon.svg', mimetype='image/svg+xml')

# --- AVATAR CACHING ---
AVATAR_DIR = os.path.join(app.root_path, 'static', 'avatars')
if not os.path.exists(AVATAR_DIR):
    os.makedirs(AVATAR_DIR)

def cache_avatar(user_id, avatar_hash):
    if not avatar_hash: 
        # For users without discriminator (new pomelo names), use (user_id >> 22) % 6
        default_index = (int(user_id) >> 22) % 6
        return f"https://cdn.discordapp.com/embed/avatars/{default_index}.png"
    
    filename = f"{user_id}_{avatar_hash}.png"
    local_path = os.path.join(AVATAR_DIR, filename)
    web_path = f"/static/avatars/{filename}"
    
    if os.path.exists(local_path):
        return web_path
        
    url = f"https://cdn.discordapp.com/avatars/{user_id}/{avatar_hash}.png"
    try:
        res = requests.get(url, timeout=5)
        if res.status_code == 200:
            with open(local_path, 'wb') as f:
                f.write(res.content)
            return web_path
    except:
        pass
    
    # Final fallback if download failed and we have a hash
    default_index = (int(user_id) >> 22) % 6
    return f"https://cdn.discordapp.com/embed/avatars/{default_index}.png"

# --- AUTH ---
@app.route("/login")
def login():
    discord = OAuth2Session(CLIENT_ID, redirect_uri=REDIRECT_URI, scope=["identify"])
    authorization_url, state = discord.authorization_url(AUTHORIZATION_BASE_URL)
    session["oauth_state"] = state
    return redirect(authorization_url)

@app.route("/callback")
def callback():
    try:
        discord = OAuth2Session(CLIENT_ID, redirect_uri=REDIRECT_URI, state=session.get("oauth_state"))
        token = discord.fetch_token(TOKEN_URL, client_secret=CLIENT_SECRET, authorization_response=request.url)
        session["oauth_token"] = token
        
        user_data = discord.get(API_BASE_URL + "/users/@me").json()
        session["user_id"] = int(user_data["id"])
        session["username"] = user_data["username"]
        # Cache avatar
        session["avatar"] = cache_avatar(user_data["id"], user_data.get("avatar"))
    except Exception as e:
        return f"Auth Error: {e} <a href='/'>Back</a>"
    
    # Init User in DB
    try:
        conn = get_db()
        cur = conn.cursor()
        cur.execute("SELECT * FROM users WHERE user_id = ?", (session["user_id"],))
        if not cur.fetchone():
            cur.execute("INSERT INTO users (user_id, balance, username, avatar) VALUES (?, 0, ?, ?)", 
                       (session["user_id"], session["username"], session["avatar"]))
        else:
            cur.execute("UPDATE users SET username = ?, avatar = ? WHERE user_id = ?", 
                       (session["username"], session["avatar"], session["user_id"]))
        conn.commit()
        conn.close()
    except Exception as e:
        print(f"DB Init Error: {e}")

    return redirect("/")

@app.route("/logout")
def logout():
    session.clear()
    return redirect("/")

# --- API ---
@app.route("/api/user")
def api_user():
    if "user_id" not in session: return jsonify({"logged_in": False})
    
    conn = get_db()
    cur = conn.cursor()
    cur.execute("SELECT balance FROM users WHERE user_id = ?", (session["user_id"],))
    res = cur.fetchone()
    conn.close()
    
    return jsonify({
        "logged_in": True,
        "username": session["username"],
        "avatar": session["avatar"],
        "balance": res["balance"] if res else 0
    })

@app.route("/api/buy_pack", methods=["POST"])
def buy_pack():
    if "user_id" not in session: return jsonify({"error": "Auth required"}), 401
    
    PRICE = 2790
    user_id = session["user_id"]
    
    conn = get_db()
    cur = conn.cursor()
    cur.execute("SELECT balance FROM users WHERE user_id = ?", (user_id,))
    res = cur.fetchone()
    
    if not res or res["balance"] < PRICE:
        conn.close()
        return jsonify({"error": "No funds"}), 400
        
    try:
        cur.execute("UPDATE users SET balance = balance - ? WHERE user_id = ?", (PRICE, user_id))
        
        seed = os.urandom(16).hex()
        rnd = random.random()
        if rnd < 0.01: rarity = "Legendary"
        elif rnd < 0.05: rarity = "Epic"
        elif rnd < 0.20: rarity = "Rare"
        elif rnd < 0.50: rarity = "Uncommon"
        else: rarity = "Common"
        
        power = random.randint(1, 1000)
        luck = random.randint(1, 100)
        
        cur.execute("""
            INSERT INTO cards (owner_id, seed, rarity, power, luck, mint_date)
            VALUES (?, ?, ?, ?, ?, ?)
        """, (user_id, seed, rarity, power, luck, int(time.time())))
        
        card_id = cur.lastrowid
        conn.commit()
        
        return jsonify({
            "success": True,
            "card_id": card_id, # FIX: Explicitly return card_id for frontend
            "card": {
                "card_id": card_id, # Ensure it's inside the card object too
                "id": card_id, "seed": seed, "rarity": rarity, "power": power, "luck": luck,
                "owner_avatar": session.get("avatar"), "owner_name": session.get("username")
            }
        })
    except Exception as e:
        conn.rollback()
        return jsonify({"error": str(e)}), 500
    finally:
        conn.close()

@app.route("/api/inventory")
def inventory():
    if "user_id" not in session: return jsonify([])
    conn = get_db()
    cur = conn.cursor()
    # Filter out listed cards
    cur.execute("""
        SELECT * FROM cards 
        WHERE owner_id = ? 
        AND card_id NOT IN (SELECT card_id FROM listings)
        ORDER BY card_id DESC
    """, (session["user_id"],))
    cards = [dict(row) for row in cur.fetchall()]
    conn.close()
    
    for card in cards:
        card['owner_name'] = session.get("username")
        card['owner_avatar'] = session.get("avatar")
    return jsonify(cards)

@app.route("/api/sell_card_bank", methods=["POST"])
def sell_card_bank():
    if "user_id" not in session: return jsonify({"error": "Auth required"}), 401
    
    data = request.json
    card_id = data.get("card_id")
    user_id = session["user_id"]

    conn = get_db()
    cur = conn.cursor()
    cur.execute("SELECT * FROM cards WHERE card_id = ?", (card_id,))
    card = cur.fetchone()
    
    if not card or card["owner_id"] != user_id:
        conn.close()
        return jsonify({"error": "Not yours"}), 403

    # Dynamic Price Calculation
    # Base: 100. Power: +1 per point. Luck: +2 per point.
    # Rarity Multiplier: Common x1, Uncommon x1.2, Rare x1.5, Epic x2, Legendary x5
    rarity_mult = {"common":1, "uncommon":1.2, "rare":1.5, "epic":2, "legendary":5}.get(card["rarity"].lower(), 1)
    base_price = 100 + (card["power"] * 0.1) + (card["luck"] * 5)
    final_price = int(base_price * rarity_mult)
    
    # Cap to ensure loss (Pack is 2790)
    if final_price > 2500: final_price = 2500

    try:
        cur.execute("DELETE FROM cards WHERE card_id = ?", (card_id,))
        cur.execute("DELETE FROM listings WHERE card_id = ?", (card_id,)) # Remove from market if listed
        cur.execute("UPDATE users SET balance = balance + ? WHERE user_id = ?", (final_price, user_id))
        conn.commit()
        return jsonify({"success": True, "price": final_price})
    except Exception as e:
        conn.rollback()
        return jsonify({"error": str(e)}), 500
    finally:
        conn.close()

@app.route("/api/market_list", methods=["POST"])
def market_list():
    if "user_id" not in session: return jsonify({"error": "Auth required"}), 401
    
    data = request.json
    card_id = data.get("card_id")
    price = int(data.get("price"))
    
    if price < 100 or price > 1000000:
        return jsonify({"error": "Invalid price"}), 400

    user_id = session["user_id"]
    conn = get_db()
    cur = conn.cursor()
    
    cur.execute("SELECT owner_id FROM cards WHERE card_id = ?", (card_id,))
    card = cur.fetchone()
    if not card or card["owner_id"] != user_id:
        conn.close()
        return jsonify({"error": "Not yours"}), 403
        
    try:
        cur.execute("INSERT INTO listings (card_id, seller_id, price, created_at) VALUES (?, ?, ?, ?)",
                   (card_id, user_id, price, int(time.time())))
        conn.commit()
        return jsonify({"success": True})
    except Exception as e:
        return jsonify({"error": str(e)}), 500
    finally:
        conn.close()

@app.route("/api/market_cancel", methods=["POST"])
def market_cancel():
    if "user_id" not in session: return jsonify({"error": "Auth required"}), 401
    
    data = request.json
    listing_id = data.get("listing_id")
    user_id = session["user_id"]
    
    conn = get_db()
    cur = conn.cursor()
    
    cur.execute("SELECT * FROM listings WHERE listing_id = ?", (listing_id,))
    listing = cur.fetchone()
    
    if not listing:
        conn.close()
        return jsonify({"error": "Not found"}), 404
        
    if listing["seller_id"] != user_id:
        conn.close()
        return jsonify({"error": "Not yours"}), 403
        
    try:
        cur.execute("DELETE FROM listings WHERE listing_id = ?", (listing_id,))
        conn.commit()
        return jsonify({"success": True})
    except Exception as e:
        conn.rollback()
        return jsonify({"error": str(e)}), 500
    finally:
        conn.close()

@app.route("/api/market_buy", methods=["POST"])
def market_buy():
    if "user_id" not in session: return jsonify({"error": "Auth required"}), 401
    
    data = request.json
    listing_id = data.get("listing_id")
    buyer_id = session["user_id"]
    
    conn = get_db()
    cur = conn.cursor()
    
    # Get Listing + Card + Seller info
    cur.execute("""
        SELECT l.*, c.owner_id as current_owner 
        FROM listings l
        JOIN cards c ON l.card_id = c.card_id
        WHERE l.listing_id = ?
    """, (listing_id,))
    listing = cur.fetchone()
    
    if not listing:
        conn.close()
        return jsonify({"error": "Not found"}), 404
        
    if listing["seller_id"] == buyer_id:
        conn.close()
        return jsonify({"error": "Cannot buy own"}), 400
        
    price = listing["price"]
    
    # Check Balance
    cur.execute("SELECT balance FROM users WHERE user_id = ?", (buyer_id,))
    buyer = cur.fetchone()
    if not buyer or buyer["balance"] < price:
        conn.close()
        return jsonify({"error": "Insufficient funds"}), 400
        
    try:
        # Transaction
        cur.execute("UPDATE users SET balance = balance - ? WHERE user_id = ?", (price, buyer_id))
        cur.execute("UPDATE users SET balance = balance + ? WHERE user_id = ?", (price, listing["seller_id"]))
        cur.execute("UPDATE cards SET owner_id = ? WHERE card_id = ?", (buyer_id, listing["card_id"]))
        cur.execute("DELETE FROM listings WHERE listing_id = ?", (listing_id,)) # Remove listing
        conn.commit()
        return jsonify({"success": True})
    except Exception as e:
        conn.rollback()
        return jsonify({"error": str(e)}), 500
    except Exception as e:
        conn.rollback()
        return jsonify({"error": str(e)}), 500
    finally:
        conn.close()

@app.route("/api/market_my_listings")
def market_my_listings():
    if "user_id" not in session: return jsonify([])
    conn = get_db()
    cur = conn.cursor()
    cur.execute("""
        SELECT l.listing_id, l.price, l.created_at, 
               c.*, 
               u.username as seller_name, u.avatar as seller_avatar
        FROM listings l
        JOIN cards c ON l.card_id = c.card_id
        JOIN users u ON l.seller_id = u.user_id
        WHERE l.seller_id = ?
        ORDER BY l.created_at DESC
    """, (session["user_id"],))
    listings = [dict(row) for row in cur.fetchall()]
    conn.close()
    return jsonify(listings)

@app.route("/api/market")
def get_market():
    conn = get_db()
    cur = conn.cursor()
    # Join with cards and users to get all info
    cur.execute("""
        SELECT l.listing_id, l.price, l.created_at, 
               c.*, 
               u.username as seller_name, u.avatar as seller_avatar
        FROM listings l
        JOIN cards c ON l.card_id = c.card_id
        JOIN users u ON l.seller_id = u.user_id
        ORDER BY l.created_at DESC
    """)
    listings = [dict(row) for row in cur.fetchall()]
    conn.close()
    return jsonify(listings)

@app.route("/api/sign_card", methods=["POST"])
def sign_card():
    if "user_id" not in session: return jsonify({"error": "Auth required"}), 401
    
    data = request.json
    card_id = data.get("card_id")
    signature = data.get("signature")[:25]
    
    conn = get_db()
    cur = conn.cursor()
    cur.execute("SELECT owner_id FROM cards WHERE card_id = ?", (card_id,))
    card = cur.fetchone()
    
    if not card or card["owner_id"] != session["user_id"]:
        conn.close()
        return jsonify({"error": "Not yours"}), 403
        
    cur.execute("UPDATE cards SET signature = ? WHERE card_id = ?", (signature, card_id))
    conn.commit()
    conn.close()
    return jsonify({"success": True})

@app.route("/view/<seed>")
def view_card(seed):
    conn = get_db()
    conn.row_factory = sqlite3.Row 
    cur = conn.cursor()
    
    cur.execute("SELECT * FROM cards WHERE seed = ?", (seed,))
    card_row = cur.fetchone()
    
    if not card_row:
        conn.close()
        return "<h1>404 Not Found</h1>"
    
    card = dict(card_row)
    owner_id = card['owner_id']
    owner_name = f"ID: {owner_id}"
    owner_avatar = f"https://cdn.discordapp.com/embed/avatars/{(int(owner_id) >> 22) % 6}.png"
    
    try:
        cur.execute("SELECT * FROM users WHERE user_id = ?", (owner_id,))
        user_row = cur.fetchone()
        if user_row:
            user_data = dict(user_row)
            if 'username' in user_data and user_data['username']: owner_name = user_data['username']
            if 'avatar' in user_data and user_data['avatar']:
                # If avatar is stored as path (new modular system style) or hash (old style)
                avatar_val = user_data['avatar']
                if avatar_val.startswith('/static/') or avatar_val.startswith('http'):
                    owner_avatar = avatar_val
                else:
                    owner_avatar = f"https://cdn.discordapp.com/avatars/{owner_id}/{avatar_val}.png"
    except Exception:
        pass
    
    conn.close()
    
    art_seed = int(seed[:8], 16)
    # Расширенный список мемных предметов
    emojis = [
        # Классика и Мемы
        '🗿', '💀', '🤡', '👽', '👾', '🤖', '👻', '💩', '👺', '👹',
        '🧢', '🕶️', '🎩', '🦠', '🧬', '🧠', '👁️', '👄', '🦴',

        # Оружие и Опасность
        '💣', '🧨', '🔪', '🗡️', '⚔️', '🛡️', '🪓', '🔫', '🩸', '💊', '💉',
        '🚬', '⚰️', '🪦', '🧯', '🔨', '🔧', '🪚', '⚓', '⚖️',

        # Космос и Магия
        '🚀', '🛸', '🪐', '🌑', '☀️', '⚡', '🔥', '❄️', '🌪️', '🌊',
        '🔮', '🧿', '⚗️', '🕯️', '🔦', '🧭', '🗝️', '🚪',

        # Деньги и Лут
        '💎', '👑', '💍', '🏆', '🥇', '💰', '💸', '💵', '💳', '🎰',
        '🎲', '🎱', '🎳', '🎮', '🕹️', '🎫', '🎁', '📦',

        # Техника
        '💻', '🖥️', '💾', '💿', '📼', '📷', '📹', '🎥', '📺', '📻',
        '📱', '📟', '📠', '🔋', '🔌', '📡', '🚗', '🚓', '🚜', '🏎️',

        # Еда и Растения
        '🍆', '🍑', '🍌', '🥑', '🌶️', '🌽', '🍄', '🌵', '🌲', '🍂',
        '🍔', '🍕', '🌭', '🌮', '🍣', '🍩', '🍪', '🍺', '🍷', '🥃',
        '🧂', '🍿', '🧀', '🍗', '🥩', '🍤', '🦞', '🦀',

        # Животные (Мемные)
        '🦍', '🦧', '🐕', '🐈', '🐅', '🦖', '🦕', '🦈', '🐊', '🐍',
        '🦅', '🦉', '🦇', '🦄', '🦆', '🦚', '🦜', '🦩', '🐀', '🐁',

        # Странное / Рандом
        '🚽', '🧻', '🪠', '🧼', '🧽', '🧱', '🧸', '🪑', '🛌', '🛒',
        '🚨', '🛑', '🚩', '🏁', '🚫', '⚠️', '💢', '💤', '💥', '💦'
    ]
    main_emoji = emojis[art_seed % len(emojis)]
    rarity_class = card["rarity"].lower()
    
    # Добавляем слой шиммера только для редких карт
    shimmer_div = '<div class="shimmer-layer"></div>' if rarity_class in ['legendary', 'epic', 'rare'] else ''
    
    return render_template_string(f"""
    <!DOCTYPE html>
    <html lang="ru">
    <head>
        <link rel="icon" type="image/svg+xml" href="favicon.svg">
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Xorgus Asset #{card['card_id']}</title>
        <link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@300;500;700&family=Bad+Script&display=swap" rel="stylesheet">
        <style>
            :root {{ --bg: #050505; --glass-border: rgba(255, 255, 255, 0.1); }}
            body {{ background: #050505; color: #fff; font-family: 'Space Grotesk', sans-serif; display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 100vh; margin: 0; background: radial-gradient(circle at 50% 0%, #1a1a2e 0%, #000 80%); }}
            
            .card-wrapper {{ width: 300px; height: 480px; position: relative; }}
            .card {{ width: 100%; height: 100%; border-radius: 24px; position: relative; overflow: hidden; border: 1px solid rgba(255,255,255,0.1); box-shadow: 0 25px 50px -12px rgba(0,0,0,0.6); display: flex; flex-direction: column; }}
            .card {{ background: linear-gradient(135deg, #2b2b38 0%, #101015 100%); }}
            
            /* Horizontal Shimmer */
            @keyframes shimmerMove {{ 0% {{ transform: translateX(-300%); }} 100% {{ transform: translateX(400%); }} }}
            
            .shimmer-layer {{
                position: absolute; top: 0; bottom: 0; width: 50%;
                background: linear-gradient(to right, transparent 0%, var(--shimmer-color, rgba(255,255,255,0.05)) 50%, transparent 100%);
                filter: blur(25px); opacity: 0.8; pointer-events: none; z-index: 10;
                transform: translateX(-300%);
                animation: shimmerMove 3.5s infinite linear;
                mix-blend-mode: overlay;
            }}

            .card-header {{ padding: 20px; display: flex; justify-content: space-between; z-index: 5; position: relative; }}
            .rarity-badge {{ font-size: 0.65rem; font-weight: 800; text-transform: uppercase; letter-spacing: 1px; padding: 5px 10px; border-radius: 12px; }}
            
            .card-art {{ height: 180px; display: flex; align-items: center; justify-content: center; font-size: 7rem; text-shadow: 0 10px 30px rgba(0,0,0,0.5); z-index: 5; position: relative; }}
            
            .card-body {{ padding: 0 20px; flex: 1; z-index: 5; position: relative; }}
            .stats-row {{ display: flex; gap: 10px; margin-bottom: 20px; }}
            .stat {{ background: rgba(255,255,255,0.05); padding: 8px; border-radius: 8px; flex: 1; text-align: center; border: 1px solid rgba(255,255,255,0.05); }}
            .stat span {{ display: block; }}
            
            .signature {{ font-family: 'Bad Script', cursive; font-size: 1.8rem; color: #e5e5e5; transform: rotate(-3deg); text-align: center; margin-top: 10px; text-shadow: 0 2px 4px rgba(0,0,0,0.8); }}
            
            .card-footer {{ padding: 15px 20px; background: rgb(16, 16, 22); border-top: 1px solid rgb(22 22 22); display: flex; align-items: center; gap: 10px; z-index: 5; position: relative; }}
            .owner-avatar {{ width: 32px; height: 32px; border-radius: 50%; }}
            
            .legendary {{ border-color: rgba(251, 191, 36, 0.5); box-shadow: 0 0 30px rgba(251, 191, 36, 0.15); }}
            .legendary .shimmer-layer {{ --shimmer-color: rgba(251, 191, 36, 0.4); animation-duration: 3s; }}
            .legendary .rarity-badge {{ background: #fbbf24; color: #000; }}
            
            .epic {{ border-color: rgba(192, 132, 252, 0.5); }}
            .epic .shimmer-layer {{ --shimmer-color: rgba(192, 132, 252, 0.35); animation-duration: 4s; }}
            .epic .rarity-badge {{ background: #c084fc; color: #fff; }}
            
            .rare {{ border-color: rgba(96, 165, 250, 0.5); }}
            .rare .shimmer-layer {{ --shimmer-color: rgba(96, 165, 250, 0.3); animation-duration: 5s; }}
            .rare .rarity-badge {{ background: #60a5fa; color: #000; }}
            
            .uncommon .rarity-badge {{ background: #4ade80; color: #000; }}
            .common .rarity-badge {{ background: #333; color: #888; }}
        </style>
    </head>
    <body>
        <div class="card-wrapper">
            <div class="card {rarity_class}">
                {shimmer_div}
                <div class="card-header">
                    <span class="rarity-badge">{card['rarity']}</span>
                    <span style="font-family:monospace; color:#555; font-size:0.8rem">#{card['card_id']}</span>
                </div>
                <div class="card-art">{main_emoji}</div>
                <div class="card-body">
                    <div class="stats-row">
                        <div class="stat"><span style="font-size:0.6rem; color:#888;">POWER</span><b>{card['power']}</b></div>
                        <div class="stat"><span style="font-size:0.6rem; color:#888;">LUCK</span><b>{card['luck']}%</b></div>
                    </div>
                    <div class="signature">{card['signature'] if card['signature'] else ''}</div>
                </div>
                <div class="card-footer">
                    <img src="{owner_avatar}" class="owner-avatar">
                    <div style="display:flex; flex-direction:column">
                        <span style="font-size:0.6rem; color:#666; line-height:1">OWNER</span>
                        <span style="font-size:0.8rem; font-weight:700">{owner_name}</span>
                    </div>
                </div>
            </div>
        </div>
        <p style="margin-top:20px; color:#4ade80; font-size:0.9rem">✓ Blockchain Verified Asset</p>
    </body>
    </html>
    """)

@app.route("/")
def index():
    return render_template("index.html")

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000, debug=True)
