# ui.py — message templates and keyboard builders for TDX BLACK HOST
import html
import psutil
import platform
from datetime import datetime
from typing import Optional, List
import telebot.types as types

BRAND = "TDX BLACK HOST"

# ── keyboards ──────────────────────────────────────────────────────────────

def main_menu_kb() -> types.InlineKeyboardMarkup:
    kb = types.InlineKeyboardMarkup(row_width=2)
    kb.add(
        types.InlineKeyboardButton("⬡ Dashboard", callback_data="dashboard"),
        types.InlineKeyboardButton("⬆ Upload Project", callback_data="upload"),
    )
    kb.add(
        types.InlineKeyboardButton("⬡ My Projects", callback_data="my_projects"),
        types.InlineKeyboardButton("⬡ Running", callback_data="running_projects"),
    )
    kb.add(
        types.InlineKeyboardButton("⬡ Statistics", callback_data="stats"),
        types.InlineKeyboardButton("⬡ Subscription", callback_data="subscription"),
    )
    kb.add(types.InlineKeyboardButton("⬡ Support", callback_data="support"))
    return kb


def project_kb(project_id: int, is_running: bool) -> types.InlineKeyboardMarkup:
    kb = types.InlineKeyboardMarkup(row_width=3)
    if is_running:
        kb.add(
            types.InlineKeyboardButton("■ Stop", callback_data=f"stop_{project_id}"),
            types.InlineKeyboardButton("↺ Restart", callback_data=f"restart_{project_id}"),
        )
    else:
        kb.add(
            types.InlineKeyboardButton("▶ Start", callback_data=f"start_{project_id}"),
        )
    kb.add(
        types.InlineKeyboardButton("⬡ Logs", callback_data=f"logs_{project_id}"),
        types.InlineKeyboardButton("⬇ Download", callback_data=f"download_{project_id}"),
        types.InlineKeyboardButton("⬡ Rescan", callback_data=f"rescan_{project_id}"),
    )
    kb.add(
        types.InlineKeyboardButton("✕ Delete", callback_data=f"del_confirm_{project_id}"),
        types.InlineKeyboardButton("← Back", callback_data="my_projects"),
    )
    return kb


def confirm_delete_kb(project_id: int) -> types.InlineKeyboardMarkup:
    kb = types.InlineKeyboardMarkup(row_width=2)
    kb.add(
        types.InlineKeyboardButton("✓ Confirm Delete", callback_data=f"del_execute_{project_id}"),
        types.InlineKeyboardButton("✕ Cancel", callback_data=f"project_{project_id}"),
    )
    return kb


def projects_list_kb(projects, prefix: str = "project") -> types.InlineKeyboardMarkup:
    kb = types.InlineKeyboardMarkup(row_width=1)
    for p in projects:
        status_icon = "▶" if p['status'] == 'running' else "■"
        label = f"{status_icon} {p['name'][:30]} [{p['file_type'].upper()}]"
        kb.add(types.InlineKeyboardButton(label, callback_data=f"{prefix}_{p['id']}"))
    kb.add(types.InlineKeyboardButton("← Back", callback_data="menu"))
    return kb


def back_kb(dest: str = "menu") -> types.InlineKeyboardMarkup:
    kb = types.InlineKeyboardMarkup()
    kb.add(types.InlineKeyboardButton("← Back", callback_data=dest))
    return kb


# ── admin keyboards ────────────────────────────────────────────────────────

def admin_main_kb() -> types.InlineKeyboardMarkup:
    kb = types.InlineKeyboardMarkup(row_width=2)
    kb.add(
        types.InlineKeyboardButton("⬡ System", callback_data="adm_system"),
        types.InlineKeyboardButton("⬡ Files", callback_data="adm_files"),
    )
    kb.add(
        types.InlineKeyboardButton("⬡ Users", callback_data="adm_users"),
        types.InlineKeyboardButton("⬡ Pending", callback_data="adm_pending"),
    )
    kb.add(
        types.InlineKeyboardButton("⬡ Broadcast", callback_data="adm_broadcast"),
        types.InlineKeyboardButton("⬡ Admins", callback_data="adm_admins"),
    )
    kb.add(
        types.InlineKeyboardButton("⬡ Bot Lock", callback_data="adm_lock_toggle"),
        types.InlineKeyboardButton("← Close", callback_data="menu"),
    )
    return kb


def admin_file_kb(project_id: int, is_running: bool) -> types.InlineKeyboardMarkup:
    kb = types.InlineKeyboardMarkup(row_width=3)
    if is_running:
        kb.add(
            types.InlineKeyboardButton("■ Stop", callback_data=f"adm_stop_{project_id}"),
            types.InlineKeyboardButton("↺ Restart", callback_data=f"adm_restart_{project_id}"),
        )
    else:
        kb.add(
            types.InlineKeyboardButton("▶ Start", callback_data=f"adm_start_{project_id}"),
        )
    kb.add(
        types.InlineKeyboardButton("⬇ Download", callback_data=f"adm_dl_{project_id}"),
        types.InlineKeyboardButton("⬡ Logs", callback_data=f"adm_logs_{project_id}"),
        types.InlineKeyboardButton("⬡ Rescan", callback_data=f"adm_rescan_{project_id}"),
    )
    kb.add(
        types.InlineKeyboardButton("✓ Approve", callback_data=f"adm_approve_{project_id}"),
        types.InlineKeyboardButton("✕ Reject", callback_data=f"adm_reject_{project_id}"),
    )
    kb.add(
        types.InlineKeyboardButton("✕ Delete", callback_data=f"adm_del_{project_id}"),
        types.InlineKeyboardButton("← Back", callback_data="adm_files"),
    )
    return kb


def admin_user_kb(target_id: int, is_banned: bool) -> types.InlineKeyboardMarkup:
    kb = types.InlineKeyboardMarkup(row_width=2)
    if is_banned:
        kb.add(types.InlineKeyboardButton("✓ Unban", callback_data=f"adm_unban_{target_id}"))
    else:
        kb.add(types.InlineKeyboardButton("✕ Ban", callback_data=f"adm_ban_{target_id}"))
    kb.add(
        types.InlineKeyboardButton("⬡ Files", callback_data=f"adm_userfiles_{target_id}"),
        types.InlineKeyboardButton("⬡ Sub", callback_data=f"adm_usersub_{target_id}"),
    )
    kb.add(types.InlineKeyboardButton("← Back", callback_data="adm_users"))
    return kb


def sub_change_kb(target_id: int) -> types.InlineKeyboardMarkup:
    kb = types.InlineKeyboardMarkup(row_width=2)
    for plan in ['FREE', 'PREMIUM', 'ADMIN']:
        kb.add(types.InlineKeyboardButton(
            plan, callback_data=f"adm_setplan_{target_id}_{plan}"
        ))
    kb.add(types.InlineKeyboardButton("← Back", callback_data=f"adm_user_{target_id}"))
    return kb


# ── message templates ──────────────────────────────────────────────────────

def header(title: str) -> str:
    return (
        f"<code>{'─' * 32}</code>\n"
        f"<b>  {BRAND}</b>\n"
        f"<code>{'─' * 32}</code>\n"
        f"<b>{title}</b>\n\n"
    )


def dashboard_msg(user, sub, projects, running_count: int) -> str:
    plan = sub['plan'] if sub else 'FREE'
    name = html.escape(user['first_name'] or 'Unknown')
    uname = f"@{html.escape(user['username'])}" if user['username'] else "—"
    return (
        header("HOSTING CONTROL CENTER") +
        f"<b>Operator:</b> {name} ({uname})\n"
        f"<b>Telegram ID:</b> <code>{user['user_id']}</code>\n"
        f"<b>Account Status:</b> {'🔴 Banned' if user['is_banned'] else '🟢 Active'}\n\n"
        f"<b>Plan:</b> <code>{plan}</code>\n"
        f"<b>Projects:</b> {len(projects)}\n"
        f"<b>Running:</b> {running_count}\n"
        f"<b>Joined:</b> <code>{user['created_at'][:10]}</code>\n"
    )


def project_detail_msg(project, stats: dict) -> str:
    name = html.escape(project['name'])
    status = project['status'].upper()
    approval = project['approval_status'].upper()
    scan = project['scan_result']
    size_kb = round(project['file_size'] / 1024, 1)
    alive = stats.get('alive', False)

    return (
        header("PROJECT DEPLOYMENT") +
        f"<b>Name:</b> <code>{name}</code>\n"
        f"<b>Type:</b> <code>{project['file_type'].upper()}</code>\n"
        f"<b>Size:</b> <code>{size_kb} KB</code>\n"
        f"<b>Created:</b> <code>{project['created_at'][:16]}</code>\n\n"
        f"<b>Status:</b> <code>{status}</code>\n"
        f"<b>Approval:</b> <code>{approval}</code>\n"
        f"<b>Scan:</b> <code>{scan}</code>\n\n"
        f"<b>Process:</b> {'🟢 Alive' if alive else '🔴 Inactive'}\n"
        f"<b>PID:</b> <code>{stats.get('pid', '—')}</code>\n"
        f"<b>CPU:</b> <code>{stats.get('cpu', 0)}%</code>\n"
        f"<b>RAM:</b> <code>{stats.get('ram_mb', 0)} MB</code>\n"
    )


def system_msg() -> str:
    cpu = psutil.cpu_percent(interval=0.5)
    ram = psutil.virtual_memory()
    disk = psutil.disk_usage('/')
    uptime_s = int(datetime.now().timestamp() - psutil.boot_time())
    h, rem = divmod(uptime_s, 3600)
    m = rem // 60
    return (
        header("SYSTEM OVERVIEW") +
        f"<b>CPU:</b> <code>{cpu}%</code>\n"
        f"<b>RAM:</b> <code>{ram.percent}% ({round(ram.used/1e9,1)}/{round(ram.total/1e9,1)} GB)</code>\n"
        f"<b>Disk:</b> <code>{disk.percent}% ({round(disk.used/1e9,1)}/{round(disk.total/1e9,1)} GB)</code>\n"
        f"<b>Uptime:</b> <code>{h}h {m}m</code>\n"
        f"<b>OS:</b> <code>{platform.system()} {platform.release()}</code>\n"
        f"<b>Python:</b> <code>{platform.python_version()}</code>\n"
    )


def admin_file_inspect_msg(project, owner, stats: dict) -> str:
    name = html.escape(project['name'])
    owner_name = html.escape(owner['first_name'] or 'Unknown') if owner else '—'
    size_kb = round(project['file_size'] / 1024, 1)
    details = html.escape(project['scan_details'] or '—')
    alive = stats.get('alive', False)

    return (
        header("FILE INSPECTION") +
        f"<b>Name:</b> <code>{name}</code>\n"
        f"<b>Owner:</b> {owner_name} (<code>{project['owner_id']}</code>)\n"
        f"<b>Type:</b> <code>{project['file_type'].upper()}</code>\n"
        f"<b>Size:</b> <code>{size_kb} KB</code>\n"
        f"<b>Created:</b> <code>{project['created_at'][:16]}</code>\n"
        f"<b>Status:</b> <code>{project['status'].upper()}</code>\n"
        f"<b>Approval:</b> <code>{project['approval_status'].upper()}</code>\n\n"
        f"<b>Process:</b> {'🟢 Alive' if alive else '🔴 Inactive'}\n"
        f"<b>PID:</b> <code>{stats.get('pid','—')}</code>\n"
        f"<b>CPU:</b> <code>{stats.get('cpu',0)}%</code>\n"
        f"<b>RAM:</b> <code>{stats.get('ram_mb',0)} MB</code>\n\n"
        f"<b>Scan Result:</b> <code>{project['scan_result']}</code>\n"
        f"<b>Findings:</b>\n<pre>{details}</pre>\n"
    )