import sqlite3, time, random
from datetime import datetime
from telegram import (
    Update, InlineKeyboardButton, InlineKeyboardMarkup, ParseMode
)
from telegram.ext import (
    Updater, CommandHandler, CallbackQueryHandler,
    ConversationHandler, MessageHandler, Filters, CallbackContext
)

# ------------------- پیکربندی -------------------
BOT_TOKEN = "8782221356:AAGwesklgPf7AwktGBqwdEaICWw_6M-RXNI"
ADMIN_ID = 7945871034
SUPPORT_USERNAME = "love4kaulitz"

# استیت‌ها
(ADD_NAME, ADD_PRICE, ADD_STOCK, ADD_CATEGORY) = range(4)
(EDIT_SELECT, EDIT_NAME, EDIT_PRICE, EDIT_STOCK, EDIT_CATEGORY) = range(5,10)
(CAT_ACTION, CAT_ADD, CAT_DEL) = range(10,13)
(CARD_ACTION, CARD_ADD_BANK, CARD_ADD_NUMBER, CARD_ADD_HOLDER, CARD_DEL) = range(13,18)
(DISC_ACTION, DISC_ADD_CODE, DISC_ADD_TYPE, DISC_ADD_AMOUNT, DISC_ADD_MAX, DISC_ADD_EXPIRY, DISC_DEL) = range(18,25)
(SELECT_PRODUCT, DISCOUNT_CODE, RECEIPT_PHOTO, ACCOUNT_INFO) = range(100,104)

DB = "shop.db"

# ------------------- دیتابیس -------------------
def init_db():
    with sqlite3.connect(DB) as conn:
        conn.executescript("""
            CREATE TABLE IF NOT EXISTS categories (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, is_active INTEGER DEFAULT 1);
            CREATE TABLE IF NOT EXISTS products (id INTEGER PRIMARY KEY AUTOINCREMENT, category_id INTEGER, name TEXT, price INTEGER, stock INTEGER DEFAULT 0, is_active INTEGER DEFAULT 1);
            CREATE TABLE IF NOT EXISTS card_numbers (id INTEGER PRIMARY KEY AUTOINCREMENT, bank_name TEXT, card_number TEXT, holder_name TEXT, is_default INTEGER DEFAULT 0);
            CREATE TABLE IF NOT EXISTS discount_codes (id INTEGER PRIMARY KEY AUTOINCREMENT, code TEXT UNIQUE, type TEXT, amount INTEGER, max_uses INTEGER DEFAULT 0, used_count INTEGER DEFAULT 0, expires_at TEXT, is_active INTEGER DEFAULT 1);
            CREATE TABLE IF NOT EXISTS orders (id INTEGER PRIMARY KEY AUTOINCREMENT, order_code TEXT, user_id INTEGER, username TEXT, first_name TEXT, product_id INTEGER, product_name TEXT, product_price INTEGER, discount_code_id INTEGER, discount_amount INTEGER DEFAULT 0, final_price INTEGER, status TEXT DEFAULT 'pending_payment', card_message_id INTEGER, expiry_time REAL, note TEXT, created_at TEXT, paid_at TEXT);
            CREATE TABLE IF NOT EXISTS logs (id INTEGER PRIMARY KEY AUTOINCREMENT, order_id INTEGER, event TEXT, timestamp TEXT DEFAULT (datetime('now','localtime')));
        """)
        if conn.execute("SELECT COUNT(*) FROM card_numbers").fetchone()[0] == 0:
            conn.execute("INSERT INTO card_numbers (bank_name, card_number, holder_name, is_default) VALUES (?,?,?,?)",("ملی","6037991899652145","فروشگاه تست",1))
        conn.commit()

def get_default_card(conn):
    row = conn.execute("SELECT * FROM card_numbers WHERE is_default=1 LIMIT 1").fetchone()
    return row if row else conn.execute("SELECT * FROM card_numbers LIMIT 1").fetchone()

def get_active_order(conn, user_id):
    return conn.execute("SELECT * FROM orders WHERE user_id=? AND status IN ('pending_payment','awaiting_receipt','awaiting_approval') ORDER BY id DESC LIMIT 1",(user_id,)).fetchone()

def check_discount(conn, code):
    row = conn.execute("SELECT * FROM discount_codes WHERE code=? AND is_active=1",(code,)).fetchone()
    if not row: return None,"کد نامعتبر"
    if row[7] and datetime.strptime(row[7],"%Y-%m-%d %H:%M:%S") < datetime.now(): return None,"منقضی"
    if row[5]>0 and row[6]>=row[5]: return None,"سقف استفاده تمام شد"
    return row,None

# کیبوردها
def admin_main():
    return InlineKeyboardMarkup([
        [InlineKeyboardButton("➕ افزودن محصول", callback_data="add")],
        [InlineKeyboardButton("✏️ ویرایش محصول", callback_data="edit")],
        [InlineKeyboardButton("🗑️ حذف محصول", callback_data="delete")],
        [InlineKeyboardButton("📁 مدیریت دسته‌بندی", callback_data="cats")],
        [InlineKeyboardButton("💳 مدیریت کارت‌ها", callback_data="cards")],
        [InlineKeyboardButton("🏷️ مدیریت تخفیف‌ها", callback_data="discounts")],
        [InlineKeyboardButton("📊 گزارش فروش", callback_data="report")],
        [InlineKeyboardButton("🔙 خروج", callback_data="close")]
    ])

def user_main():
    return InlineKeyboardMarkup([
        [InlineKeyboardButton("🛍️ مشاهده محصولات", callback_data="shop")],
        [InlineKeyboardButton("📋 سوابق خرید", callback_data="history")],
        [InlineKeyboardButton("📞 پشتیبانی", url=f"https://t.me/{SUPPORT_USERNAME}")]
    ])

def product_menu(conn, cat_id=None):
    if cat_id:
        rows = conn.execute("SELECT id,name,price,stock FROM products WHERE is_active=1 AND category_id=?",(cat_id,)).fetchall()
    else:
        rows = conn.execute("SELECT id,name,price,stock FROM products WHERE is_active=1").fetchall()
    kb = []
    for r in rows:
        txt = f"{r[1]} - {r[2]:,} تومان" if r[3]>0 else f"🚫 {r[1]} (ناموجود)"
        cb = f"prod_{r[0]}" if r[3]>0 else "none"
        kb.append([InlineKeyboardButton(txt,callback_data=cb)])
    kb.append([InlineKeyboardButton("🔙 بازگشت", callback_data="back_shop")])
    return InlineKeyboardMarkup(kb)

# هندلرها
def start(update, context):
    update.message.reply_text(f"سلام {update.effective_user.first_name}!\nبه فروشگاه ما خوش آمدید.", reply_markup=user_main())

def admin(update, context):
    if update.effective_user.id != ADMIN_ID: return
    update.message.reply_text("پنل مدیریت", reply_markup=admin_main())

# افزودن محصول
def add_start(update, context):
    update.callback_query.edit_message_text("نام محصول:")
    return ADD_NAME
def add_name(update, context):
    context.user_data['n']=update.message.text
    update.message.reply_text("قیمت:")
    return ADD_PRICE
def add_price(update, context):
    try:
        context.user_data['p']=int(update.message.text.replace(',',''))
        update.message.reply_text("موجودی:")
        return ADD_STOCK
    except: update.message.reply_text("عدد وارد کنید:"); return ADD_PRICE
def add_stock(update, context):
    try:
        context.user_data['s']=int(update.message.text)
        cats = sqlite3.connect(DB).execute("SELECT id,name FROM categories WHERE is_active=1").fetchall()
        if not cats:
            save_product(update, context, None)
            return ConversationHandler.END
        kb = [[InlineKeyboardButton(c[1], callback_data=f"addcat_{c[0]}")] for c in cats]
        kb.append([InlineKeyboardButton("بدون دسته", callback_data="addcat_none")])
        update.message.reply_text("دسته:", reply_markup=InlineKeyboardMarkup(kb))
        return ADD_CATEGORY
    except: update.message.reply_text("عدد وارد کنید:"); return ADD_STOCK
def add_category(update, context):
    data = update.callback_query.data.split("_")[1]
    cat = None if data=="none" else int(data)
    save_product(update, context, cat)
    return ConversationHandler.END
def save_product(update, context, cat, query=None):
    n,p,s = context.user_data.pop('n'), context.user_data.pop('p'), context.user_data.pop('s')
    with sqlite3.connect(DB) as conn:
        conn.execute("INSERT INTO products (category_id,name,price,stock) VALUES (?,?,?,?)",(cat,n,p,s))
    update.effective_chat.send_message("محصول اضافه شد.", reply_markup=admin_main())

# حذف محصول
def delete_product(update, context):
    with sqlite3.connect(DB) as conn:
        prods = conn.execute("SELECT id,name FROM products WHERE is_active=1").fetchall()
        kb = [[InlineKeyboardButton(f"❌ {p[1]}", callback_data=f"del_{p[0]}")] for p in prods]
    kb.append([InlineKeyboardButton("🔙", callback_data="back_admin")])
    update.callback_query.edit_message_text("حذف:", reply_markup=InlineKeyboardMarkup(kb))
def delete_confirm(update, context):
    pid = int(update.callback_query.data.split("_")[1])
    with sqlite3.connect(DB) as conn:
        conn.execute("UPDATE products SET is_active=0 WHERE id=?",(pid,))
    update.callback_query.edit_message_text("حذف شد.")
    update.effective_chat.send_message("ادمین", reply_markup=admin_main())

# مدیریت دسته‌بندی
def cat_manage(update, context):
    update.callback_query.edit_message_text("انتخاب:", reply_markup=InlineKeyboardMarkup([
        [InlineKeyboardButton("افزودن", callback_data="cat_add"), InlineKeyboardButton("حذف", callback_data="cat_del")],
        [InlineKeyboardButton("🔙", callback_data="back_admin")]
    ]))
    return CAT_ACTION
def cat_add_prompt(update, context):
    update.callback_query.edit_message_text("نام دسته:"); return CAT_ADD
def cat_add_save(update, context):
    with sqlite3.connect(DB) as conn: conn.execute("INSERT INTO categories (name) VALUES (?)",(update.message.text,))
    update.message.reply_text("دسته اضافه شد."); update.effective_chat.send_message("ادمین", reply_markup=admin_main())
    return ConversationHandler.END
def cat_del_prompt(update, context):
    with sqlite3.connect(DB) as conn:
        cats = conn.execute("SELECT id,name FROM categories WHERE is_active=1").fetchall()
        kb = [[InlineKeyboardButton(f"❌ {c[1]}", callback_data=f"cdel_{c[0]}")] for c in cats]
    update.callback_query.edit_message_text("حذف دسته:", reply_markup=InlineKeyboardMarkup(kb))
    return CAT_DEL
def cat_del_save(update, context):
    cid = int(update.callback_query.data.split("_")[1])
    with sqlite3.connect(DB) as conn: conn.execute("UPDATE categories SET is_active=0 WHERE id=?",(cid,))
    update.callback_query.edit_message_text("حذف شد.")
    update.effective_chat.send_message("ادمین", reply_markup=admin_main())
    return ConversationHandler.END

# مدیریت کارت
def card_manage(update, context):
    with sqlite3.connect(DB) as conn:
        cards = conn.execute("SELECT id,bank_name,card_number FROM card_numbers").fetchall()
    txt = "کارت‌ها:\n" + "\n".join(f"{c[1]}: {c[2]}" for c in cards)
    kb = [[InlineKeyboardButton("افزودن", callback_data="cadd"), InlineKeyboardButton("حذف", callback_data="cdel")],
          [InlineKeyboardButton("پیش‌فرض", callback_data="cdef"), InlineKeyboardButton("🔙", callback_data="back_admin")]]
    update.callback_query.edit_message_text(txt, reply_markup=InlineKeyboardMarkup(kb))
    return CARD_ACTION
def card_add_bank(update, context):
    update.callback_query.edit_message_text("نام بانک:"); return CARD_ADD_BANK
def card_add_number(update, context):
    context.user_data['bank']=update.message.text; update.message.reply_text("شماره کارت:"); return CARD_ADD_NUMBER
def card_add_holder(update, context):
    context.user_data['num']=update.message.text; update.message.reply_text("نام دارنده:"); return CARD_ADD_HOLDER
def card_save(update, context):
    h,b,n = update.message.text, context.user_data.pop('bank'), context.user_data.pop('num')
    with sqlite3.connect(DB) as conn: conn.execute("INSERT INTO card_numbers (bank_name,card_number,holder_name) VALUES (?,?,?)",(b,n,h))
    update.message.reply_text("کارت اضافه شد."); update.effective_chat.send_message("ادمین", reply_markup=admin_main())
    return ConversationHandler.END
def card_del_prompt(update, context):
    with sqlite3.connect(DB) as conn:
        cards = conn.execute("SELECT id,bank_name,card_number FROM card_numbers").fetchall()
        kb = [[InlineKeyboardButton(f"❌ {c[1]} {c[2]}", callback_data=f"cdel_{c[0]}")] for c in cards]
    update.callback_query.edit_message_text("حذف:", reply_markup=InlineKeyboardMarkup(kb))
    return CARD_DEL
def card_del_exec(update, context):
    cid = int(update.callback_query.data.split("_")[1])
    with sqlite3.connect(DB) as conn: conn.execute("DELETE FROM card_numbers WHERE id=?",(cid,))
    update.callback_query.edit_message_text("حذف شد."); update.effective_chat.send_message("ادمین", reply_markup=admin_main())
    return ConversationHandler.END
def card_set_default(update, context):
    with sqlite3.connect(DB) as conn:
        cards = conn.execute("SELECT id,bank_name,card_number FROM card_numbers").fetchall()
        kb = [[InlineKeyboardButton(f"⭐ {c[1]} {c[2]}", callback_data=f"cset_{c[0]}")] for c in cards]
    update.callback_query.edit_message_text("پیش‌فرض:", reply_markup=InlineKeyboardMarkup(kb))
    return CARD_ACTION
def card_set_exec(update, context):
    cid = int(update.callback_query.data.split("_")[1])
    with sqlite3.connect(DB) as conn:
        conn.execute("UPDATE card_numbers SET is_default=0"); conn.execute("UPDATE card_numbers SET is_default=1 WHERE id=?",(cid,))
    update.callback_query.edit_message_text("تنظیم شد."); update.effective_chat.send_message("ادمین", reply_markup=admin_main())
    return ConversationHandler.END

# تخفیف
def disc_manage(update, context):
    update.callback_query.edit_message_text("تخفیف:", reply_markup=InlineKeyboardMarkup([
        [InlineKeyboardButton("افزودن", callback_data="dadd"), InlineKeyboardButton("حذف", callback_data="ddel")],
        [InlineKeyboardButton("🔙", callback_data="back_admin")]
    ]))
    return DISC_ACTION
def disc_add_code(update, context):
    update.callback_query.edit_message_text("کد:"); return DISC_ADD_CODE
def disc_add_type(update, context):
    context.user_data['dcode']=update.message.text
    update.message.reply_text("نوع:", reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("درصدی", callback_data="dtype_percent"), InlineKeyboardButton("مبلغی", callback_data="dtype_fixed")]]))
    return DISC_ADD_TYPE
def disc_add_amount(update, context):
    context.user_data['dtype']=update.callback_query.data.split("_")[1]
    update.callback_query.edit_message_text("مقدار:"); return DISC_ADD_AMOUNT
def disc_add_max(update, context):
    try:
        context.user_data['damount']=int(update.message.text); update.message.reply_text("حداکثر استفاده:")
        return DISC_ADD_MAX
    except: update.message.reply_text("عدد وارد کنید:"); return DISC_ADD_AMOUNT
def disc_add_expiry(update, context):
    try:
        context.user_data['dmax']=int(update.message.text); update.message.reply_text("تاریخ انقضا (YYYY-MM-DD HH:MM:SS) یا 0:")
        return DISC_ADD_EXPIRY
    except: update.message.reply_text("عدد وارد کنید:"); return DISC_ADD_MAX
def disc_save(update, context):
    exp = update.message.text if update.message.text!="0" else None
    with sqlite3.connect(DB) as conn:
        conn.execute("INSERT INTO discount_codes (code,type,amount,max_uses,expires_at) VALUES (?,?,?,?,?)",
                     (context.user_data.pop('dcode'), context.user_data.pop('dtype'), context.user_data.pop('damount'), context.user_data.pop('dmax'), exp))
    update.message.reply_text("کد تخفیف اضافه شد."); update.effective_chat.send_message("ادمین", reply_markup=admin_main())
    return ConversationHandler.END
def disc_del_prompt(update, context):
    with sqlite3.connect(DB) as conn:
        codes = conn.execute("SELECT id,code FROM discount_codes WHERE is_active=1").fetchall()
        kb = [[InlineKeyboardButton(f"❌ {c[1]}", callback_data=f"ddel_{c[0]}")] for c in codes]
    update.callback_query.edit_message_text("حذف:", reply_markup=InlineKeyboardMarkup(kb))
    return DISC_DEL
def disc_del_exec(update, context):
    did = int(update.callback_query.data.split("_")[1])
    with sqlite3.connect(DB) as conn: conn.execute("UPDATE discount_codes SET is_active=0 WHERE id=?",(did,))
    update.callback_query.edit_message_text("حذف شد."); update.effective_chat.send_message("ادمین", reply_markup=admin_main())
    return ConversationHandler.END

# گزارش
def report(update, context):
    with sqlite3.connect(DB) as conn:
        total = conn.execute("SELECT COUNT(*), SUM(final_price) FROM orders WHERE status='completed'").fetchone()
        top = conn.execute("SELECT product_name, COUNT(*) FROM orders WHERE status='completed' GROUP BY product_id ORDER BY COUNT(*) DESC LIMIT 5").fetchall()
    txt = f"📊 فروش: {total[0] or 0} عدد\nدرآمد: {(total[1] or 0):,} تومان\n\nپرفروش‌ها:\n" + "\n".join(f"{t[0]}: {t[1]}" for t in top)
    update.callback_query.edit_message_text(txt)

# خرید
def shop(update, context):
    user_id = update.effective_user.id
    with sqlite3.connect(DB) as conn:
        if get_active_order(conn, user_id):
            update.callback_query.answer("شما یک سفارش باز دارید.", show_alert=True); return
        cats = conn.execute("SELECT id,name FROM categories WHERE is_active=1").fetchall()
        if cats:
            kb = [[InlineKeyboardButton(c[1], callback_data=f"cat_{c[0]}")] for c in cats] + [[InlineKeyboardButton("همه", callback_data="cat_all"), InlineKeyboardButton("🔙", callback_data="back_main")]]
            update.callback_query.edit_message_text("دسته‌بندی:", reply_markup=InlineKeyboardMarkup(kb))
        else:
            update.callback_query.edit_message_text("محصولات:", reply_markup=product_menu(conn))
def show_cat(update, context):
    cid = update.callback_query.data.split("_")[1]
    with sqlite3.connect(DB) as conn:
        update.callback_query.edit_message_text("محصولات:", reply_markup=product_menu(conn, None if cid=="all" else int(cid)))
def product_selected(update, context):
    pid = int(update.callback_query.data.split("_")[1])
    user = update.effective_user
    with sqlite3.connect(DB) as conn:
        prod = conn.execute("SELECT * FROM products WHERE id=?",(pid,)).fetchone()
        if not prod or prod[4]<=0:
            update.callback_query.answer("ناموجود"); return
        now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        code = f"ORD-{now[2:7].replace('-','')}-{random.randint(1000,9999)}"
        conn.execute("INSERT INTO orders (order_code,user_id,username,first_name,product_id,product_name,product_price,final_price,status,created_at,expiry_time) VALUES (?,?,?,?,?,?,?,?,?,?,?)",
                     (code,user.id,user.username,user.first_name,pid,prod[2],prod[3],prod[3],'pending_payment',now,time.time()+600))
        conn.execute("UPDATE products SET stock=stock-1 WHERE id=?",(pid,))
        card = get_default_card(conn)
        card_txt = f"{card[1]} - {card[2]} - {card[3]}" if card else "تنظیم نشده"
    update.callback_query.delete_message()
    msg = context.bot.send_message(user.id,
        f"🧾 کد: {code}\n📦 {prod[2]}\n💰 {prod[3]:,} تومان\n\n💳 {card_txt}\n⏳ ۱۰ دقیقه فرصت دارید.",
        reply_markup=InlineKeyboardMarkup([
            [InlineKeyboardButton("پرداخت شد", callback_data=f"paid_{code}"), InlineKeyboardButton("کد تخفیف", callback_data=f"disc_{code}")],
            [InlineKeyboardButton("انصراف", callback_data=f"cancel_{code}")]
        ]))
    with sqlite3.connect(DB) as conn:
        conn.execute("UPDATE orders SET card_message_id=? WHERE order_code=?",(msg.message_id,code))
    context.job_queue.run_once(payment_timeout, 600, context={'code':code,'chat':user.id,'msg':msg.message_id})
    context.job_queue.run_once(lambda c: c.bot.send_message(c.job.context['chat'],"⏰ ۲ دقیقه تا لغو"), 480, context={'chat':user.id})
def payment_timeout(context):
    code = context.job.context['code']
    with sqlite3.connect(DB) as conn:
        row = conn.execute("SELECT product_id,status FROM orders WHERE order_code=?",(code,)).fetchone()
        if row and row[1]=='pending_payment':
            conn.execute("UPDATE orders SET status='failed' WHERE order_code=?",(code,))
            conn.execute("UPDATE products SET stock=stock+1 WHERE id=?",(row[0],))
            try: context.bot.delete_message(context.job.context['chat'], context.job.context['msg'])
            except: pass
            context.bot.send_message(context.job.context['chat'],"❌ تراکنش ناموفق")
def cancel_order(update, context):
    code = update.callback_query.data.split("_")[1]
    with sqlite3.connect(DB) as conn:
        row = conn.execute("SELECT product_id,card_message_id,status FROM orders WHERE order_code=?",(code,)).fetchone()
        if row and row[2]=='pending_payment':
            conn.execute("UPDATE orders SET status='cancelled' WHERE order_code=?",(code,))
            conn.execute("UPDATE products SET stock=stock+1 WHERE id=?",(row[0],))
            try: context.bot.delete_message(update.effective_chat.id, row[1])
            except: pass
    update.callback_query.edit_message_text("لغو شد.")
def apply_discount(update, context):
    context.user_data['dis