import sqlite3
import json
import logging
import os
from datetime import datetime, timedelta
from pathlib import Path
from typing import Dict, List, Optional, Tuple
import requests

logger = logging.getLogger(__name__)

# Пути к базам данных
ECONOMY_DB_PATH = os.getenv("ECONOMY_DB_PATH", "/db/economy.sqlite3")

class EconomyManager:
    def __init__(self):
        self.init_db()
    
    def init_db(self):
        """Инициализация базы данных экономики"""
        conn = sqlite3.connect(ECONOMY_DB_PATH)
        cursor = conn.cursor()
        
        # Таблица балансов пользователей
        cursor.execute('''
            CREATE TABLE IF NOT EXISTS user_balances (
                user_id INTEGER PRIMARY KEY,
                balance REAL DEFAULT 0.0,
                daily_income REAL DEFAULT 0.0,
                last_daily_reset DATE,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
            )
        ''')
        
        # Таблица вкладов
        cursor.execute('''
            CREATE TABLE IF NOT EXISTS deposits (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                user_id INTEGER,
                amount REAL,
                interest_rate REAL,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                matures_at TIMESTAMP,
                is_active BOOLEAN DEFAULT 1
            )
        ''')
        
        # Таблица кредитов
        cursor.execute('''
            CREATE TABLE IF NOT EXISTS loans (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                user_id INTEGER,
                amount REAL,
                interest_rate REAL,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                due_at TIMESTAMP,
                is_repaid BOOLEAN DEFAULT 0
            )
        ''')
        
        # Таблица транзакций
        cursor.execute('''
            CREATE TABLE IF NOT EXISTS transactions (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                from_user_id INTEGER,
                to_user_id INTEGER,
                amount REAL,
                transaction_type TEXT,
                description TEXT,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
            )
        ''')
        
        # Таблица налогов
        cursor.execute('''
            CREATE TABLE IF NOT EXISTS taxes (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                user_id INTEGER,
                amount REAL,
                tax_date DATE,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
            )
        ''')
        
        # Таблица глобальных настроек экономики
        cursor.execute('''
            CREATE TABLE IF NOT EXISTS economy_settings (
                key TEXT PRIMARY KEY,
                value TEXT,
                updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
            )
        ''')
        
        # Таблица ежедневной активности пользователей
        cursor.execute('''
            CREATE TABLE IF NOT EXISTS daily_activity (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                user_id INTEGER,
                activity_date DATE,
                message_count INTEGER DEFAULT 0,
                last_activity_time TIMESTAMP,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                UNIQUE(user_id, activity_date)
            )
        ''')
        
        # Таблица Центрального Банка
        cursor.execute('''
            CREATE TABLE IF NOT EXISTS central_bank (
                id INTEGER PRIMARY KEY DEFAULT 1,
                capital REAL DEFAULT 1000.0,
                total_taxes_collected REAL DEFAULT 0.0,
                total_inflation_adjustments REAL DEFAULT 0.0,
                total_emissions REAL DEFAULT 0.0,
                last_updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                UNIQUE(id)
            )
        ''')
        
        # Вставка настроек по умолчанию
        default_settings = {
            'central_bank_rate': '7.5',  # Ставка ЦБ РФ
            'deposit_min_amount': '10.0',
            'deposit_min_days': '7',
            'loan_max_amount': '100.0',
            'loan_interest_rate': '15.0',
            'tax_rate': '13.0',
            'transfer_limit_percent': '20.0',
            'inflation_rate': '5.0',
            'vanomasa_cooldown': '30',  # дней между ваномаса
            'message_reward_rate': '0.01',  # см за сообщение
            'last_activity_payout': ''  # дата последней выплаты за активность
        }
        
        for key, value in default_settings.items():
            cursor.execute('INSERT OR IGNORE INTO economy_settings (key, value) VALUES (?, ?)', (key, value))
        
        # Инициализация Центрального Банка
        cursor.execute('INSERT OR IGNORE INTO central_bank (id, capital) VALUES (1, 1000.0)')
        
        conn.commit()
        conn.close()
    
    def get_user_balance(self, user_id: int) -> float:
        """Получить баланс пользователя"""
        conn = sqlite3.connect(ECONOMY_DB_PATH)
        cursor = conn.cursor()
        cursor.execute('SELECT balance FROM user_balances WHERE user_id = ?', (user_id,))
        result = cursor.fetchone()
        conn.close()
        return result[0] if result else 0.0
    
    def update_balance(self, user_id: int, amount: float, transaction_type: str, description: str = ""):
        """Обновить баланс пользователя"""
        conn = sqlite3.connect(ECONOMY_DB_PATH)
        cursor = conn.cursor()
        
        # Вставляем или обновляем баланс
        cursor.execute('''
            INSERT INTO user_balances (user_id, balance, daily_income, last_daily_reset)
            VALUES (?, ?, 0.0, date('now'))
            ON CONFLICT(user_id) DO UPDATE SET balance = balance + ?
        ''', (user_id, amount, amount))
        
        # Записываем транзакцию
        cursor.execute('''
            INSERT INTO transactions (from_user_id, to_user_id, amount, transaction_type, description)
            VALUES (?, ?, ?, ?, ?)
        ''', (user_id, user_id, amount, transaction_type, description))
        
        conn.commit()
        conn.close()
        
        logger.info(f"Balance updated for user {user_id}: +{amount} ({transaction_type})")
    
    def transfer_money(self, from_user_id: int, to_user_id: int, amount: float, description: str = "") -> bool:
        """Перевод денег между пользователями"""
        if amount <= 0:
            return False
        
        from_balance = self.get_user_balance(from_user_id)
        transfer_limit = from_balance * 0.2  # 20% от капитала
        
        if amount > transfer_limit:
            return False
        
        if from_balance < amount:
            return False
        
        conn = sqlite3.connect(ECONOMY_DB_PATH)
        cursor = conn.cursor()
        
        # Обновляем балансы
        cursor.execute('''
            UPDATE user_balances SET balance = balance - ? WHERE user_id = ?
        ''', (amount, from_user_id))
        
        cursor.execute('''
            INSERT INTO user_balances (user_id, balance, daily_income, last_daily_reset)
            VALUES (?, ?, 0.0, date('now'))
            ON CONFLICT(user_id) DO UPDATE SET balance = balance + ?
        ''', (to_user_id, amount, amount))
        
        # Записываем транзакцию
        cursor.execute('''
            INSERT INTO transactions (from_user_id, to_user_id, amount, transaction_type, description)
            VALUES (?, ?, ?, ?, ?)
        ''', (from_user_id, to_user_id, amount, 'transfer', description))
        
        conn.commit()
        conn.close()
        
        logger.info(f"Transfer: {amount} from user {from_user_id} to user {to_user_id}")
        return True
    
    def create_deposit(self, user_id: int, amount: float, days: int) -> bool:
        """Создать вклад"""
        if amount <= 0:
            return False
        
        balance = self.get_user_balance(user_id)
        min_deposit = float(self.get_setting('deposit_min_amount'))
        
        if amount < min_deposit:
            return False
        
        if balance < amount:
            return False
        
        central_bank_rate = float(self.get_setting('central_bank_rate'))
        matures_at = datetime.now() + timedelta(days=days)
        
        conn = sqlite3.connect(ECONOMY_DB_PATH)
        cursor = conn.cursor()
        
        # Списываем деньги со счета
        cursor.execute('UPDATE user_balances SET balance = balance - ? WHERE user_id = ?', (amount, user_id))
        
        # Создаем вклад
        cursor.execute('''
            INSERT INTO deposits (user_id, amount, interest_rate, matures_at)
            VALUES (?, ?, ?, ?)
        ''', (user_id, amount, central_bank_rate, matures_at))
        
        conn.commit()
        conn.close()
        
        logger.info(f"Deposit created: user {user_id}, amount {amount}, rate {central_bank_rate}%")
        return True
    
    def create_loan(self, user_id: int, amount: float, days: int) -> bool:
        """Создать кредит"""
        if amount <= 0:
            return False
        
        max_loan = float(self.get_setting('loan_max_amount'))
        loan_rate = float(self.get_setting('loan_interest_rate'))
        
        if amount > max_loan:
            return False
        
        due_at = datetime.now() + timedelta(days=days)
        
        conn = sqlite3.connect(ECONOMY_DB_PATH)
        cursor = conn.cursor()
        
        # Начисляем деньги на счет
        cursor.execute('''
            INSERT INTO user_balances (user_id, balance, daily_income, last_daily_reset)
            VALUES (?, ?, 0.0, date('now'))
            ON CONFLICT(user_id) DO UPDATE SET balance = balance + ?
        ''', (user_id, amount, amount))
        
        # Создаем кредит
        cursor.execute('''
            INSERT INTO loans (user_id, amount, interest_rate, due_at)
            VALUES (?, ?, ?, ?)
        ''', (user_id, amount, loan_rate, due_at))
        
        conn.commit()
        conn.close()
        
        logger.info(f"Loan created: user {user_id}, amount {amount}, rate {loan_rate}%")
        return True
    
    def repay_loan(self, user_id: int, loan_id: int) -> bool:
        """Погасить кредит"""
        conn = sqlite3.connect(ECONOMY_DB_PATH)
        cursor = conn.cursor()
        
        cursor.execute('SELECT amount, interest_rate, is_repaid FROM loans WHERE id = ? AND user_id = ?', (loan_id, user_id))
        loan = cursor.fetchone()
        
        if not loan or loan[2]:  # Кредит не найден или уже погашен
            conn.close()
            return False
        
        amount, rate, _ = loan
        total_repayment = amount * (1 + rate / 100)
        
        balance = self.get_user_balance(user_id)
        if balance < total_repayment:
            conn.close()
            return False
        
        # Списываем деньги
        cursor.execute('UPDATE user_balances SET balance = balance - ? WHERE user_id = ?', (total_repayment, user_id))
        
        # Отмечаем кредит как погашенный
        cursor.execute('UPDATE loans SET is_repaid = 1 WHERE id = ?', (loan_id,))
        
        conn.commit()
        conn.close()
        
        logger.info(f"Loan repaid: user {user_id}, loan {loan_id}, amount {total_repayment}")
        return True
    
    def collect_daily_taxes(self):
        """Сбор ежедневных налогов"""
        tax_rate = float(self.get_setting('tax_rate')) / 100
        conn = sqlite3.connect(ECONOMY_DB_PATH)
        cursor = conn.cursor()
        
        # Получаем всех пользователей с ежедневным доходом
        cursor.execute('''
            SELECT user_id, daily_income FROM user_balances 
            WHERE daily_income > 0 AND (last_daily_reset != date('now') OR last_daily_reset IS NULL)
        ''')
        
        users = cursor.fetchall()
        
        total_taxes_collected = 0.0
        
        for user_id, daily_income in users:
            tax_amount = daily_income * tax_rate
            if tax_amount > 0:
                # Списываем налог
                cursor.execute(
                    'UPDATE user_balances SET balance = balance - ?, daily_income = 0, last_daily_reset = date(\'now\') WHERE user_id = ?', 
                    (tax_amount, user_id)
                )
                
                # Записываем налог
                cursor.execute('INSERT INTO taxes (user_id, amount, tax_date) VALUES (?, ?, date("now"))', (user_id, tax_amount))
                
                total_taxes_collected += tax_amount
        
        # Переводим собранные налоги в Центральный Банк
        if total_taxes_collected > 0:
            cursor.execute('UPDATE central_bank SET capital = capital + ?, total_taxes_collected = total_taxes_collected + ? WHERE id = 1', 
                         (total_taxes_collected, total_taxes_collected))
        
        conn.commit()
        conn.close()
        
        logger.info(f"Daily taxes collected: {total_taxes_collected:.2f} cm from {len(users)} users")
    
    def count_message(self, user_id: int):
        """Учесть сообщение пользователя"""
        conn = sqlite3.connect(ECONOMY_DB_PATH)
        cursor = conn.cursor()
        
        today = datetime.now().strftime('%Y-%m-%d')
        
        # Вставляем или обновляем счетчик сообщений за сегодня
        cursor.execute('''
            INSERT INTO daily_activity (user_id, activity_date, message_count, last_activity_time)
            VALUES (?, ?, 1, CURRENT_TIMESTAMP)
            ON CONFLICT(user_id, activity_date) 
            DO UPDATE SET 
                message_count = message_count + 1,
                last_activity_time = CURRENT_TIMESTAMP
        ''', (user_id, today))
        
        conn.commit()
        conn.close()
    
    def pay_daily_activity_rewards(self) -> int:
        """Начислить вознаграждения за ежедневную активность"""
        reward_rate = float(self.get_setting('message_reward_rate'))
        last_payout = self.get_setting('last_activity_payout')
        today = datetime.now().strftime('%Y-%m-%d')
        
        # Проверяем, не выплачивали ли уже сегодня
        if last_payout == today:
            return 0
        
        conn = sqlite3.connect(ECONOMY_DB_PATH)
        cursor = conn.cursor()
        
        # Получаем всех пользователей с активностью за вчерашний день
        yesterday = (datetime.now() - timedelta(days=1)).strftime('%Y-%m-%d')
        cursor.execute('''
            SELECT user_id, message_count FROM daily_activity 
            WHERE activity_date = ? AND message_count > 0
        ''', (yesterday,))
        
        users = cursor.fetchall()
        total_paid = 0
        
        for user_id, message_count in users:
            reward = message_count * reward_rate
            if reward > 0:
                # Обновляем баланс
                cursor.execute('''
                    INSERT INTO user_balances (user_id, balance, daily_income, last_daily_reset)
                    VALUES (?, ?, 0.0, date('now'))
                    ON CONFLICT(user_id) DO UPDATE SET 
                        balance = balance + ?,
                        daily_income = daily_income + ?
                ''', (user_id, reward, reward, reward))
                
                # Записываем транзакцию
                cursor.execute('''
                    INSERT INTO transactions (from_user_id, to_user_id, amount, transaction_type, description)
                    VALUES (?, ?, ?, ?, ?)
                ''', (user_id, user_id, reward, 'activity_reward', f'Вознаграждение за {message_count} сообщений'))
                
                total_paid += reward
        
        # Обновляем дату последней выплаты
        cursor.execute('UPDATE economy_settings SET value = ? WHERE key = ?', (today, 'last_activity_payout'))
        
        conn.commit()
        conn.close()
        
        logger.info(f"Activity rewards paid: {total_paid:.2f} cm to {len(users)} users")
        return len(users)
    
    def get_central_bank_stats(self) -> Dict:
        """Получить статистику Центрального Банка"""
        conn = sqlite3.connect(ECONOMY_DB_PATH)
        cursor = conn.cursor()
        
        cursor.execute('SELECT capital, total_taxes_collected, total_inflation_adjustments, total_emissions FROM central_bank WHERE id = 1')
        result = cursor.fetchone()
        
        conn.close()
        
        if result:
            return {
                'capital': result[0],
                'total_taxes_collected': result[1],
                'total_inflation_adjustments': result[2],
                'total_emissions': result[3]
            }
        else:
            return {
                'capital': 1000.0,
                'total_taxes_collected': 0.0,
                'total_inflation_adjustments': 0.0,
                'total_emissions': 0.0
            }
    
    def update_central_bank(self, capital_change: float, transaction_type: str, description: str = ""):
        """Обновить капитал Центрального Банка"""
        conn = sqlite3.connect(ECONOMY_DB_PATH)
        cursor = conn.cursor()
        
        # Обновляем капитал
        cursor.execute('''
            UPDATE central_bank SET 
                capital = capital + ?,
                last_updated = CURRENT_TIMESTAMP
            WHERE id = 1
        ''', (capital_change,))
        
        # Обновляем соответствующую статистику
        if transaction_type == 'tax':
            cursor.execute('UPDATE central_bank SET total_taxes_collected = total_taxes_collected + ? WHERE id = 1', (abs(capital_change),))
        elif transaction_type == 'inflation':
            cursor.execute('UPDATE central_bank SET total_inflation_adjustments = total_inflation_adjustments + ? WHERE id = 1', (abs(capital_change),))
        elif transaction_type == 'emission':
            cursor.execute('UPDATE central_bank SET total_emissions = total_emissions + ? WHERE id = 1', (abs(capital_change),))
        
        conn.commit()
        conn.close()
        
        logger.info(f"Central bank updated: {capital_change} ({transaction_type})")
    
    def emit_money(self, amount: float, reason: str = "") -> bool:
        """Эмиссия денег - добавление денег в систему из ЦБ"""
        cb_stats = self.get_central_bank_stats()
        
        if cb_stats['capital'] < amount:
            return False
        
        # Уменьшаем капитал ЦБ
        self.update_central_bank(-amount, 'emission', reason)
        
        # Здесь можно добавить логику распределения денег
        # Например, пропорционально текущим балансам или равными долями
        
        logger.info(f"Money emitted: {amount} cm ({reason})")
        return True
    
    def vanomasa(self) -> bool:
        """Полное обнуление всех балансов"""
        conn = sqlite3.connect(ECONOMY_DB_PATH)
        cursor = conn.cursor()
        
        # Проверяем кулдаун
        cursor.execute('SELECT value FROM economy_settings WHERE key = "last_vanomasa"')
        last_vanomasa = cursor.fetchone()
        
        if last_vanomasa:
            last_date = datetime.strptime(last_vanomasa[0], '%Y-%m-%d')
            cooldown_days = int(self.get_setting('vanomasa_cooldown'))
            if datetime.now() - last_date < timedelta(days=cooldown_days):
                conn.close()
                return False
        
        # Обнуляем все балансы
        cursor.execute('UPDATE user_balances SET balance = 0, daily_income = 0')
        
        # Записываем дату ваномаса
        cursor.execute('INSERT OR REPLACE INTO economy_settings (key, value, updated_at) VALUES ("last_vanomasa", date("now"), CURRENT_TIMESTAMP)')
        
        conn.commit()
        conn.close()
        
        logger.warning("VANOMASA: All balances reset to zero!")
        return True
    
    def get_setting(self, key: str) -> str:
        """Получить настройку экономики"""
        conn = sqlite3.connect(ECONOMY_DB_PATH)
        cursor = conn.cursor()
        cursor.execute('SELECT value FROM economy_settings WHERE key = ?', (key,))
        result = cursor.fetchone()
        conn.close()
        return result[0] if result else '0'
    
    def update_setting(self, key: str, value: str):
        """Обновить настройку экономики"""
        conn = sqlite3.connect(ECONOMY_DB_PATH)
        cursor = conn.cursor()
        cursor.execute('INSERT OR REPLACE INTO economy_settings (key, value, updated_at) VALUES (?, ?, CURRENT_TIMESTAMP)', (key, value))
        conn.commit()
        conn.close()
    
    def get_user_stats(self, user_id: int) -> Dict:
        """Получить статистику пользователя"""
        conn = sqlite3.connect(ECONOMY_DB_PATH)
        cursor = conn.cursor()
        
        # Баланс
        cursor.execute('SELECT balance FROM user_balances WHERE user_id = ?', (user_id,))
        balance = cursor.fetchone()[0] if cursor.fetchone() else 0.0
        
        # Активные вклады
        cursor.execute('SELECT COUNT(*), SUM(amount) FROM deposits WHERE user_id = ? AND is_active = 1', (user_id,))
        deposits = cursor.fetchone()
        
        # Активные кредиты
        cursor.execute('SELECT COUNT(*), SUM(amount) FROM loans WHERE user_id = ? AND is_repaid = 0', (user_id,))
        loans = cursor.fetchone()
        
        conn.close()
        
        # Получаем статистику сообщений за сегодня
        today = datetime.now().strftime('%Y-%m-%d')
        cursor.execute('SELECT message_count FROM daily_activity WHERE user_id = ? AND activity_date = ?', (user_id, today))
        today_messages = cursor.fetchone()
        
        # Получаем статистику сообщений за вчера
        yesterday = (datetime.now() - timedelta(days=1)).strftime('%Y-%m-%d')
        cursor.execute('SELECT message_count FROM daily_activity WHERE user_id = ? AND activity_date = ?', (user_id, yesterday))
        yesterday_messages = cursor.fetchone()
        
        conn.close()
        
        return {
            'balance': balance,
            'active_deposits_count': deposits[0] or 0,
            'active_deposits_sum': deposits[1] or 0.0,
            'active_loans_count': loans[0] or 0,
            'active_loans_sum': loans[1] or 0.0,
            'today_messages': today_messages[0] if today_messages else 0,
            'yesterday_messages': yesterday_messages[0] if yesterday_messages else 0
        }
    
    def regulate_inflation(self):
        """Регулирование инфляции через Центральный Банк"""
        inflation_rate = float(self.get_setting('inflation_rate'))
        total_supply = 0.0
        user_count = 0
        
        conn = sqlite3.connect(ECONOMY_DB_PATH)
        cursor = conn.cursor()
        
        # Получаем общую массу денег и количество пользователей
        cursor.execute('SELECT SUM(balance), COUNT(*) FROM user_balances')
        result = cursor.fetchone()
        if result[0]:
            total_supply = result[0]
            user_count = result[1]
        
        # Получаем статистику ЦБ
        cursor.execute('SELECT capital FROM central_bank WHERE id = 1')
        cb_capital = cursor.fetchone()[0] if cursor.fetchone() else 1000.0
        
        conn.close()
        
        # Если инфляция высокая, ЦБ может скупать деньги с рынка
        if inflation_rate > 10.0 and total_supply > 1000 and cb_capital > 100:
            # ЦБ скупает деньги для борьбы с инфляцией
            buyback_amount = min(total_supply * 0.05, cb_capital * 0.1)  # 5% от массы или 10% от капитала ЦБ
            
            # Уменьшаем капитал ЦБ (скупка денег)
            self.update_central_bank(-buyback_amount, 'inflation', f'Anti-inflation measures: buying back {buyback_amount:.2f} cm')
            
            # Увеличиваем налоги для дополнительной борьбы с инфляцией
            new_tax_rate = min(20.0, 13.0 + (inflation_rate - 10.0) * 0.5)
            self.update_setting('tax_rate', str(new_tax_rate))
            
            logger.info(f"Inflation regulation: CB bought back {buyback_amount:.2f} cm, tax rate increased to {new_tax_rate}%")
        
        # Если дефляция (низкая инфляция) и много денег в ЦБ, можно делать эмиссию
        elif inflation_rate < 2.0 and total_supply < 500 and cb_capital > 200:
            emission_amount = cb_capital * 0.05  # 5% от капитала ЦБ
            
            # Эмиссия денег через ЦБ
            self.update_central_bank(-emission_amount, 'emission', f'Economic stimulus: emitting {emission_amount:.2f} cm')
            
            # Уменьшаем налоги для стимуляции экономики
            new_tax_rate = max(10.0, 13.0 - (2.0 - inflation_rate) * 1.5)
            self.update_setting('tax_rate', str(new_tax_rate))
            
            logger.info(f"Economic stimulus: CB emitted {emission_amount:.2f} cm, tax rate decreased to {new_tax_rate}%")

# Глобальный экземпляр
economy = EconomyManager()
