from fastapi import FastAPI, Query
import requests, time
from bs4 import BeautifulSoup
from fastapi.responses import RedirectResponse
from datetime import datetime
app = FastAPI(title="FIDE DATA FETCHER")


@app.get("/")
def home():
    return RedirectResponse(url="/docs")


@app.get("/top_players")
def get_top_players(limit: int = 100, gender: str = "women/open"):
    try:
        headers = {
            "User-Agent": "Mozilla/5.0"
        }
        url = f"https://ratings.fide.com/a_top.php?list={gender}"
        response = requests.get(url, headers=headers, timeout=10)
        response.raise_for_status()
        soup = BeautifulSoup(response.text, "html.parser")
        table_selector = ".top_recors_table"
        table = soup.select_one(table_selector)
        rows: list = table.find_all("tr")
        rows.pop(0)
        top_players = []
        for i, row in enumerate(rows):
            if i+1 <= limit:
                raw_row = []
                for column in row.find_all("td"):
                    raw_data = column.get_text().replace(u'\xa0', '')
                    raw_row.append(raw_data)
                    player_url = column.find("a")
                    if player_url: 
                        raw_row.append(player_url["href"].split("/")[-1])
                top_players.append({
                  "rank": raw_row[0],
                  "name": raw_row[1],
                  "fide_id": raw_row[2],
                  "country": raw_row[3].strip(),
                  "rating": raw_row[4],
                })
        return top_players

    except Exception as e:
        return {
            "error": str(e)
        }


@app.get("/top_country_players")
def get_top_country_players(limit: int = 100, country: str = "BAN", gender: str = 'M'):
    try:
        headers = {
            "User-Agent": "Mozilla/5.0",
            "X-Requested-With": "XMLHttpRequest",
            "Referer": "https://ratings.fide.com/"
        }        
        url = f"https://ratings.fide.com/a_top_var.php?continent=&country={country}&rating=&gender={gender}&age1=&age2=&period=&period2="
        response = requests.get(url, headers=headers, timeout=10)
        response.raise_for_status()
        soup = BeautifulSoup(response.text, "html.parser")
        rows: list = soup.find_all("tr")
        rows.pop(0)
        top_country_players = []
        for i, row in enumerate(rows):
            if i+1 <= limit:
                raw_row = []
                for column in row.find_all("td"):
                    raw_data = column.get_text().replace(u'\xa0', '')
                    raw_row.append(raw_data)
                    player_url = column.find("a")
                    if player_url: 
                        raw_row.append(player_url["href"].split("/")[-1])
                top_country_players.append({
                  "rank": raw_row[0],
                  "name": raw_row[1],
                  "fide_id": raw_row[2],
                  "country": raw_row[3].strip(),
                  "rating": raw_row[4],
                })
        return top_country_players

    except Exception as e:
        return {
            "error": str(e)
        }

    except Exception as e:
        return {
            "error": str(e)
        }


@app.get("/tournaments")
def get_tournaments():
    try:
        headers = {
            "User-Agent": "Mozilla/5.0",
            "X-Requested-With": "XMLHttpRequest",
            "Referer": "https://ratings.fide.com/"
        }

        url = f"https://ratings.fide.com/a_tournaments.php?country=all&_={int(time.time()*1000)}"

        response = requests.get(url, headers=headers, timeout=10)
        response.raise_for_status()
        data = response.json()
        tournaments = []

        today = datetime.now().date()

        for row in data["data"]:
            try:
                start_date = datetime.fromisoformat(row[4]).date()
                end_date = datetime.fromisoformat(row[5]).date()

                if (start_date < today) and (end_date < today):
                    continue

                tournaments.append({
                    "id": row[0],
                    "name": row[1],
                    "location": row[2],
                    "start_date": row[4],
                    "end_date": row[5],
                })

            except Exception:
                continue

        return {
            "count": len(tournaments),
            "tournaments": tournaments
        }

    except Exception as e:
        return {"error": str(e)}
        
        
@app.get("/get_country_tournaments")
def get_country_tournaments():
    try:
        headers = {
            "User-Agent": "Mozilla/5.0",
            "X-Requested-With": "XMLHttpRequest",
            "Referer": "https://ratings.fide.com/"
        }

        url = f"https://ratings.fide.com/a_tournaments.php?country=BAN&period=current&_={int(time.time()*1000)}"

        response = requests.get(url, headers=headers, timeout=10)
        response.raise_for_status()

        try:
            data = response.json()
        except Exception:
            return {
                "error": "Response is not JSON",
                "preview": response.text[:300]
            }

        rows = data.get("data")
        country_tournaments = []
        today = datetime.now().date()

        for row in rows:
            try:
                start_date = datetime.fromisoformat(row[4]).date()

                if row[5]:
                    end_date = datetime.fromisoformat(row[5]).date()
                else:
                    end_date = start_date

                if start_date > end_date:
                    start_date, end_date = end_date, start_date

                if end_date < today:
                    continue

                country_tournaments.append({
                    "id": row[0],
                    "name": row[1],
                    "location": row[2],
                    "start_date": start_date.isoformat(),
                    "end_date": end_date.isoformat(),
                })

            except Exception as e:
                print("ERROR:", row, e) 
                continue

        return {
            "count": len(country_tournaments),
            "country_tournaments": country_tournaments
        }

    except Exception as e:
        return {"error": str(e)}
