import asyncio
import sys
from datetime import datetime, timezone

import aiohttp

# ============== CONFIGURATION ==============

INSTANCES = [
    "https://your-instance-1.example.com",
    "https://your-instance-2.example.com",
]

IMDB_ID = "tt30472557"
CHECK_INTERVAL = 300
TIMEOUT = 30

WEBHOOK_URL = "https://discord.com/api/webhooks/YOUR_WEBHOOK_ID/YOUR_WEBHOOK_TOKEN"
WEBHOOK_USERNAME = "Comet Monitor"
WEBHOOK_AVATAR = "https://raw.githubusercontent.com/g0ldyy/comet/refs/heads/main/comet/assets/icon.png"

# ===========================================


C_RESET = "\033[0m"
C_DIM = "\033[2m"
C_BOLD = "\033[1m"
C_GREEN = "\033[38;5;114m"
C_YELLOW = "\033[38;5;221m"
C_RED = "\033[38;5;203m"
C_CYAN = "\033[38;5;117m"
C_GRAY = "\033[38;5;245m"


class InstanceStatus:
    def __init__(
        self,
        url: str,
        is_online: bool,
        manifest_ok: bool,
        search_ok: bool,
        response_time: float,
        error: str | None,
    ):
        self.url = url
        self.is_online = is_online
        self.manifest_ok = manifest_ok
        self.search_ok = search_ok
        self.response_time = response_time
        self.error = error


async def check_instance(session: aiohttp.ClientSession, url: str) -> InstanceStatus:
    start = asyncio.get_event_loop().time()
    manifest_ok = False
    search_ok = False
    error = None

    try:
        async with session.get(f"{url}/manifest.json") as resp:
            if resp.status == 200:
                data = await resp.json()
                manifest_ok = "id" in data and "resources" in data
    except Exception as e:
        error = str(e)[:60]

    if manifest_ok:
        try:
            async with session.get(f"{url}/stream/movie/{IMDB_ID}.json") as resp:
                if resp.status == 200:
                    data = await resp.json()
                    streams = data.get("streams", [])
                    search_ok = len(streams) > 0 or resp.status == 200
        except Exception as e:
            if not error:
                error = str(e)[:60]

    response_time = asyncio.get_event_loop().time() - start

    return InstanceStatus(
        url=url,
        is_online=manifest_ok,
        manifest_ok=manifest_ok,
        search_ok=search_ok,
        response_time=response_time,
        error=error,
    )


def build_embed(status: InstanceStatus) -> dict:
    instance_name = status.url.replace("https://", "").replace("http://", "")
    timestamp = datetime.now(timezone.utc).isoformat()

    if status.is_online and status.search_ok:
        color = 0x43B581
        description = "● Instance is healthy and responding"
    elif status.is_online:
        color = 0xFAA61A
        description = "◐ Instance is online but search may be slow"
    else:
        color = 0xF04747
        description = "○ Instance is unreachable"

    manifest_value = "✓ Valid" if status.manifest_ok else "✗ Failed"
    search_value = "✓ Working" if status.search_ok else "✗ Failed"

    fields = [
        {
            "name": "Response Time",
            "value": f"```\n{status.response_time:.2f}s\n```",
            "inline": True,
        },
        {
            "name": "Manifest",
            "value": f"```\n{manifest_value}\n```",
            "inline": True,
        },
        {
            "name": "Search API",
            "value": f"```\n{search_value}\n```",
            "inline": True,
        },
    ]

    if status.error:
        fields.append(
            {
                "name": "Error",
                "value": f"```\n{status.error}\n```",
                "inline": False,
            }
        )

    return {
        "embeds": [
            {
                "title": f"☄️ {instance_name}",
                "url": status.url,
                "description": description,
                "color": color,
                "fields": fields,
                "footer": {
                    "icon_url": WEBHOOK_AVATAR,
                },
                "timestamp": timestamp,
            }
        ],
        "username": WEBHOOK_USERNAME,
        "avatar_url": WEBHOOK_AVATAR,
    }


async def send_webhook(session: aiohttp.ClientSession, payload: dict) -> bool:
    try:
        async with session.post(WEBHOOK_URL, json=payload) as resp:
            return resp.status in (200, 204)
    except Exception:
        return False


def print_status(status: InstanceStatus) -> None:
    timestamp = datetime.now().strftime("%H:%M:%S")
    instance_name = status.url.replace("https://", "").replace("http://", "")

    if status.is_online and status.search_ok:
        indicator = f"{C_GREEN}●{C_RESET}"
        state = "operational"
        state_color = C_GREEN
    elif status.is_online:
        indicator = f"{C_YELLOW}◐{C_RESET}"
        state = "degraded"
        state_color = C_YELLOW
    else:
        indicator = f"{C_RED}○{C_RESET}"
        state = "offline"
        state_color = C_RED

    latency = f"{status.response_time:>6.2f}s"

    manifest_check = (
        f"{C_GREEN}✓{C_RESET}" if status.manifest_ok else f"{C_RED}✗{C_RESET}"
    )
    search_check = f"{C_GREEN}✓{C_RESET}" if status.search_ok else f"{C_RED}✗{C_RESET}"

    print(
        f"  {C_DIM}{timestamp}{C_RESET}  {indicator}  {C_BOLD}{instance_name:<40}{C_RESET}  "
        f"{state_color}{state:<11}{C_RESET}  {C_CYAN}{latency}{C_RESET}  {C_GRAY}[{manifest_check}{C_GRAY}/{search_check}{C_GRAY}]{C_RESET}"
    )

    if status.error:
        print(f"             {C_DIM}└─ {status.error}{C_RESET}")


async def monitor_instance(session: aiohttp.ClientSession, url: str) -> None:
    while True:
        status = await check_instance(session, url)
        print_status(status)

        payload = build_embed(status)
        await send_webhook(session, payload)

        await asyncio.sleep(CHECK_INTERVAL)


def print_header() -> None:
    print()
    print(f"  {C_BOLD}☄️  Comet Uptime Monitor{C_RESET}")
    print(f"  {C_DIM}{'─' * 50}{C_RESET}")
    print(
        f"  {C_GRAY}Instances: {C_RESET}{len(INSTANCES)}  {C_GRAY}│  Interval: {C_RESET}{CHECK_INTERVAL}s"
    )
    print()
    for inst in INSTANCES:
        name = inst.replace("https://", "").replace("http://", "")
        print(f"  {C_DIM}•{C_RESET} {name}")
    print()
    print(f"  {C_DIM}{'─' * 50}{C_RESET}")
    print()


async def main() -> None:
    print_header()

    timeout = aiohttp.ClientTimeout(total=TIMEOUT)
    async with aiohttp.ClientSession(timeout=timeout) as session:
        tasks = [monitor_instance(session, url) for url in INSTANCES]
        await asyncio.gather(*tasks)


if __name__ == "__main__":
    try:
        asyncio.run(main())
    except KeyboardInterrupt:
        print(f"\n  {C_GREEN}✓{C_RESET} Stopped\n")
        sys.exit(0)
