# ============================================================
#  database.py - مدیریت دیتابیس SQLite
# ============================================================

import sqlite3
import json
from datetime import datetime
from typing import Optional, List, Dict, Any

class Database:
    def __init__(self, db_file: str = 'hamster.db'):
        self.db_file = db_file
        self._init_db()
    
    def _init_db(self):
        """ایجاد جدول‌های دیتابیس"""
        with sqlite3.connect(self.db_file) as conn:
            cursor = conn.cursor()
            
            # جدول کاربران
            cursor.execute('''
                CREATE TABLE IF NOT EXISTS users (
                    id INTEGER PRIMARY KEY,
                    first_name TEXT,
                    username TEXT,
                    coins INTEGER DEFAULT 0,
                    profit INTEGER DEFAULT 0,
                    referrals INTEGER DEFAULT 0,
                    referred_by INTEGER,
                    referral_code TEXT UNIQUE,
                    join_date TEXT,
                    last_active TEXT
                )
            ''')
            
            # جدول دعوت‌ها (برای تاریخچه)
            cursor.execute('''
                CREATE TABLE IF NOT EXISTS referrals (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    referrer_id INTEGER,
                    referred_id INTEGER,
                    reward INTEGER,
                    date TEXT,
                    FOREIGN KEY (referrer_id) REFERENCES users (id),
                    FOREIGN KEY (referred_id) REFERENCES users (id)
                )
            ''')
            
            conn.commit()
    
    # ============================================================
    #  عملیات کاربران
    # ============================================================
    
    def get_user(self, user_id: int) -> Optional[Dict[str, Any]]:
        """دریافت اطلاعات کاربر"""
        with sqlite3.connect(self.db_file) as conn:
            conn.row_factory = sqlite3.Row
            cursor = conn.cursor()
            cursor.execute('SELECT * FROM users WHERE id = ?', (user_id,))
            row = cursor.fetchone()
            return dict(row) if row else None
    
    def get_user_by_code(self, code: str) -> Optional[Dict[str, Any]]:
        """دریافت کاربر با کد دعوت"""
        with sqlite3.connect(self.db_file) as conn:
            conn.row_factory = sqlite3.Row
            cursor = conn.cursor()
            cursor.execute('SELECT * FROM users WHERE referral_code = ?', (code,))
            row = cursor.fetchone()
            return dict(row) if row else None
    
    def create_user(self, user_id: int, first_name: str, username: str = '', 
                    referred_by: int = None) -> Dict[str, Any]:
        """ایجاد کاربر جدید"""
        import random
        import string
        
        # تولید کد دعوت یکتا
        referral_code = self._generate_unique_code()
        
        now = datetime.now().isoformat()
        
        with sqlite3.connect(self.db_file) as conn:
            cursor = conn.cursor()
            cursor.execute('''
                INSERT INTO users (
                    id, first_name, username, coins, profit, referrals,
                    referred_by, referral_code, join_date, last_active
                ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
            ''', (
                user_id, first_name, username, 0, 0, 0,
                referred_by, referral_code, now, now
            ))
            conn.commit()
            
            # اگر کاربر توسط کسی دعوت شده، پاداش بده
            if referred_by:
                self._process_referral(referred_by, user_id)
            
            return self.get_user(user_id)
    
    def update_user(self, user_id: int, **kwargs) -> bool:
        """بروزرسانی اطلاعات کاربر"""
        allowed_fields = ['coins', 'profit', 'referrals', 'last_active']
        updates = {k: v for k, v in kwargs.items() if k in allowed_fields}
        
        if not updates:
            return False
        
        updates['last_active'] = datetime.now().isoformat()
        
        set_clause = ', '.join([f'{k} = ?' for k in updates.keys()])
        values = list(updates.values()) + [user_id]
        
        with sqlite3.connect(self.db_file) as conn:
            cursor = conn.cursor()
            cursor.execute(f'UPDATE users SET {set_clause} WHERE id = ?', values)
            conn.commit()
            return cursor.rowcount > 0
    
    def get_top_users(self, limit: int = 10) -> List[Dict[str, Any]]:
        """دریافت برترین کاربران بر اساس سکه"""
        with sqlite3.connect(self.db_file) as conn:
            conn.row_factory = sqlite3.Row
            cursor = conn.cursor()
            cursor.execute('''
                SELECT id, first_name, username, coins, profit, referrals
                FROM users
                ORDER BY coins DESC
                LIMIT ?
            ''', (limit,))
            return [dict(row) for row in cursor.fetchall()]
    
    def get_user_referrals(self, user_id: int) -> List[Dict[str, Any]]:
        """دریافت لیست کاربرانی که توسط این کاربر دعوت شده‌اند"""
        with sqlite3.connect(self.db_file) as conn:
            conn.row_factory = sqlite3.Row
            cursor = conn.cursor()
            cursor.execute('''
                SELECT id, first_name, username, coins, join_date
                FROM users
                WHERE referred_by = ?
                ORDER BY join_date DESC
            ''', (user_id,))
            return [dict(row) for row in cursor.fetchall()]
    
    def get_referral_stats(self, user_id: int) -> Dict[str, Any]:
        """دریافت آمار دعوت‌های کاربر"""
        with sqlite3.connect(self.db_file) as conn:
            cursor = conn.cursor()
            
            # تعداد کل دعوت‌ها
            cursor.execute('SELECT COUNT(*) FROM users WHERE referred_by = ?', (user_id,))
            total = cursor.fetchone()[0]
            
            # تعداد دعوت‌های امروز
            today = datetime.now().date().isoformat()
            cursor.execute('''
                SELECT COUNT(*) FROM users 
                WHERE referred_by = ? AND date(join_date) = ?
            ''', (user_id, today))
            today_count = cursor.fetchone()[0]
            
            # کل پاداش دریافتی از دعوت‌ها
            cursor.execute('''
                SELECT SUM(reward) FROM referrals WHERE referrer_id = ?
            ''', (user_id,))
            total_reward = cursor.fetchone()[0] or 0
            
            return {
                'total': total,
                'today': today_count,
                'total_reward': total_reward
            }
    
    # ============================================================
    #  متدهای خصوصی
    # ============================================================
    
    def _generate_unique_code(self) -> str:
        """تولید کد دعوت یکتا"""
        import random
        import string
        
        while True:
            code = ''.join(random.choices(string.ascii_uppercase + string.digits, k=6))
            if not self.get_user_by_code(code):
                return code
    
    def _process_referral(self, referrer_id: int, referred_id: int):
        """پردازش دعوت و اعطای پاداش"""
        from config import Config
        
        with sqlite3.connect(self.db_file) as conn:
            cursor = conn.cursor()
            
            # افزایش تعداد دعوت‌های دعوت‌کننده
            cursor.execute('''
                UPDATE users 
                SET referrals = referrals + 1,
                    coins = coins + ?
                WHERE id = ?
            ''', (Config.REFERRAL_REWARD, referrer_id))
            
            # ثبت در تاریخچه دعوت‌ها
            cursor.execute('''
                INSERT INTO referrals (referrer_id, referred_id, reward, date)
                VALUES (?, ?, ?, ?)
            ''', (referrer_id, referred_id, Config.REFERRAL_REWARD, datetime.now().isoformat()))
            
            conn.commit()

# ============================================================
#  نمونه دیتابیس (برای استفاده در جاهای دیگر)
# ============================================================
db = Database()
