from flask import Flask, request, jsonify
from playwright.sync_api import sync_playwright, TimeoutError as PlaywrightTimeoutError
import os
import re
from queue import Queue, Empty
import threading

app = Flask(__name__)

# JSON সেটিংস: স্পেশাল ক্যারেক্টার, Pretty Print এবং কাস্টম সিরিয়াল (Order) ঠিক রাখার জন্য
app.json.ensure_ascii = False
app.json.compact = False
app.json.indent = 2
app.json.sort_keys = False # এটি ডেটাকে আপনার দেওয়া সিরিয়ালেই রাখবে, A-Z সাজাবে না

REDX_URL = os.getenv("REDX_CHECKER_URL", "https://redxgame.com/tools/free-fire-id-checker")
UID_RE = re.compile(r"^\d{6,15}$")

# Playwright Background Worker Globals
playwright_queue = Queue()
playwright_ready = threading.Event()

# Database Config

def clean(value):
    return re.sub(r"\s+", " ", (value or "")).strip()

def extract_profile(page, uid):
    try:
        page.get_by_text(re.compile(r"Account\s*found", re.I)).first.wait_for(
            state="visible", timeout=8000
        )
    except PlaywrightTimeoutError:
        pass

    account_found = page.get_by_text(re.compile(r"^Account\s*found$", re.I)).first
    if account_found.count() == 0:
        account_found = page.get_by_text(re.compile(r"Account\s*found", re.I)).first

    if account_found.count() == 0:
        return None

    card = account_found.locator("xpath=..")
    for _ in range(5):
        try:
            text = clean(card.inner_text(timeout=1500))
        except Exception:
            text = ""
        if "Nickname" in text and "Region" in text:
            break
        card = card.locator("xpath=..")

    try:
        card_text = card.inner_text(timeout=3000)
    except Exception:
        card_text = page.locator("body").inner_text(timeout=3000)

    lines = [clean(x) for x in card_text.splitlines() if clean(x)]
    nickname = None
    region = None

    for i, line in enumerate(lines):
        normalized = line.lower().rstrip(":")
        if normalized == "nickname":
            for candidate in lines[i + 1:]:
                if candidate.lower().rstrip(":") not in {"account found", "nickname", "region"}:
                    nickname = candidate
                    break
        elif normalized == "region":
            for candidate in lines[i + 1:]:
                if candidate.lower().rstrip(":") not in {"account found", "nickname", "region"}:
                    region = candidate
                    break

    if not nickname or not region:
        try:
            rows = card.locator("tr")
            for i in range(rows.count()):
                cells = rows.nth(i).locator("th,td")
                values = [clean(cells.nth(j).inner_text()) for j in range(cells.count())]
                if len(values) >= 2:
                    key = values[0].lower().rstrip(":")
                    if key == "nickname":
                        nickname = values[1]
                    elif key == "region":
                        region = values[1]
        except Exception:
            pass

    if not nickname:
        m = re.search(r"Nickname\s*[:\n]\s*([^\n]+)", card_text, re.I)
        if m:
            nickname = clean(m.group(1))

    if not region:
        m = re.search(r"Region\s*[:\n]\s*([^\n]+)", card_text, re.I)
        if m:
            region = clean(m.group(1))

    bad = {"region", "nickname", "account found", "garena free fire top-ups are delivered to your player id instantly"}
    if nickname and nickname.lower() in bad:
        nickname = None

    if not nickname:
        return None

    return {
        "uid": uid,
        "nickname": nickname,
        "region": region or "Unknown",
        "account_found": True,
    }

def playwright_worker():
    with sync_playwright() as p:
        browser = p.chromium.launch(
            headless=True,
            args=["--no-sandbox", "--disable-dev-shm-usage"]
        )
        page = browser.new_page(
            viewport={"width": 1280, "height": 900},
            user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36"
        )
        
        # Block heavy resources to drastically speed up page loads
        page.route("**/*", lambda route: route.abort() if route.request.resource_type in ["image", "stylesheet", "font", "media"] else route.continue_())
        
        # Pre-load the website
        try:
            page.goto(REDX_URL, wait_until="domcontentloaded", timeout=30000)
        except Exception:
            pass
            
        playwright_ready.set()
        print("✅ Playwright Background Worker Ready!")
        
        while True:
            try:
                job = playwright_queue.get(timeout=1.0)
                if job is None: continue
                uid, result_event, result_dict = job
                
                try:
                    # If page crashed or closed, recreate it
                    if page.is_closed():
                        page = browser.new_page(viewport={"width": 1280, "height": 900})
                        page.route("**/*", lambda route: route.abort() if route.request.resource_type in ["image", "stylesheet", "font", "media"] else route.continue_())
                    
                    if REDX_URL not in page.url:
                        page.goto(REDX_URL, wait_until="domcontentloaded", timeout=15000)
                        
                    uid_input = page.locator("#user_id")
                    uid_input.wait_for(state="visible", timeout=10000)
                    # Clear and fill the input
                    uid_input.fill("")
                    uid_input.fill(str(uid))

                    check = page.get_by_role("button", name=re.compile(r"^Check Account$", re.I)).first
                    check.wait_for(state="visible", timeout=10000)
                    check.click()

                    try:
                        page.get_by_text(re.compile(r"^Account\s*found$", re.I)).first.wait_for(state="visible", timeout=12000)
                    except PlaywrightTimeoutError:
                        pass # Let extract_profile handle checking again

                    res = extract_profile(page, uid)
                    result_dict['data'] = res
                    
                    # Refresh page for next request instantly to reset state
                    page.goto(REDX_URL, wait_until="domcontentloaded", timeout=15000)
                    
                except Exception as e:
                    result_dict['error'] = str(e)
                    print("Playwright Worker Error:", e)
                finally:
                    result_event.set()
                    playwright_queue.task_done()
                    
            except Empty:
                pass

# Start the worker thread
worker_thread = threading.Thread(target=playwright_worker, daemon=True)
worker_thread.start()

def lookup_redx(uid):
    # Wait max 10 seconds for Playwright to initialize on first boot
    playwright_ready.wait(timeout=10.0)
    
    result_event = threading.Event()
    result_dict = {}
    
    playwright_queue.put((uid, result_event, result_dict))
    
    # Wait for the worker to process this UID
    if result_event.wait(timeout=30.0):
        return result_dict.get('data')
    
    return None

@app.get("/api/name-check")
def api_name_check():
    uid = request.args.get("uid", "").strip()

    if not UID_RE.fullmatch(uid):
        return jsonify({
            "status": False,
            "data": {
                "massage": "Enter a valid numeric Free Fire Player ID.",
                "developer": "@DeVe_Rahman"
            }
        }), 400

    try:
        data = lookup_redx(uid)
        
        if data and data.get("nickname"):
            return jsonify({
                "status": True,
                "data": {
                    "status": True,
                    "username": data["nickname"],
                    "developer": "@DeVe_Rahman"
                }
            })
        else:
            return jsonify({
                "status": False,
                "data": {
                    "massage": "Account not found",
                    "developer": "@DeVe_Rahman"
                }
            }), 404

    except Exception as e:
        app.logger.exception("REDX lookup failed")
        return jsonify({
            "status": False,
            "data": {
                "massage": "Server error during lookup.",
                "developer": "@DeVe_Rahman"
            }
        }), 500

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=int(os.getenv("PORT", "5000")), debug=False)