from telegram import Update
from telegram.ext import ContextTypes
from config.settings import DOCS_URL, ADMIN_IDS, BOT_TYPE, ALLOWED_ROLE
from services import merchant as msvc
from services.merchant import DEP_STATUS, WD_STATUS


ROLE_LABEL = "Merchant" if ALLOWED_ROLE == 2 else "Reseller"
ROLE_LABEL_BN = "মার্চেন্ট" if ALLOWED_ROLE == 2 else "রিসেলার"

PRIVATE_ONLY_MSG = (
    f"🚫 এই বট *শুধু গ্রুপে* কাজ করে।\n\n"
    f"পার্সোনাল চ্যাটে ব্যালেন্স / অর্ডার দেখা যাবে না।\n\n"
    f"👉 বটকে আপনার গ্রুপে Add করুন, তারপর গ্রুপে:\n"
    f"`/link username আপনার_{ROLE_LABEL.lower()}_username`\n"
    f"লিংক হলে গ্রুপ থেকে `/balance` ব্যবহার করুন।"
)


def is_group(update: Update) -> bool:
    chat = update.effective_chat
    return chat is not None and chat.type in ("group", "supergroup")


async def require_group(update: Update) -> bool:
    if is_group(update):
        return True
    await update.effective_message.reply_text(PRIVATE_ONLY_MSG, parse_mode="Markdown")
    return False


async def resolve_user(update: Update):
    chat = update.effective_chat
    if chat and chat.type in ("group", "supergroup"):
        return await msvc.get_group_linked(chat.id)
    return None


async def require_link(update: Update):
    if not await require_group(update):
        return None
    user = await resolve_user(update)
    if user:
        return user
    await update.effective_message.reply_text(
        f"❌ এই গ্রুপ এখনো কোনো {ROLE_LABEL_BN}-এর সাথে লিংক নেই।\n\n"
        "এই গ্রুপেই লিখুন:\n"
        f"• `/link username {ROLE_LABEL.lower()}_username`\n"
        "• `/link key API_KEY`\n\n"
        f"উদাহরণ: `/link username my{ROLE_LABEL.lower()}01`",
        parse_mode="Markdown",
    )
    return None


def fmt_money(amount) -> str:
    try:
        return f"{float(amount):,.2f} BDT"
    except Exception:
        return str(amount)


# ---------- Commands ----------

async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
    if not is_group(update):
        await update.effective_message.reply_text(PRIVATE_ONLY_MSG, parse_mode="Markdown")
        return

    user = update.effective_user
    linked = await resolve_user(update)

    if linked:
        text = (
            f"স্বাগতম, {user.first_name}!\n\n"
            f"✅ এই গ্রুপ লিংকড: *{linked['username']}* ({ROLE_LABEL})\n"
            f"💰 ব্যালেন্স: *{fmt_money(linked['balance'])}*\n\n"
            "কমান্ডসমূহ (শুধু এই গ্রুপে):\n"
            "/balance — ব্যালেন্স\n"
            "/payin <order_no> — Payin চেক\n"
            "/payout <order_no> — Payout চেক\n"
            "/recent — সাম্প্রতিক অর্ডার\n"
            "/status — লিংক স্ট্যাটাস\n"
            "/unlink — গ্রুপ আনলিংক\n"
            "/help — সাহায্য"
        )
    else:
        text = (
            f"স্বাগতম! ({ROLE_LABEL} Bot)\n\n"
            f"এই *গ্রুপ* এখনো কোনো {ROLE_LABEL_BN}-এর সাথে লিংক নেই।\n\n"
            "এখানেই লিখুন:\n"
            f"`/link username your_{ROLE_LABEL.lower()}`\n"
            "`/link key pk_live_xxxx`\n\n"
            "একবার লিংক হলে গ্রুপের *সবাই* `/balance` দিয়ে দেখতে পারবে।"
        )

    await update.effective_message.reply_text(text, parse_mode="Markdown")


async def help_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE):
    if not await require_group(update):
        return
    text = (
        f"*📋 কমান্ড তালিকা* ({ROLE_LABEL} Bot – শুধু গ্রুপে)\n\n"
        f"`/link username <name>` — গ্রুপ লিংক (Username)\n"
        f"`/link key <api_key>` — গ্রুপ লিংক (API Key)\n"
        "`/balance` — ব্যালেন্স\n"
        "`/payin <order_no>` — Payin অর্ডার\n"
        "`/payout <order_no>` — Payout অর্ডার\n"
        "`/recent` — শেষ ৫টি অর্ডার\n"
        "`/status` — গ্রুপ লিংক স্ট্যাটাস\n"
        "`/unlink` — গ্রুপ আনলিংক\n"
        "`/apidoc` — API ডকুমেন্টেশন\n"
        "`/help` — এই মেসেজ\n\n"
        "⚠️ পার্সোনাল চ্যাটে এই বট কাজ করে না।\n"
        f"📖 {DOCS_URL}"
    )
    await update.effective_message.reply_text(text, parse_mode="Markdown")


async def link(update: Update, context: ContextTypes.DEFAULT_TYPE):
    if not await require_group(update):
        return

    user = update.effective_user
    chat = update.effective_chat
    args = context.args or []

    if len(args) < 2:
        await update.effective_message.reply_text(
            "❌ ভুল ফরম্যাট।\n\n"
            "সঠিক ব্যবহার (শুধু গ্রুপে):\n"
            f"`/link username your_{ROLE_LABEL.lower()}`\n"
            "`/link key your_api_key`",
            parse_mode="Markdown",
        )
        return

    method = args[0].lower().strip()
    value = " ".join(args[1:]).strip()

    if method == "username":
        found = await msvc.find_by_username(value)
        linked_by = "username"
    elif method == "key":
        found = await msvc.find_by_api_key(value)
        linked_by = "api_key"
    else:
        await update.effective_message.reply_text(
            "❌ প্রথম আর্গুমেন্ট হতে হবে `username` অথবা `key`",
            parse_mode="Markdown",
        )
        return

    if not found:
        await update.effective_message.reply_text(
            f"❌ কোনো অ্যাক্টিভ {ROLE_LABEL_BN} পাওয়া যায়নি।\n"
            f"Username / API Key ঠিক আছে কিনা এবং role={ALLOWED_ROLE} কিনা চেক করুন।"
        )
        return

    await msvc.link_group(
        chat_id=chat.id,
        chat_title=chat.title,
        merchant_id=found["id"],
        linked_by_user_id=user.id,
        linked_by=linked_by,
    )

    await update.effective_message.reply_text(
        f"✅ গ্রুপ সফলভাবে লিংক হয়েছে!\n\n"
        f"👤 {ROLE_LABEL}: *{found['username']}*\n"
        f"💰 ব্যালেন্স: *{fmt_money(found['balance'])}*\n\n"
        "এখন থেকে এই গ্রুপের সবাই `/balance`, `/payin`, `/payout` ব্যবহার করতে পারবে।",
        parse_mode="Markdown",
    )


async def unlink(update: Update, context: ContextTypes.DEFAULT_TYPE):
    if not await require_group(update):
        return

    linked = await resolve_user(update)
    if not linked:
        await update.effective_message.reply_text("❌ এই গ্রুপ এখনো লিংকড নয়।")
        return

    await msvc.unlink_group(update.effective_chat.id)
    await update.effective_message.reply_text(
        f"✅ গ্রুপ আনলিংক হয়েছে।\nআগে লিংকড ছিল: *{linked['username']}*",
        parse_mode="Markdown",
    )


async def status(update: Update, context: ContextTypes.DEFAULT_TYPE):
    if not await require_group(update):
        return

    linked = await resolve_user(update)
    if linked:
        text = (
            f"🔗 *লিংক স্ট্যাটাস*\n\n"
            f"✅ লিংকড: *{linked['username']}* ({ROLE_LABEL})\n"
            f"💰 ব্যালেন্স: *{fmt_money(linked['balance'])}*\n"
            f"📅 লিংকড অ্যাট: `{linked.get('linked_at', 'N/A')}`"
        )
    else:
        text = f"❌ এই গ্রুপ কোনো {ROLE_LABEL_BN}-এর সাথে লিংকড নয়।"

    await update.effective_message.reply_text(text, parse_mode="Markdown")


async def balance(update: Update, context: ContextTypes.DEFAULT_TYPE):
    linked = await require_link(update)
    if not linked:
        return
    bal = await msvc.get_balance(linked["id"])
    await update.effective_message.reply_text(
        f"💰 *{linked['username']}*\n"
        f"ব্যালেন্স: *{fmt_money(bal)}*",
        parse_mode="Markdown",
    )


async def payin(update: Update, context: ContextTypes.DEFAULT_TYPE):
    linked = await require_link(update)
    if not linked:
        return
    args = context.args or []
    if not args:
        await update.effective_message.reply_text(
            "❌ অর্ডার নম্বর দিন।\nউদাহরণ: `/payin ORD123456`",
            parse_mode="Markdown",
        )
        return

    order = await msvc.get_payin_order(linked["id"], args[0])
    if not order:
        await update.effective_message.reply_text("❌ এই অর্ডার পাওয়া যায়নি।")
        return

    st = DEP_STATUS.get(order["status"], str(order["status"]))
    text = (
        f"📥 *Payin Order*\n\n"
        f"Order: `{order['order_no']}`\n"
        f"Amount: *{fmt_money(order['amount'])}*\n"
        f"Status: *{st}*\n"
        f"Created: `{order['created_at']}`"
    )
    await update.effective_message.reply_text(text, parse_mode="Markdown")


async def payout(update: Update, context: ContextTypes.DEFAULT_TYPE):
    linked = await require_link(update)
    if not linked:
        return
    args = context.args or []
    if not args:
        await update.effective_message.reply_text(
            "❌ অর্ডার নম্বর দিন।\nউদাহরণ: `/payout WD123456`",
            parse_mode="Markdown",
        )
        return

    order = await msvc.get_payout_order(linked["id"], args[0])
    if not order:
        await update.effective_message.reply_text("❌ এই অর্ডার পাওয়া যায়নি।")
        return

    st = WD_STATUS.get(order["status"], str(order["status"]))
    text = (
        f"📤 *Payout Order*\n\n"
        f"Order: `{order['order_no']}`\n"
        f"Amount: *{fmt_money(order['amount'])}*\n"
        f"Status: *{st}*\n"
        f"Created: `{order['created_at']}`"
    )
    await update.effective_message.reply_text(text, parse_mode="Markdown")


async def recent(update: Update, context: ContextTypes.DEFAULT_TYPE):
    linked = await require_link(update)
    if not linked:
        return

    payins = await msvc.get_recent_payins(linked["id"], 5)
    payouts = await msvc.get_recent_payouts(linked["id"], 5)

    lines = [f"📋 *সাম্প্রতিক অর্ডার* — {linked['username']}\n"]
    lines.append("*Payin:*")
    if payins:
        for o in payins:
            st = DEP_STATUS.get(o["status"], str(o["status"]))
            lines.append(f"• `{o['order_no']}` {fmt_money(o['amount'])} — {st}")
    else:
        lines.append("• কোনো নেই")

    lines.append("\n*Payout:*")
    if payouts:
        for o in payouts:
            st = WD_STATUS.get(o["status"], str(o["status"]))
            lines.append(f"• `{o['order_no']}` {fmt_money(o['amount'])} — {st}")
    else:
        lines.append("• কোনো নেই")

    await update.effective_message.reply_text("\n".join(lines), parse_mode="Markdown")


async def apidoc(update: Update, context: ContextTypes.DEFAULT_TYPE):
    if not await require_group(update):
        return
    await update.effective_message.reply_text(
        f"📖 *API Documentation*\n\n{DOCS_URL}",
        parse_mode="Markdown",
    )


async def unknown(update: Update, context: ContextTypes.DEFAULT_TYPE):
    if not is_group(update):
        return
    await update.effective_message.reply_text(
        "❓ অজানা কমান্ড। `/help` লিখুন।"
    )
