# -*- coding: utf-8 -*-

import logging
import sqlite3
import asyncio
import os
from datetime import datetime
from contextlib import contextmanager

# 📦 بررسی نصب بودن کتابخانه‌های مورد نیاز
try:
    import jdatetime
    from aiogram import Bot, Dispatcher, Router, F
    from aiogram.filters import Command, BaseFilter
    from aiogram.fsm.context import FSMContext
    from aiogram.fsm.state import State, StatesGroup
    from aiogram.fsm.storage.memory import MemoryStorage
    from aiogram.types import (
        ReplyKeyboardMarkup, KeyboardButton, 
        InlineKeyboardMarkup, InlineKeyboardButton, 
        FSInputFile, CallbackQuery, Message
    )
except ImportError as e:
    print("❌ خطای وابستگی: کتابخانه‌های مورد نیاز نصب نیستند.")
    print(f"Error: {e}")
    print("لطفا دستور زیر را اجرا کنید:")
    print("pip install aiogram jdatetime")
    exit()

# ⚙️ تنظیمات ربات
TELEGRAM_BOT_TOKEN = "8553004617:AAErLVbxAbriB5mxS17suu-Ynli3WVbZZBs"
ADMIN_USER_IDS = [468398141, 75096114]  # 👈 لیست ادمین‌ها

# نام فایل پایگاه داده
DB_FILE = "gold_shop.db"

# 📝 تنظیمات لاگ‌گیری
logging.basicConfig(
    format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", 
    level=logging.INFO,
    handlers=[
        logging.FileHandler('bot_aiogram.log', encoding='utf-8'),
        logging.StreamHandler()
    ]
)
logger = logging.getLogger(__name__)

# 🗄️ تعریف وضعیت‌ها (States)
class SellStates(StatesGroup):
    ask_item_type = State()
    ask_count = State()
    ask_weight = State()
    ask_profit = State()
    confirm = State()

class AddInventoryStates(StatesGroup):
    ask_item_type = State()
    ask_count = State()
    ask_weight = State()
    confirm = State()

class SetInventoryStates(StatesGroup):
    ask_item_type = State()
    ask_count = State()
    ask_weight = State()
    confirm = State()

class ReportRangeStates(StatesGroup):
    get_start_date = State()
    get_end_date = State()

# 🛡️ فیلتر ادمین
class IsAdmin(BaseFilter):
    async def __call__(self, message: Message) -> bool:
        if not message.from_user: return False
        return message.from_user.id in ADMIN_USER_IDS

# ==========================================
# 🔧 توابع کمکی (Utils)
# ==========================================

@contextmanager
def db_connection():
    """مدیریت خودکار اتصال به پایگاه داده"""
    conn = None
    try:
        conn = sqlite3.connect(DB_FILE, timeout=20)
        conn.row_factory = sqlite3.Row
        conn.execute("PRAGMA foreign_keys = ON")
        yield conn
    except sqlite3.Error as e:
        logger.error(f"خطا در اتصال به پایگاه داده: {e}")
        raise
    finally:
        if conn:
            conn.close()

def setup_database():
    """ایجاد جداول اولیه"""
    try:
        with db_connection() as conn:
            with conn:
                conn.execute("""
                CREATE TABLE IF NOT EXISTS inventory (
                    item_type TEXT PRIMARY KEY, count INTEGER DEFAULT 0, weight REAL DEFAULT 0.0
                );
                """)
                conn.execute("""
                CREATE TABLE IF NOT EXISTS sales_log (
                    id INTEGER PRIMARY KEY AUTOINCREMENT, date TEXT NOT NULL,
                    item_type TEXT NOT NULL, count_sold INTEGER DEFAULT 0,
                    weight_sold REAL DEFAULT 0.0, profit REAL DEFAULT 0.0
                );
                """)
                conn.execute("""
                CREATE TABLE IF NOT EXISTS inventory_add_log (
                    id INTEGER PRIMARY KEY AUTOINCREMENT, date TEXT NOT NULL, weight_added REAL DEFAULT 0.0
                );
                """)
                # رکوردهای اولیه
                initial_items = ['leather', 'stone', 'coin', 'misc']
                for item in initial_items:
                    conn.execute("INSERT OR IGNORE INTO inventory (item_type) VALUES (?)", (item,))
        logger.info("✅ پایگاه داده با موفقیت آماده شد.")
    except Exception as e:
        logger.error(f"❌ خطا در راه‌اندازی پایگاه داده: {e}")

def get_persian_item_name(item_type):
    names = {
        'leather': 'دستبند چرم 💎', 'stone': 'دستبند سنگی 📿',
        'coin': 'سکه پارسیان 🪙', 'misc': 'متفرقه/شکسته ⚖️'
    }
    return names.get(item_type, 'ناشناخته')

def format_number(num):
    try:
        if isinstance(num, (int, float)):
            return f"{num:,.0f}"
        return num
    except:
        return num

def parse_date(date_string: str) -> str | None:
    date_string = date_string.strip().replace('/', '-')
    try:
        jd = jdatetime.datetime.strptime(date_string, "%Y-%m-%d")
        return jd.togregorian().strftime("%Y-%m-%d")
    except ValueError:
        try:
            gd = datetime.strptime(date_string, "%Y-%m-%d")
            return gd.strftime("%Y-%m-%d")
        except ValueError:
            return None

def validate_number(text: str, is_float=False) -> tuple[bool, int|float, str]:
    try:
        if is_float:
            num = float(text.strip())
        else:
            num = int(text.strip())
        
        if num < 0:
            return False, 0, "عدد نمی‌تواند منفی باشد"
        return True, num, ""
    except ValueError:
        return False, 0, "لطفاً فقط عدد وارد کنید"

# ==========================================
# 🎹 کیبوردها (Keyboards)
# ==========================================

def get_main_keyboard():
    return ReplyKeyboardMarkup(
        keyboard=[
            [KeyboardButton(text="✍️ ثبت فروش"), KeyboardButton(text="➕ افزودن موجودی")],
            [KeyboardButton(text="📊 گزارشات"), KeyboardButton(text="↩️ لغو فروش")],
            [KeyboardButton(text="⚙️ تنظیم موجودی"), KeyboardButton(text="📋 موجودی"), KeyboardButton(text="ℹ️ راهنما")],
            [KeyboardButton(text="🗃 Backup"), KeyboardButton(text="🔄 رفرش")]
        ],
        resize_keyboard=True
    )

def get_item_keyboard(action_prefix: str):
    return InlineKeyboardMarkup(inline_keyboard=[
        [
            InlineKeyboardButton(text=get_persian_item_name('leather'), callback_data=f"{action_prefix}_leather"),
            InlineKeyboardButton(text=get_persian_item_name('stone'), callback_data=f"{action_prefix}_stone")
        ],
        [
            InlineKeyboardButton(text=get_persian_item_name('coin'), callback_data=f"{action_prefix}_coin"),
            InlineKeyboardButton(text=get_persian_item_name('misc'), callback_data=f"{action_prefix}_misc")
        ],
        [InlineKeyboardButton(text="❌ لغو عملیات", callback_data="cancel_action")]
    ])

def get_confirm_keyboard():
    return InlineKeyboardMarkup(inline_keyboard=[
        [
            InlineKeyboardButton(text="✅ تایید و ثبت", callback_data="confirm_yes"),
            InlineKeyboardButton(text="❌ لغو", callback_data="cancel_action")
        ]
    ])

def get_help_keyboard():
    return InlineKeyboardMarkup(inline_keyboard=[
        [InlineKeyboardButton(text="راهنمای ✍️ ثبت فروش", callback_data="help_sell")],
        [InlineKeyboardButton(text="راهنمای ➕ افزودن موجودی", callback_data="help_add")],
        [InlineKeyboardButton(text="راهنمای ⚙️ تنظیم موجودی", callback_data="help_set")],
        [InlineKeyboardButton(text="راهنمای 📊 گزارشات", callback_data="help_report")],
        [InlineKeyboardButton(text="راهنمای ↩️ لغو فروش", callback_data="help_undo")],
        [InlineKeyboardButton(text="راهنمای 🗃 Backup", callback_data="help_backup")],
        [InlineKeyboardButton(text="✅ بستن راهنما", callback_data="cancel_action")]
    ])

def get_back_to_help_keyboard():
    return InlineKeyboardMarkup(inline_keyboard=[
        [InlineKeyboardButton(text="🔙 بازگشت به منوی راهنما", callback_data="help_menu")]
    ])

# ==========================================
# 🤖 روترها و هندلرها
# ==========================================

# روتر مخصوص ادمین‌ها
admin_router = Router()
admin_router.message.filter(IsAdmin())
admin_router.callback_query.filter(IsAdmin())

# روتر مخصوص کاربران غیرمجاز
guest_router = Router()

# -----------------------------------
# بخش هندلرهای ادمین
# -----------------------------------

@admin_router.callback_query(F.data == "cancel_action")
async def cancel_handler(query: CallbackQuery, state: FSMContext):
    await state.clear()
    await query.message.edit_text("✅ عملیات لغو شد. ↩️")
    await query.message.answer("به منوی اصلی بازگشتید.", reply_markup=get_main_keyboard())

# --- Start & Main Menu ---
@admin_router.message(Command("start"))
async def cmd_start(message: Message, state: FSMContext):
    await state.clear()
    user_name = message.from_user.first_name
    
    total_weight = 0
    try:
        with db_connection() as conn:
            res = conn.execute("SELECT SUM(weight) as tw FROM inventory").fetchone()
            if res and res['tw']:
                total_weight = res['tw']
    except Exception as e:
        logger.error(f"خطا در چک کردن موجودی در start: {e}")
        await message.answer("❌ خطا در بررسی وضعیت انبار.")
        return

    if total_weight == 0:
        welcome_text = (f"سلام {user_name}! 👋\n"
                        "به ربات مدیریت طلا خوش آمدید.\n\n"
                        "🎉 به نظر می‌رسه این اولین باره که از ربات استفاده می‌کنید.\n"
                        "**برای شروع، لطفاً از دکمه «⚙️ تنظیم موجودی» استفاده کنید** "
                        "تا موجودی اولیه انبار خود را وارد کنید.")
    else:
        welcome_text = (f"سلام مجدد {user_name}! 👋\n"
                        "به ربات مدیریت طلا خوش آمدید.\n\n"
                        "از دکمه‌های زیر برای مدیریت فروشگاه استفاده کنید. 🤖")
    
    await message.answer(welcome_text, reply_markup=get_main_keyboard(), parse_mode="Markdown")

@admin_router.message(F.text == "🔄 رفرش")
async def cmd_refresh(message: Message, state: FSMContext):
    await state.clear()
    await message.answer("✅ رابط کاربری بروزرسانی شد!", reply_markup=get_main_keyboard())

@admin_router.message(F.text == "📋 موجودی")
async def cmd_inventory(message: Message):
    try:
        with db_connection() as conn:
            inventory_rows = conn.execute(
                "SELECT item_type, count, weight FROM inventory ORDER BY item_type"
            ).fetchall()
            
            if not inventory_rows:
                await message.answer("📦 موجودی انبار خالی است.")
                return
            
            text = "📋 **موجودی فعلی انبار**\n\n"
            total_weight = 0
            total_count = 0
            
            for item in inventory_rows:
                item_name = get_persian_item_name(item['item_type'])
                text += f"• {item_name}:\n"
                text += f"  └ تعداد: {item['count']} عدد\n"
                text += f"  └ وزن: {item['weight']:.2f} گرم\n\n"
                total_weight += item['weight']
                total_count += item['count']
            
            text += f"📊 **جمع کل:** {total_count} عدد | {total_weight:.2f} گرم"
            await message.answer(text, parse_mode="Markdown")
            
    except Exception as e:
        logger.error(f"خطا در مشاهده موجودی: {e}")
        await message.answer("❌ خطا در بارگذاری موجودی انبار.")

@admin_router.message(F.text == "🗃 Backup")
async def cmd_backup(message: Message):
    try:
        if not os.path.exists(DB_FILE):
             await message.answer(f"❌ خطا: فایل پایگاه داده `{DB_FILE}` یافت نشد.", parse_mode="Markdown")
             return

        file = FSInputFile(DB_FILE, filename=f"backup_gold_shop_{datetime.now().strftime('%Y%m%d_%H%M')}.db")
        await message.answer_document(
            document=file, 
            caption="🗃 این فایل پشتیبان پایگاه داده شماست. آن را در جای امن نگه دارید."
        )
    except Exception as e:
        await message.answer(f"❌ خطا در ارسال پشتیبان: {e}")

# --- 1. ثبت فروش ---

@admin_router.message(F.text == "✍️ ثبت فروش")
async def sell_start(message: Message, state: FSMContext):
    await state.clear()
    await message.answer(
        "🛒 **ثبت فروش جدید**\n\nلطفاً نوع کالای فروخته شده را انتخاب کنید:", 
        reply_markup=get_item_keyboard("sell"), 
        parse_mode="Markdown"
    )
    await state.set_state(SellStates.ask_item_type)

@admin_router.callback_query(SellStates.ask_item_type, F.data.startswith("sell_"))
async def sell_item_selected(query: CallbackQuery, state: FSMContext):
    item_type = query.data.split("_")[1]
    await state.update_data(item_type=item_type)
    item_name_fa = get_persian_item_name(item_type)
    
    await query.message.edit_text(
        f"📦 کالا: {item_name_fa}\n\n✅ تعداد فروخته شده را وارد کنید (مثلاً: `2`):",
        reply_markup=None, parse_mode="Markdown"
    )
    await state.set_state(SellStates.ask_count)

@admin_router.message(SellStates.ask_count)
async def sell_get_count(message: Message, state: FSMContext):
    valid, count, err = validate_number(message.text)
    if not valid or count <= 0:
        await message.answer(f"❌ خطا: {err if err else 'لطفاً عدد صحیح مثبت وارد کنید'}\nمثال: `2`", parse_mode="Markdown")
        return
    
    await state.update_data(count_sold=count)
    data = await state.get_data()
    item_name_fa = get_persian_item_name(data['item_type'])

    await message.answer(
        f"📦 کالا: {item_name_fa}\n🔢 تعداد: {count} عدد\n\n✅ وزن فروخته شده را وارد کنید (به گرم، مثلاً: `5.2`):",
        parse_mode="Markdown"
    )
    await state.set_state(SellStates.ask_weight)

@admin_router.message(SellStates.ask_weight)
async def sell_get_weight(message: Message, state: FSMContext):
    valid, weight, err = validate_number(message.text, is_float=True)
    if not valid or weight <= 0:
        await message.answer(f"❌ خطا: {err if err else 'لطفاً عدد مثبت وارد کنید'}\nمثال: `5.2`", parse_mode="Markdown")
        return
        
    await state.update_data(weight_sold=weight)
    data = await state.get_data()
    item_name_fa = get_persian_item_name(data['item_type'])
    
    await message.answer(
        f"📦 کالا: {item_name_fa}\n🔢 تعداد: {data['count_sold']} عدد\n⚖️ وزن: {weight:.2f} گرم\n\n"
        "✅ سود حاصل از این فروش را وارد کنید (به تومان، مثلاً: `150000`):",
        parse_mode="Markdown"
    )
    await state.set_state(SellStates.ask_profit)

@admin_router.message(SellStates.ask_profit)
async def sell_get_profit(message: Message, state: FSMContext):
    valid, profit, err = validate_number(message.text, is_float=True)
    if not valid:
        await message.answer(f"❌ خطا: {err if err else 'لطفاً عدد وارد کنید'}\nمثال: `150000`", parse_mode="Markdown")
        return

    data = await state.update_data(profit=profit)
    
    # بررسی موجودی
    with db_connection() as conn:
        current = conn.execute("SELECT count, weight FROM inventory WHERE item_type=?", (data['item_type'],)).fetchone()
    
    error_msg = ""
    if data['count_sold'] > current['count']:
        error_msg += f"\n- ❌ موجودی تعداد کافی نیست (موجود: {current['count']} عدد)"
    if data['weight_sold'] > current['weight']:
        error_msg += f"\n- ❌ موجودی وزن کافی نیست (موجود: {current['weight']:.2f} گرم)"

    if error_msg:
        await message.answer(
            f"❌ **خطای موجودی!** ❌\n{error_msg}\n\n🔙 عملیات لغو شد. لطفاً دوباره تلاش کنید.", 
            reply_markup=get_main_keyboard(), parse_mode="Markdown"
        )
        await state.clear()
        return

    item_name_fa = get_persian_item_name(data['item_type'])
    summary = (
        "**📋 خلاصه فروش - لطفا تأیید کنید:**\n\n"
        f"📦 کالا: {item_name_fa}\n"
        f"🔢 تعداد فروش: {data['count_sold']} عدد\n"
        f"⚖️ وزن فروش: {data['weight_sold']:.2f} گرم\n"
        f"💰 سود: {format_number(data['profit'])} تومان\n\n"
        "⚠️ پس از تأیید، این عملیات غیرقابل بازگشت است!"
    )
    await message.answer(summary, parse_mode="Markdown", reply_markup=get_confirm_keyboard())
    await state.set_state(SellStates.confirm)

@admin_router.callback_query(SellStates.confirm, F.data == "confirm_yes")
async def sell_finish(query: CallbackQuery, state: FSMContext):
    data = await state.get_data()
    try:
        with db_connection() as conn:
            with conn:
                conn.execute(
                    "UPDATE inventory SET count = count - ?, weight = weight - ? WHERE item_type = ?",
                    (data['count_sold'], data['weight_sold'], data['item_type'])
                )
                conn.execute(
                    "INSERT INTO sales_log (date, item_type, count_sold, weight_sold, profit) VALUES (?, ?, ?, ?, ?)",
                    (datetime.now().strftime("%Y-%m-%d"), data['item_type'], data['count_sold'], data['weight_sold'], data['profit'])
                )
        
        item_name_fa = get_persian_item_name(data['item_type'])
        await query.message.edit_text(
            f"✅ **فروش با موفقیت ثبت شد!**\n\n"
            f"📦 {item_name_fa}\n"
            f"🔢 {data['count_sold']} عدد\n"
            f"⚖️ {data['weight_sold']:.2f} گرم\n"
            f"💰 {format_number(data['profit'])} تومان",
            parse_mode="Markdown"
        )
    except Exception as e:
        logger.error(f"خطا در ثبت فروش: {e}")
        await query.message.edit_text(f"❌ **خطا در ثبت فروش!**\n\nخطای پایگاه داده: {e}")
    finally:
        await state.clear()

# --- 2. افزودن موجودی ---

@admin_router.message(F.text == "➕ افزودن موجودی")
async def add_start(message: Message, state: FSMContext):
    await state.clear()
    await message.answer(
        "➕ **افزودن موجودی جدید**\n\nلطفاً نوع کالای اضافه شده را انتخاب کنید:", 
        reply_markup=get_item_keyboard("add"), parse_mode="Markdown"
    )
    await state.set_state(AddInventoryStates.ask_item_type)

@admin_router.callback_query(AddInventoryStates.ask_item_type, F.data.startswith("add_"))
async def add_item_sel(query: CallbackQuery, state: FSMContext):
    await state.update_data(item_type=query.data.split("_")[1])
    item_name_fa = get_persian_item_name(query.data.split("_")[1])
    await query.message.edit_text(
        f"📦 کالا: {item_name_fa}\n\n✅ تعداد اضافه شده را وارد کنید (مثلاً: `10`):",
        parse_mode="Markdown"
    )
    await state.set_state(AddInventoryStates.ask_count)

@admin_router.message(AddInventoryStates.ask_count)
async def add_get_count(message: Message, state: FSMContext):
    valid, val, err = validate_number(message.text)
    if not valid or val <= 0: 
        await message.answer(f"❌ خطا: {err}\nمثال: `10`", parse_mode="Markdown")
        return
    await state.update_data(count=val)
    
    data = await state.get_data()
    item_name_fa = get_persian_item_name(data['item_type'])
    await message.answer(
        f"📦 کالا: {item_name_fa}\n🔢 تعداد: {val} عدد\n\n✅ وزن اضافه شده را وارد کنید (به گرم، مثلاً: `50.5`):",
        parse_mode="Markdown"
    )
    await state.set_state(AddInventoryStates.ask_weight)

@admin_router.message(AddInventoryStates.ask_weight)
async def add_get_weight(message: Message, state: FSMContext):
    valid, val, err = validate_number(message.text, True)
    if not valid or val <= 0: 
        await message.answer(f"❌ خطا: {err}\nمثال: `50.5`", parse_mode="Markdown")
        return
    
    data = await state.update_data(weight=val)
    item_name_fa = get_persian_item_name(data['item_type'])
    
    summary = (
        "**📋 خلاصه افزودن موجودی - لطفا تأیید کنید:**\n\n"
        f"📦 کالا: {item_name_fa}\n"
        f"🔢 تعداد اضافه شده: +{data['count']} عدد\n"
        f"⚖️ وزن اضافه شده: +{data['weight']:.2f} گرم\n\n"
        "✅ با تأیید، موجودی انبار بروزرسانی می‌شود."
    )
    await message.answer(summary, parse_mode="Markdown", reply_markup=get_confirm_keyboard())
    await state.set_state(AddInventoryStates.confirm)

@admin_router.callback_query(AddInventoryStates.confirm, F.data == "confirm_yes")
async def add_finish(query: CallbackQuery, state: FSMContext):
    data = await state.get_data()
    try:
        with db_connection() as conn:
            with conn:
                conn.execute(
                    "UPDATE inventory SET count = count + ?, weight = weight + ? WHERE item_type = ?",
                    (data['count'], data['weight'], data['item_type'])
                )
                conn.execute(
                    "INSERT INTO inventory_add_log (date, weight_added) VALUES (?, ?)",
                    (datetime.now().strftime("%Y-%m-%d"), data['weight'])
                )
        
        item_name_fa = get_persian_item_name(data['item_type'])
        await query.message.edit_text(
            f"✅ **موجودی با موفقیت اضافه شد!**\n\n"
            f"📦 {item_name_fa}\n"
            f"🔢 +{data['count']} عدد\n"
            f"⚖️ +{data['weight']:.2f} گرم",
            parse_mode="Markdown"
        )
    except Exception as e:
        await query.message.edit_text(f"❌ **خطا در افزودن موجودی!**\n\nخطای پایگاه داده: {e}")
    finally:
        await state.clear()

# --- 3. تنظیم موجودی (Set Inventory) ---

@admin_router.message(F.text == "⚙️ تنظیم موجودی")
async def set_start(message: Message, state: FSMContext):
    await state.clear()
    await message.answer(
        "⚙️ **تنظیم/اصلاح موجودی (انبارگردانی)**\n\n"
        "⚠️ **هشدار مهم:** این دستور موجودی قبلی را **بازنویسی** می‌کند!\n\n"
        "لطفاً نوع کالا را انتخاب کنید:", 
        reply_markup=get_item_keyboard("set"), parse_mode="Markdown"
    )
    await state.set_state(SetInventoryStates.ask_item_type)

@admin_router.callback_query(SetInventoryStates.ask_item_type, F.data.startswith("set_"))
async def set_item_sel(query: CallbackQuery, state: FSMContext):
    await state.update_data(item_type=query.data.split("_")[1])
    item_name_fa = get_persian_item_name(query.data.split("_")[1])
    await query.message.edit_text(
        f"📦 کالا: {item_name_fa}\n\n✅ تعداد *کل* موجودی این کالا را وارد کنید (مثلاً: `50`):",
        parse_mode="Markdown"
    )
    await state.set_state(SetInventoryStates.ask_count)

@admin_router.message(SetInventoryStates.ask_count)
async def set_get_count(message: Message, state: FSMContext):
    valid, val, err = validate_number(message.text)
    if not valid: 
        await message.answer(f"❌ خطا: {err}\nمثال: `50`", parse_mode="Markdown")
        return
    await state.update_data(count=val)
    
    data = await state.get_data()
    item_name_fa = get_persian_item_name(data['item_type'])
    await message.answer(
        f"📦 کالا: {item_name_fa}\n🔢 تعداد کل: {val} عدد\n\n✅ وزن *کل* موجودی این کالا را وارد کنید (به گرم، مثلاً: `120.7`):",
        parse_mode="Markdown"
    )
    await state.set_state(SetInventoryStates.ask_weight)

@admin_router.message(SetInventoryStates.ask_weight)
async def set_get_weight(message: Message, state: FSMContext):
    valid, val, err = validate_number(message.text, True)
    if not valid: 
        await message.answer(f"❌ خطا: {err}\nمثال: `120.7`", parse_mode="Markdown")
        return
    data = await state.update_data(weight=val)
    item_name_fa = get_persian_item_name(data['item_type'])
    
    summary = (
        "⚠️ **تأیید بازنویسی موجودی** ⚠️\n\n"
        f"📦 کالا: {item_name_fa}\n"
        f"🔢 موجودی جدید (تعداد): {data['count']} عدد\n"
        f"⚖️ موجودی جدید (وزن): {data['weight']:.2f} گرم\n\n"
        "❌ **این عمل غیرقابل بازگشت است!**\n"
        "موجودی قبلی کاملاً پاک خواهد شد."
    )
    await message.answer(summary, parse_mode="Markdown", reply_markup=get_confirm_keyboard())
    await state.set_state(SetInventoryStates.confirm)

@admin_router.callback_query(SetInventoryStates.confirm, F.data == "confirm_yes")
async def set_finish(query: CallbackQuery, state: FSMContext):
    data = await state.get_data()
    try:
        with db_connection() as conn:
            with conn:
                conn.execute(
                    "UPDATE inventory SET count = ?, weight = ? WHERE item_type = ?",
                    (data['count'], data['weight'], data['item_type'])
                )
        
        item_name_fa = get_persian_item_name(data['item_type'])
        await query.message.edit_text(
            f"✅ **موجودی با موفقیت بروزرسانی شد!**\n\n"
            f"📦 {item_name_fa}\n"
            f"🔢 {data['count']} عدد\n"
            f"⚖️ {data['weight']:.2f} گرم",
            parse_mode="Markdown"
        )
    except Exception as e:
        await query.message.edit_text(f"❌ **خطا در تنظیم موجودی!**\n\nخطای پایگاه داده: {e}")
    finally:
        await state.clear()

# --- 4. گزارشات (Reports) ---

@admin_router.message(F.text == "📊 گزارشات")
async def report_menu(message: Message):
    kb = InlineKeyboardMarkup(inline_keyboard=[
        [InlineKeyboardButton(text="📊 گزارش کامل (وضعیت فعلی)", callback_data="rep_full")],
        [InlineKeyboardButton(text="☀️ گزارش امروز", callback_data="rep_today")],
        [InlineKeyboardButton(text="🌙 گزارش این ماه", callback_data="rep_month")],
        [InlineKeyboardButton(text="📅 گزارش بازه زمانی", callback_data="rep_custom")]
    ])
    await message.answer(
        "📈 **سیستم گزارش‌گیری**\n\nلطفاً نوع گزارش مورد نظر را انتخاب کنید:", 
        reply_markup=kb, parse_mode="Markdown"
    )

async def generate_detailed_report(start_date=None, end_date=None, title="📊 گزارش کامل مدیریت"):
    try:
        with db_connection() as conn:
            report = f"**{title}**\n\n"
            
            # 1. موجودی انبار
            report += "--- 👑 موجودی انبار ---\n"
            inv = conn.execute("SELECT item_type, count, weight FROM inventory ORDER BY item_type").fetchall()
            total_w, total_c = 0.0, 0
            for item in inv:
                name = get_persian_item_name(item['item_type'])
                report += f"• {name}: {item['count']} عدد ({item['weight']:.2f} گرم)\n"
                total_w += item['weight']
                total_c += item['count']
            report += f"\n📊 **جمع کل:** {total_c} عدد | {total_w:.2f} گرم\n\n"
            
            # 2. آمار فروش و سود
            report += "--- 📈 آمار فروش ---\n"
            where_clause = ""
            params = []
            if start_date and end_date:
                where_clause = "WHERE date BETWEEN ? AND ?"
                params = [start_date, end_date]
            
            # تعداد کل فاکتورها و ...
            q_total = f"SELECT COUNT(*) as cnt, SUM(count_sold) as tc, SUM(weight_sold) as tw FROM sales_log {where_clause}"
            totals = conn.execute(q_total, params).fetchone()
            report += f"• تعداد فاکتورها: {totals['cnt']} عدد\n"
            report += f"• تعداد کالاهای فروخته شده: {totals['tc'] or 0} عدد\n"
            report += f"• وزن کل فروش: {totals['tw'] or 0:.2f} گرم\n\n"
            
            # بخش سود به تفکیک
            report += "--- 💰 سود فروش ---\n"
            def get_profit_sum(types, w_clause, p_params):
                if isinstance(types, str): types = [types]
                ph = ','.join('?' for _ in types)
                q = f"SELECT SUM(profit) as total FROM sales_log WHERE item_type IN ({ph})"
                p = list(types)
                if w_clause:
                    q += f" AND ({w_clause.replace('WHERE', '')})"
                    p.extend(p_params)
                return conn.execute(q, p).fetchone()['total'] or 0

            p_bracelets = get_profit_sum(['leather', 'stone'], where_clause, params)
            p_coins = get_profit_sum('coin', where_clause, params)
            p_misc = get_profit_sum('misc', where_clause, params)
            total_profit = p_bracelets + p_coins + p_misc

            report += f"• 💎 سود دستبندها: {format_number(p_bracelets)} تومان\n"
            report += f"• 🪙 سود سکه‌ها: {format_number(p_coins)} تومان\n"
            report += f"• ⚖️ سود متفرقه: {format_number(p_misc)} تومان\n"
            report += "----------------\n"
            report += f"💰 **جمع کل سود: {format_number(total_profit)} تومان**\n\n"
            
            # 3. طلای اضافه شده
            report += "--- 📈 طلای اضافه شده ---\n"
            g_query = f"SELECT SUM(weight_added) as total FROM inventory_add_log {where_clause}"
            growth = conn.execute(g_query, params).fetchone()['total'] or 0
            report += f"• 🏋️‍♂️ طلای اضافه شده: {growth:.2f} گرم\n"
            
            if start_date:
                report += f"\n📅 **بازه زمانی:** {start_date} تا {end_date}"
            
            return report
    except Exception as e:
        logger.error(f"Report Error: {e}")
        return f"❌ خطا در تولید گزارش: {e}"

@admin_router.callback_query(F.data.in_({"rep_full", "rep_today", "rep_month"}))
async def report_quick(query: CallbackQuery):
    mode = query.data
    today = datetime.now().strftime("%Y-%m-%d")
    month_start = datetime.now().strftime("%Y-%m-01")
    
    text = ""
    if mode == "rep_full":
        text = await generate_detailed_report()
    elif mode == "rep_today":
        text = await generate_detailed_report(today, today, "☀️ گزارش امروز")
    elif mode == "rep_month":
        text = await generate_detailed_report(month_start, today, "🌙 گزارش این ماه")
        
    await query.message.edit_text(text, parse_mode="Markdown")

@admin_router.callback_query(F.data == "rep_custom")
async def report_custom_start(query: CallbackQuery, state: FSMContext):
    await query.message.edit_text(
        "📅 **گزارش بازه زمانی**\n\nلطفاً تاریخ *شروع* را وارد کنید:\n• فرمت شمسی: `1403/08/22`\n• فرمت میلادی: `2024-11-12`",
        parse_mode="Markdown"
    )
    await state.set_state(ReportRangeStates.get_start_date)

@admin_router.message(ReportRangeStates.get_start_date)
async def report_get_start(message: Message, state: FSMContext):
    d = parse_date(message.text)
    if not d: 
        await message.answer("❌ خطا: فرمت تاریخ اشتباه است!\nمثال: `1403/08/22`", parse_mode="Markdown")
        return
    await state.update_data(start=d)
    await message.answer(f"✅ تاریخ شروع: `{d}`\n\nلطفاً تاریخ *پایان* را وارد کنید:", parse_mode="Markdown")
    await state.set_state(ReportRangeStates.get_end_date)

@admin_router.message(ReportRangeStates.get_end_date)
async def report_get_end(message: Message, state: FSMContext):
    d = parse_date(message.text)
    if not d: 
        await message.answer("❌ خطا: فرمت تاریخ اشتباه است!", parse_mode="Markdown")
        return
    
    data = await state.get_data()
    if data['start'] > d:
        await message.answer("❌ خطا: تاریخ شروع نمی‌تواند بعد از تاریخ پایان باشد!\n🔙 عملیات لغو شد.", reply_markup=get_main_keyboard())
        await state.clear()
        return
        
    report = await generate_detailed_report(data['start'], d, f"📊 گزارش از {data['start']} تا {d}")
    await message.answer(report, parse_mode="Markdown", reply_markup=get_main_keyboard())
    await state.clear()

# --- 5. لغو فروش (Undo Sales) ---

@admin_router.message(F.text == "↩️ لغو فروش")
async def undo_list(message: Message, page: int = 0):
    ITEMS_PER_PAGE = 5
    offset = page * ITEMS_PER_PAGE
    
    try:
        with db_connection() as conn:
            total_sales = conn.execute("SELECT COUNT(*) as total FROM sales_log").fetchone()['total']
            total_pages = (total_sales + ITEMS_PER_PAGE - 1) // ITEMS_PER_PAGE if total_sales > 0 else 1
            
            sales = conn.execute(
                f"SELECT id, date, item_type, count_sold, weight_sold, profit FROM sales_log ORDER BY id DESC LIMIT {ITEMS_PER_PAGE} OFFSET {offset}"
            ).fetchall()
            
            if not sales:
                await message.answer("✅ هیچ فروشی برای لغو کردن یافت نشد.")
                return

            text = f"↩️ **لغو فروش** (صفحه {page+1} از {total_pages})\n\n"
            text += "کدام فروش را می‌خواهید لغو کنید؟\n⚠️ با زدن ❌، فروش پاک شده و موجودی به انبار باز می‌گردد.\n\n"

            kb = []
            for s in sales:
                item_name = get_persian_item_name(s['item_type'])
                label = f"{s['date']} | {item_name} | {s['count_sold']}عدد"
                kb.append([InlineKeyboardButton(text=f"❌ {label}", callback_data=f"del_sale_{s['id']}")])
            
            nav = []
            if page > 0:
                nav.append(InlineKeyboardButton(text="⏪ صفحه قبلی", callback_data=f"undo_page_{page-1}"))
            if page < total_pages - 1:
                nav.append(InlineKeyboardButton(text="⏩ صفحه بعدی", callback_data=f"undo_page_{page+1}"))
            if nav: kb.append(nav)
            
            kb.append([InlineKeyboardButton(text="✅ بستن لیست", callback_data="cancel_action")])
            
            markup = InlineKeyboardMarkup(inline_keyboard=kb)
            if isinstance(message, CallbackQuery):
                await message.message.edit_text(text, reply_markup=markup, parse_mode="Markdown")
            else:
                await message.answer(text, reply_markup=markup, parse_mode="Markdown")
    except Exception as e:
        logger.error(f"Undo Error: {e}")
        await message.answer(f"❌ خطا: {e}")

@admin_router.callback_query(F.data.startswith("undo_page_"))
async def undo_paginate(query: CallbackQuery):
    page = int(query.data.split("_")[2])
    await undo_list(query, page)

@admin_router.callback_query(F.data.startswith("del_sale_"))
async def undo_delete(query: CallbackQuery):
    sale_id = int(query.data.split("_")[2])
    try:
        with db_connection() as conn:
            sale = conn.execute("SELECT item_type, count_sold, weight_sold FROM sales_log WHERE id=?", (sale_id,)).fetchone()
            if not sale:
                await query.answer("❌ این فروش قبلاً حذف شده است.", show_alert=True)
                return
            
            with conn:
                conn.execute(
                    "UPDATE inventory SET count = count + ?, weight = weight + ? WHERE item_type = ?",
                    (sale['count_sold'], sale['weight_sold'], sale['item_type'])
                )
                conn.execute("DELETE FROM sales_log WHERE id = ?", (sale_id,))
            
        await query.answer(f"✅ فروش {sale_id} لغو شد.", show_alert=False)
        await undo_list(query, 0) # برگشت به صفحه اول
    except Exception as e:
        await query.message.edit_text(f"❌ خطا در لغو فروش: {e}")

# --- 6. راهنما ---

@admin_router.message(F.text == "ℹ️ راهنما")
async def show_help_menu(message: Message):
    await message.answer(
        "ℹ️ **راهنمای ربات** ℹ️\n\nراهنمای کدام بخش را نیاز دارید؟",
        reply_markup=get_help_keyboard(), parse_mode="Markdown"
    )

@admin_router.callback_query(F.data == "help_menu")
async def help_menu_callback(query: CallbackQuery):
    await query.message.edit_text(
        "ℹ️ **راهنمای ربات** ℹ️\n\nراهنمای کدام بخش را نیاز دارید؟",
        reply_markup=get_help_keyboard(), parse_mode="Markdown"
    )

@admin_router.callback_query(F.data.startswith("help_"))
async def help_topic_handler(query: CallbackQuery):
    topic = query.data.split("_")[1]
    
    help_texts = {
        'sell': ("**راهنمای ✍️ ثبت فروش:**\n\n"
                 "📝 **مراحل کار:**\n"
                 "1️⃣ انتخاب نوع کالا\n"
                 "2️⃣ وارد کردن تعداد فروخته شده\n"
                 "3️⃣ وارد کردن وزن فروخته شده (گرم)\n"
                 "4️⃣ وارد کردن سود حاصل (تومان)\n"
                 "5️⃣ تأیید نهایی\n\n"
                 "⚠️ **نکته:** در صورت عدم موجودی کافی، عملیات لغو می‌شود."),
        'add': ("**راهنمای ➕ افزودن موجودی:**\n\n"
                "📝 **مراحل کار:**\n"
                "1️⃣ انتخاب نوع کالا\n"
                "2️⃣ وارد کردن تعداد اضافه شده\n"
                "3️⃣ وارد کردن وزن اضافه شده (گرم)\n"
                "4️⃣ تأیید نهایی\n\n"
                "💡 **کاربرد:** برای ثبت خریدهای جدید و اضافه کردن به انبار"),
        'set': ("**راهنمای ⚙️ تنظیم موجودی:**\n\n"
                "📝 **مراحل کار:**\n"
                "1️⃣ انتخاب نوع کالا\n"
                "2️⃣ وارد کردن تعداد کل جدید\n"
                "3️⃣ وارد کردن وزن کل جدید (گرم)\n"
                "4️⃣ تأیید نهایی\n\n"
                "⚠️ **هشدار:** این عملیات موجودی قبلی را **بازنویسی** می‌کند!\n"
                "💡 **کاربرد:** برای اصلاح موجودی در انبارگردانی"),
        'report': ("**راهنمای 📊 گزارشات:**\n\n"
                   "📈 **انواع گزارش:**\n"
                   "• **گزارش کامل:** وضعیت فعلی انبار و سود کل\n"
                   "• **گزارش امروز:** سود و فروش امروز\n"
                   "• **گزارش این ماه:** سود و فروش ماه جاری\n"
                   "• **گزارش بازه زمانی:** سود در تاریخ دلخواه\n\n"
                   "📅 **فرمت تاریخ:** `1403/08/22` یا `2024-11-12`"),
        'undo': ("**راهنمای ↩️ لغو فروش:**\n\n"
                 "📝 **کاربرد:** حذف فروش‌های ثبت شده به اشتباه\n"
                 "• نمایش ۵ فروش در هر صفحه\n"
                 "• بازگشت موجودی به انبار پس از لغو\n"
                 "• به‌روزرسانی خودکار لیست\n\n"
                 "⚠️ **توجه:** این عمل غیرقابل بازگشت است!"),
        'backup': ("**راهنمای 🗃 Backup:**\n\n"
                   "💾 **کاربرد:** دریافت فایل پشتیبان از پایگاه داده\n"
                   "• ذخیره در جای امن\n"
                   "• امکان بازیابی اطلاعات در صورت نیاز\n"
                   "• نام فایل شامل تاریخ و زمان پشتیبان‌گیری\n\n"
                   "🔒 **امنیت:** این فایل حاوی تمام اطلاعات شماست!")
    }
    
    text = help_texts.get(topic, "❌ خطا: راهنما یافت نشد.")
    await query.message.edit_text(text, reply_markup=get_back_to_help_keyboard(), parse_mode="Markdown")

# -----------------------------------
# هندلر کاربر غیرمجاز (آخرین اولویت)
# -----------------------------------
@guest_router.message()
async def unauthorized_user_handler(message: Message):
    user_id = message.from_user.id
    logger.warning(f"دسترسی غیرمجاز توسط کاربر {user_id}")
    await message.answer(
        f"⛔️ **دسترسی غیرمجاز!**\n\n"
        f"شما اجازه استفاده از این ربات را ندارید.\n"
        f"User ID: `{user_id}`\n\n"
        "لطفاً این آیدی را برای ادمین ارسال کنید تا به شما دسترسی دهد.",
        parse_mode="Markdown"
    )

# ==========================================
# 🚀 اجرا
# ==========================================

async def main():
    setup_database()
    
    bot = Bot(token=TELEGRAM_BOT_TOKEN)
    dp = Dispatcher(storage=MemoryStorage())
    
    # ترتیب مهم است: اول ادمین، بعد کاربر ناشناس
    dp.include_router(admin_router)
    dp.include_router(guest_router)
    
    await bot.delete_webhook(drop_pending_updates=True)
    logger.info("🚀 ربات (Aiogram نسخه کامل مشابه فایل اصلی) روشن شد!")
    
    try:
        await dp.start_polling(bot)
    except Exception as e:
        logger.error(f"Critical Error: {e}")

if __name__ == "__main__":
    try:
        asyncio.run(main())
    except KeyboardInterrupt:
        print("ربات خاموش شد 👋")