# ---------------------------------------------------------
# webapp_server.py – Flask server for Telegram WebApp
# ---------------------------------------------------------
import os
import base64
import io
import logging
import importlib.util
import sys
from flask import Flask, request, jsonify, send_from_directory
from flask_cors import CORS
from telebot.util import check_webapp_data   # برای اعتبارسنجی init‑data

# -----------------------------------------------------------------
# لاگر (از همان لاگر ربات استفاده می‌شود)
# -----------------------------------------------------------------
logger = logging.getLogger('AnonBot')

# -----------------------------------------------------------------
# توکن ربات
# -----------------------------------------------------------------
BOT_TOKEN = os.getenv('BOT_TOKEN')
if not BOT_TOKEN:
    raise RuntimeError('BOT_TOKEN not set')

# -----------------------------------------------------------------
# بارگذاری اسکریپت ربات (newfile.py یا NewFile(S).py)
# -----------------------------------------------------------------
bot_path = None
search_dirs = [
    pathlib.Path(__file__).resolve().parent,
    pathlib.Path(__file__).resolve().parent.parent,
    pathlib.Path(__file__).resolve().parent / 'Un',
]
for d in search_dirs:
    for name in ['newfile.py', 'NewFile(S).py']:
        cand = d / name
        if cand.is_file():
            bot_path = cand
            break
    if bot_path:
        break
if bot_path is None:
    raise FileNotFoundError('Bot script not found (newfile.py / NewFile(S).py)')

spec = importlib.util.spec_from_file_location('main_bot', str(bot_path))
main_bot = importlib.util.module_from_spec(spec)
sys.modules['main_bot'] = main_bot
spec.loader.exec_module(main_bot)

# ربات اصلی (شیء `bot` در اسکریپت ربات)
bot = getattr(main_bot, 'bot', None)
if bot is None:
    raise RuntimeError('Bot instance not found in the loaded script')

# -----------------------------------------------------------------
# Flask app
# -----------------------------------------------------------------
app = Flask(__name__, static_folder='.', static_url_path='')
CORS(app)

# -----------------------------------------------------------------
# اعتبارسنجی WebApp init‑data (بازمی‌گرداند user_id)
# -----------------------------------------------------------------
def _validate_webapp():
    init_data = request.headers.get('X-Telegram-Init-Data')
    if not init_data:
        logger.warning('Missing X‑Telegram‑Init‑Data header')
        return None
    try:
        data = check_webapp_data(init_data, BOT_TOKEN)
    except Exception as e:
        logger.warning('WebApp data validation failed: %s', e)
        return None
    return data.get('user', {}).get('id')

# -----------------------------------------------------------------
# سرو استاتیک HTML (وب‌اپ)
# -----------------------------------------------------------------
@app.route('/webapp_profile.html')
def serve_profile_page():
    # فایل html در همان پوشه (public_html/Un/webapp/)
    return send_from_directory(os.path.dirname(os.path.abspath(__file__)), 'webapp_profile.html')

# -----------------------------------------------------------------
# Helper: دریافت URL مستقیم عکس از file_id
# -----------------------------------------------------------------
def _telegram_file_url(file_id: str) -> str | None:
    """باز می‌گرداند: https://api.telegram.org/file/bot<token>/<file_path>"""
    try:
        file_info = bot.get_file(file_id)
        file_path = file_info.file_path
        return f"https://api.telegram.org/file/bot{BOT_TOKEN}/{file_path}"
    except Exception as e:
        logger.warning('Failed to get telegram file URL for %s: %s', file_id, e)
        return None

# -----------------------------------------------------------------
# GET پروفایل (دریافت داده‌ها + URL عکس)
# -----------------------------------------------------------------
@app.route('/api/webapp/profile', methods=['GET'])
def get_profile():
    user_id = _validate_webapp()
    if not user_id:
        return jsonify({'ok': False, 'error': 'Invalid init data'}), 403

    try:
        profile = main_bot.get_user(user_id)   # dict از DB
        # ساخت URL عکس (اگر وجود داشته باشد)
        photo_url = None
        if profile and profile.get('photo_file_id'):
            photo_url = _telegram_file_url(profile['photo_file_id'])
        meta = {
            'positions': getattr(main_bot, 'GET_POSITIONS', lambda: [])(),
            'genders':   getattr(main_bot, 'GET_GENDERS',   lambda: [])(),
            'educations': getattr(main_bot, 'GET_EDUCATIONS', lambda: [])(),
            'cities':     getattr(main_bot, 'GET_IRAN_CITIES', lambda: [])(),
        }
        coins = profile.get('coins', 0) if profile else 0
        # اضافه کردن کلید `photo_url` به payload
        if profile is not None:
            profile['photo_url'] = photo_url

        return jsonify({
            'ok': True,
            'is_owner': True,
            'profile': profile,
            'meta': meta,
            'viewer_coins': coins,
        })
    except Exception as e:
        logger.exception('Error fetching profile')
        return jsonify({'ok': False, 'error': str(e)}), 500

# -----------------------------------------------------------------
# POST ذخیره پروفایل (بدون نوشتن فایل روی دیسک)
# -----------------------------------------------------------------
@app.route('/api/webapp/profile/save', methods=['POST'])
def save_profile():
    user_id = _validate_webapp()
    if not user_id:
        return jsonify({'ok': False, 'error': 'Invalid init data'}), 403

    data = request.get_json() or {}
    try:
        # به‌روزرسانی فیلدهای متنی (استفاده از توابع موجود)
        if 'display_name' in data and hasattr(main_bot, 'update_display_name'):
            main_bot.update_display_name(user_id, data['display_name'])
        if 'bio' in data and hasattr(main_bot, 'update_user_bio'):
            main_bot.update_user_bio(user_id, data['bio'])
        if 'age' in data and hasattr(main_bot, 'update_user_age'):
            main_bot.update_user_age(user_id, data['age'])
        if 'gender' in data and hasattr(main_bot, 'update_user_gender'):
            main_bot.update_user_gender(user_id, data['gender'])
        if 'position' in data and hasattr(main_bot, 'update_user_position'):
            main_bot.update_user_position(user_id, data['position'])
        if 'education' in data and hasattr(main_bot, 'update_user_education'):
            main_bot.update_user_education(user_id, data['education'])
        if 'province' in data and hasattr(main_bot, 'update_user_province'):
            main_bot.update_user_province(user_id, data['province'])
        if 'city' in data and hasattr(main_bot, 'update_user_city'):
            main_bot.update_user_city(user_id, data['city'])

        # ----------------- آپلود عکس -----------------
        # data['photo_data_url'] مثل "data:image/jpeg;base64,/9j/4AAQ..."
        if data.get('photo_data_url'):
            header, b64 = data['photo_data_url'].split(',', 1)
            img_bytes = base64.b64decode(b64)
            # ارسال مستقیم به تلگرام (بدون نوشتن روی دیسک)
            bio = io.BytesIO(img_bytes)
            sent_msg = bot.send_photo(chat_id=user_id, photo=bio)
            # گرفتن file_id جدید
            new_file_id = sent_msg.photo[-1].file_id
            # به‌روزرسانی فیلد photo_file_id در دیتابیس
            with main_bot.get_db_connection() as conn:
                cur = conn.cursor()
                cur.execute(
                    "UPDATE users SET photo_file_id = ? WHERE user_id = ?",
                    (new_file_id, user_id)
                )
                conn.commit()

        # جوایز تکمیل پروفایل (۱۵ سکه)
        if hasattr(main_bot, 'check_and_reward_profile_completion'):
            main_bot.check_and_reward_profile_completion(user_id)

        # برگرداندن پروفایل به‌روز شده (دارای photo_url)
        profile = main_bot.get_user(user_id)
        if profile and profile.get('photo_file_id'):
            profile['photo_url'] = _telegram_file_url(profile['photo_file_id'])

        return jsonify({
            'ok': True,
            'profile': profile,
            'viewer_coins': profile.get('coins', 0) if profile else 0,
        })
    except Exception as e:
        logger.exception('Error saving profile')
        return jsonify({'ok': False, 'error': str(e)}), 500

# -----------------------------------------------------------------
# POST عملیات عمومی (vote, dm, gift, friend, block …)
# -----------------------------------------------------------------
@app.route('/api/webapp/action', methods=['POST'])
def handle_action():
    user_id = _validate_webapp()
    if not user_id:
        return jsonify({'ok': False, 'error': 'Invalid init data'}), 403

    payload = request.get_json() or {}
    action = payload.get('action')
    target_id = payload.get('target_id')
    try:
        if action == 'vote' and hasattr(main_bot, 'cast_vote'):
            main_bot.cast_vote(user_id, target_id, payload.get('vote_type'))
        elif action == 'direct_message' and hasattr(main_bot, 'process_send_direct_message'):
            main_bot.process_send_direct_message(user_id, target_id)
        elif action == 'chat_request' and hasattr(main_bot, 'process_chat_request_start'):
            main_bot.process_chat_request_start(user_id, target_id)
        elif action == 'gift' and hasattr(main_bot, 'process_gift_coins_start'):
            amount = int(payload.get('amount', 0))
            main_bot.process_gift_coins_start(user_id, target_id, amount)
        elif action == 'friend' and hasattr(main_bot, 'add_friend'):
            sub = payload.get('sub_action')
            if sub == 'add':
                main_bot.add_friend(user_id, target_id)
            elif sub == 'remove' and hasattr(main_bot, 'remove_friend'):
                main_bot.remove_friend(user_id, target_id)
            elif sub == 'set_alias' and hasattr(main_bot, 'set_friend_alias'):
                main_bot.set_friend_alias(user_id, target_id, payload.get('alias'))
        elif action == 'block' and hasattr(main_bot, 'block_user'):
            if payload.get('block'):
                main_bot.block_user(user_id, target_id)
            elif hasattr(main_bot, 'unblock_user'):
                main_bot.unblock_user(user_id, target_id)
        else:
            return jsonify({'ok': False, 'error': f'Unknown or unsupported action {action}'}), 400
        return jsonify({'ok': True})
    except Exception as e:
        logger.exception('Error handling action %s', action)
        return jsonify({'ok': False, 'error': str(e)}), 500

# -----------------------------------------------------------------
# نقطهٔ ورود یک‌باره (برای استفاده مستقیم یا با run_all)
# -----------------------------------------------------------------
def run():
    """Start the Flask server (به‌صورت خودکار توسط run_all یا مستقیم)"""
    port = int(os.getenv('WEBAPP_PORT', '5000'))
    app.run(host='0.0.0.0', port=port)

if __name__ == '__main__':
    run()