
import os
import sqlite3
import requests
from flask import Flask, request, abort

app = Flask(__name__)

TOKEN = os.environ.get("BOT_TOKEN", "")
ADMIN_ID = int(os.environ.get("ADMIN_ID", "8291127289"))
WEBHOOK_SECRET = os.environ.get("WEBHOOK_SECRET", "")

API = f"https://api.telegram.org/bot{TOKEN}"
DB = os.path.join(os.path.dirname(__file__), "shop.db")

CATEGORIES = {
    "kitchen": "🍳 لوازم آشپزخانه",
    "cleaning": "🧹 لوازم نظافت",
    "home": "🏠 لوازم خانه",
}


def db():
    con = sqlite3.connect(DB)
    con.row_factory = sqlite3.Row
    return con


def init_db():
    with db() as con:
        con.execute("""
            CREATE TABLE IF NOT EXISTS products (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                name TEXT NOT NULL,
                price INTEGER NOT NULL,
                category TEXT NOT NULL,
                stock INTEGER NOT NULL DEFAULT 0
            )
        """)
        con.execute("""
            CREATE TABLE IF NOT EXISTS customers (
                user_id INTEGER PRIMARY KEY,
                state TEXT,
                product_id INTEGER
            )
        """)
        con.execute("""
            CREATE TABLE IF NOT EXISTS orders (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                user_id INTEGER,
                name TEXT,
                phone TEXT,
                address TEXT,
                product TEXT,
                price INTEGER,
                status TEXT DEFAULT 'جدید'
            )
        """)
        count = con.execute(
            "SELECT COUNT(*) FROM products"
        ).fetchone()[0]

        if count == 0:
            con.executemany(
                """INSERT INTO products
                   (name, price, category, stock)
                   VALUES (?, ?, ?, ?)""",
                [
                    ("کتری برقی", 850000, "kitchen", 10),
                    ("مخلوط‌کن", 1450000, "kitchen", 5),
                    ("جاروبرقی", 6500000, "cleaning", 3),
                    ("پنکه", 2300000, "home", 8),
                ],
            )


def send(chat_id, text, keyboard=None):
    payload = {"chat_id": chat_id, "text": text}
    if keyboard:
        payload["reply_markup"] = keyboard

    try:
        r = requests.post(
            f"{API}/sendMessage", json=payload, timeout=15
        )
        r.raise_for_status()
    except requests.RequestException:
        app.logger.exception("Telegram sendMessage failed")


def buttons(rows):
    return {"inline_keyboard": rows}


def main_menu():
    return buttons([
        [{"text": "🛍️ مشاهده محصولات", "callback_data": "categories"}],
        [{"text": "📦 سفارش‌های من", "callback_data": "myorders"}],
        [{"text": "☎️ پشتیبانی", "callback_data": "support"}],
    ])


def contact_keyboard():
    return {
        "keyboard": [[{
            "text": "📱 ارسال شماره تماس",
            "request_contact": True
        }]],
        "resize_keyboard": True,
        "one_time_keyboard": True,
    }


def show_categories(chat_id):
    rows = [
        [{"text": label, "callback_data": f"cat:{key}"}]
        for key, label in CATEGORIES.items()
    ]
    rows.append([{"text": "🔙 منوی اصلی", "callback_data": "home"}])
    send(chat_id, "یک دسته‌بندی را انتخاب کن:", buttons(rows))


def show_products(chat_id, category):
    with db() as con:
        products = con.execute(
            "SELECT * FROM products WHERE category=? AND stock>0",
            (category,),
        ).fetchall()

    if not products:
        send(chat_id, "فعلاً محصول موجودی در این دسته نداریم.")
        return

    for p in products:
        text = (
            f"📦 {p['name']}\n"
            f"💰 قیمت: {p['price']:,} تومان\n"
            f"📊 موجودی: {p['stock']}"
        )
        keyboard = buttons([
            [{"text": "🛒 سفارش این محصول",
              "callback_data": f"buy:{p['id']}"}],
            [{"text": "🔙 دسته‌بندی‌ها",
              "callback_data": "categories"}],
        ])
        send(chat_id, text, keyboard)


def set_state(user_id, state, product_id=None):
    with db() as con:
        con.execute("""
            INSERT INTO customers(user_id, state, product_id)
            VALUES (?, ?, ?)
            ON CONFLICT(user_id) DO UPDATE SET
                state=excluded.state,
                product_id=excluded.product_id
        """, (user_id, state, product_id))


def get_customer(user_id):
    with db() as con:
        return con.execute(
            "SELECT * FROM customers WHERE user_id=?",
            (user_id,),
        ).fetchone()


def clear_state(user_id):
    with db() as con:
        con.execute(
            "DELETE FROM customers WHERE user_id=?", (user_id,)
        )


def handle_callback(query):
    data = query.get("data", "")
    chat_id = query["message"]["chat"]["id"]
    user_id = query["from"]["id"]

    requests.post(
        f"{API}/answerCallbackQuery",
        json={"callback_query_id": query["id"]},
        timeout=10,
    )

    if data == "home":
        send(chat_id, "به فروشگاه لوازم خانگی خوش آمدی!", main_menu())

    elif data == "categories":
        show_categories(chat_id)

    elif data.startswith("cat:"):
        category = data.split(":", 1)[1]
        if category in CATEGORIES:
            show_products(chat_id, category)

    elif data.startswith("buy:"):
        try:
            product_id = int(data.split(":", 1)[1])
        except ValueError:
            return

        with db() as con:
            p = con.execute(
                "SELECT * FROM products WHERE id=? AND stock>0",
                (product_id,),
            ).fetchone()

        if not p:
            send(chat_id, "این محصول موجود نیست.")
            return

        set_state(user_id, "name", product_id)
        send(chat_id, f"سفارش: {p['name']}\n\nنام و نام خانوادگی‌ات را بنویس.")

    elif data == "myorders":
        with db() as con:
            orders = con.execute(
                "SELECT * FROM orders WHERE user_id=? ORDER BY id DESC LIMIT 10",
                (user_id,),
            ).fetchall()

        if not orders:
            send(chat_id, "هنوز سفارشی ثبت نکرده‌ای.")
        else:
            for o in orders:
                send(
                    chat_id,
                    f"سفارش #{o['id']}\n{o['product']}\n"
                    f"مبلغ: {o['price']:,} تومان\n"
                    f"وضعیت: {o['status']}",
                )

    elif data == "support":
        send(chat_id, "برای پیگیری سفارش، با پشتیبانی فروشگاه تماس بگیر.")


def handle_message(message):
    chat_id = message["chat"]["id"]
    user = message.get("from", {})
    user_id = user.get("id")
    text = message.get("text", "").strip()

    if not user_id:
        return

    if text == "/start":
        send(chat_id, "سلام! 🛍️\nبه فروشگاه لوازم خانگی خوش آمدی.",
             main_menu())
        return

    if text == "/admin":
        if user_id != ADMIN_ID:
            send(chat_id, "⛔ دسترسی ندارید.")
            return
        send(
            chat_id,
            "مدیریت محصولات:\n"
            "/add نام محصول|قیمت تومان|دسته|موجودی\n\n"
            "دسته‌ها: kitchen، cleaning، home\n"
            "مثال:\n/add اتو بخار|1800000|home|4\n\n"
            "/products برای فهرست محصولات",
        )
        return

    if text.startswith("/add "):
        if user_id != ADMIN_ID:
            send(chat_id, "⛔ دسترسی ندارید.")
            return

        try:
            name, price, category, stock = text[5:].split("|")
            price, stock = int(price.strip()), int(stock.strip())
            name, category = name.strip(), category.strip()

            if not name or price < 0 or stock < 0:
                raise ValueError
            if category not in CATEGORIES:
                send(chat_id, "دسته باید kitchen یا cleaning یا home باشد.")
                return

            with db() as con:
                con.execute(
                    """INSERT INTO products(name,price,category,stock)
                       VALUES(?,?,?,?)""",
                    (name, price, category, stock),
                )
            send(chat_id, "✅ محصول اضافه شد.")
        except (ValueError, TypeError):
            send(chat_id, "فرمت اشتباه است. از /admin راهنما را ببین.")
        return

    if text == "/products" and user_id == ADMIN_ID:
        with db() as con:
            products = con.execute(
                "SELECT * FROM products ORDER BY id DESC"
            ).fetchall()
        if not products:
            send(chat_id, "محصولی ثبت نشده.")
        else:
            for p in products:
                send(chat_id,
                     f"#{p['id']} {p['name']} — {p['price']:,} تومان"
                     f" — موجودی: {p['stock']}")
        return

    customer = get_customer(user_id)
    if not customer:
        if message.get("contact"):
            send(chat_id, "برای شروع /start را بزن.")
        else:
            send(chat_id, "از منوی زیر استفاده کن:", main_menu())
        return

    state = customer["state"]
    product_id = customer["product_id"]

    if state == "name":
        if not text or text.startswith("/"):
            send(chat_id, "لطفاً نام و نام خانوادگی را به صورت متنی بنویس.")
            return
        set_state(user_id, "phone", product_id)
        send(chat_id, "حالا شماره تماس خودت را ارسال کن:",
             contact_keyboard())

    elif state == "phone":
        contact = message.get("contact")
        if contact and contact.get("user_id") not in (None, user_id):
            send(chat_id, "لطفاً شماره تماس خودت را ارسال کن.")
            return

        phone = contact.get("phone_number") if contact else text
        if not phone or len(phone) < 6:
            send(chat_id, "شماره تماس معتبر وارد کن.")
            return

        set_state(user_id, "address", product_id)
        with db() as con:
            con.execute("""
                CREATE TABLE IF NOT EXISTS temp_orders (
                    user_id INTEGER PRIMARY KEY,
                    name TEXT, phone TEXT
                )
            """)
            con.execute("""
                INSERT INTO temp_orders(user_id,name,phone)
                VALUES(?,?,?)
                ON CONFLICT(user_id) DO UPDATE SET
                    name=excluded.name, phone=excluded.phone
            """, (user_id, "", phone))
        send(chat_id, "آدرس کامل تحویل سفارش را بنویس.")

    elif state == "address":
        if not text or text.startswith("/"):
            send(chat_id, "لطفاً آدرس را به صورت متنی بنویس.")
            return

        with db() as con:
            temp = con.execute(
                "SELECT * FROM temp_orders WHERE user_id=?", (user_id,)
            ).fetchone()
            p = con.execute(
                "SELECT * FROM products WHERE id=? AND stock>0",
                (product_id,),
            ).fetchone()

            if not temp or not p:
                clear_state(user_id)
                send(chat_id, "سفارش قابل ثبت نیست؛ محصول را دوباره انتخاب کن.",
                     main_menu())
                return

            con.execute("""
                INSERT INTO orders(user_id,name,phone,address,product,price)
                VALUES(?,?,?,?,?,?)
            """, (user_id, temp["name"], temp["phone"], text,
                  p["name"], p["price"]))
            order_id = con.execute(
                "SELECT last_insert_rowid()"
            ).fetchone()[0]

            con.execute(
                "UPDATE products SET stock=stock-1 WHERE id=? AND stock>0",
                (product_id,),
            )
            con.execute("DELETE FROM temp_orders WHERE user_id=?", (user_id,))

        clear_state(user_id)
        send(chat_id,
             f"✅ سفارش #{order_id} ثبت شد!\n"
             f"محصول: {p['name']}\n"
             f"مبلغ: {p['price']:,} تومان\n"
             "ادمین برای هماهنگی با تو تماس می‌گیرد.",
             main_menu())

        send(
            ADMIN_ID,
            f"🛒 سفارش جدید #{order_id}\n"
            f"محصول: {p['name']}\n"
            f"مبلغ: {p['price']:,} تومان\n"
            f"نام: {temp['name']}\n"
            f"تلفن: {temp['phone']}\n"
            f"آدرس: {text}\n"
            f"شناسه تلگرام مشتری: {user_id}",
        )


@app.route("/", methods=["GET"])
def index():
    return "Home Appliance Shop Bot is running."


@app.route("/webhook", methods=["POST"])
def webhook():
    if not WEBHOOK_SECRET:
        abort(503)

    if request.headers.get("X-Telegram-Bot-Api-Secret-Token") != WEBHOOK_SECRET:
        abort(403)

    update = request.get_json(silent=True) or {}

    try:
        if "callback_query" in update:
            handle_callback(update["callback_query"])
        elif "message" in update:
            handle_message(update["message"])
    except Exception:
        app.logger.exception("Failed to process Telegram update")

    return "OK"


init_db()
