# handlers/vivod.py
from aiogram import Router, F
from aiogram.filters import StateFilter
from aiogram.fsm.context import FSMContext
from aiogram.fsm.state import State, StatesGroup
from aiogram.types import Message, InlineKeyboardMarkup, InlineKeyboardButton, CallbackQuery
import random
from datetime import datetime
import logging
import json
import os
from aiogram import types
from db import get_user_balance, update_user_balance, save_withdrawal
from keyboard import get_main_menu_keyboard

# Настройка логирования в файл log.txt
logging.basicConfig(filename='log.txt', level=logging.ERROR, format='%(asctime)s - %(levelname)s - %(message)s')

router = Router()

class VivdStates(StatesGroup):
    wait_amount = State()
    wait_method_choice = State()
    wait_crypto_username = State()
    wait_card_number = State()
    wait_card_name = State()

def get_chat_id(key: str):
    """Загрузка chat_id из chats.json"""
    try:
        with open(os.path.join(os.path.dirname(os.path.dirname(__file__)), 'chats.json'), 'r', encoding='utf-8') as f:
            data = json.load(f)
        return data.get(key)
    except Exception as e:
        logging.error(f"Ошибка загрузки chats.json: {str(e)}")
        return None

def get_function_status(key: str):
    """Загрузка статуса функции из function.json"""
    try:
        with open(os.path.join(os.path.dirname(os.path.dirname(__file__)), 'function.json'), 'r', encoding='utf-8') as f:
            data = json.load(f)
        return data.get(key, True)
    except Exception as e:
        logging.error(f"Ошибка загрузки function.json: {str(e)}")
        return True

def get_procent_rate():
    """Загрузка процента комиссии из procent.json"""
    try:
        with open(os.path.join(os.path.dirname(os.path.dirname(__file__)), 'procent.json'), 'r', encoding='utf-8') as f:
            data = json.load(f)
        return data.get('procent', 10) / 100
    except Exception as e:
        logging.error(f"Ошибка загрузки procent.json: {str(e)}")
        return 0.1

def get_min_withdrawal():
    """Загрузка минимальной суммы вывода из function.json"""
    try:
        with open(os.path.join(os.path.dirname(os.path.dirname(__file__)), 'function.json'), 'r', encoding='utf-8') as f:
            data = json.load(f)
        return data.get('min_withdrawal', 100)
    except Exception as e:
        logging.error(f"Ошибка загрузки function.json: {str(e)}")
        return 100

@router.message(F.text == "💸 Вывод")
async def vivod_start(message: Message, state: FSMContext):
    if not get_function_status('vivod'):
        await message.answer("Проводятся технические работы")
        return
    
    user_id = message.from_user.id
    balance = get_user_balance(user_id)
    procent_rate = get_procent_rate()
    min_withdrawal = get_min_withdrawal()
    
    # Расчет минимального требуемого баланса: min_withdrawal + процент
    min_balance_required = min_withdrawal + (min_withdrawal * procent_rate)
    
    if balance < min_balance_required:
        text = f"❌ На вашем балансе не достаточно средств. Пополните свой баланс.\n\nМинимальный баланс для вывода: {min_balance_required:.2f} рублей\nВаш текущий баланс: {balance:.2f} рублей"
        keyboard = InlineKeyboardMarkup(inline_keyboard=[
            [InlineKeyboardButton(text="💰 Пополнить баланс", callback_data="top_up_balance")],
            [InlineKeyboardButton(text="🔙 Назад", callback_data="back_to_menu")]
        ])
        await message.answer(text, reply_markup=keyboard)
        return
    
    await message.answer("Введите сумму которую хотите вывести:")
    await state.set_state(VivdStates.wait_amount)

@router.message(StateFilter(VivdStates.wait_amount))
async def process_amount(message: Message, state: FSMContext):
    try:
        amount = float(message.text)
        if amount <= 0:
            await message.answer("❌ Сумма должна быть положительной. Введите заново:")
            return
    except ValueError:
        await message.answer("❌ Неверный формат. Введите число:")
        return
    
    user_id = message.from_user.id
    balance = get_user_balance(user_id)
    procent_rate = get_procent_rate()
    min_withdrawal = get_min_withdrawal()
    
    # Расчет комиссии
    commission = amount * procent_rate
    total_deduct = amount + commission
    
    # Проверка минимальной суммы
    if amount < min_withdrawal:
        await message.answer(f"❌ Минимальная сумма вывода: {min_withdrawal:.2f} рублей. Введите заново:")
        return
    
    # Проверка баланса
    if total_deduct > balance:
        await message.answer(f"❌ Недостаточно средств. Нужно: {total_deduct:.2f} рублей (включая комиссию {int(procent_rate*100)}%), у вас есть: {balance:.2f} рублей. Введите заново:")
        return
    
    await state.update_data(amount=amount, commission=commission, total_deduct=total_deduct)
    
    # Выбор метода вывода
    keyboard = InlineKeyboardMarkup(inline_keyboard=[
        [InlineKeyboardButton(text="💎 CryptoBot", callback_data="method_crypto")],
        [InlineKeyboardButton(text="💳 Банковская карта", callback_data="method_card")],
        [InlineKeyboardButton(text="🔙 Назад", callback_data="back_to_menu")]
    ])
    
    await message.answer(f"Выберите куда хотите вывести средства ({amount:.2f} рублей с комиссией {int(procent_rate*100)}%):", reply_markup=keyboard)
    await state.set_state(VivdStates.wait_method_choice)

@router.callback_query(F.data == "method_crypto", StateFilter(VivdStates.wait_method_choice))
async def crypto_method(callback_query, state: FSMContext):
    await callback_query.answer()
    await callback_query.message.answer("Введите username аккаунта где есть ваш CryptoBot:")
    await state.update_data(method="CryptoBot")
    await state.set_state(VivdStates.wait_crypto_username)

@router.callback_query(F.data == "method_card", StateFilter(VivdStates.wait_method_choice))
async def card_method(callback_query, state: FSMContext):
    await callback_query.answer()
    await state.update_data(method="Банковская карта")
    await callback_query.message.answer("Введите номер карты:")
    await state.set_state(VivdStates.wait_card_number)

@router.message(StateFilter(VivdStates.wait_crypto_username))
async def process_crypto_username(message: Message, state: FSMContext):
    username = message.text.strip()
    
    if not username:
        await message.answer("❌ Username не может быть пустым. Введите заново:")
        return
    
    await state.update_data(rekvizit=username)
    
    user_id = message.from_user.id
    data = await state.get_data()
    
    amount = data.get('amount')
    commission = data.get('commission')
    total_deduct = data.get('total_deduct')
    method = data.get('method')
    rekvizit = data.get('rekvizit')
    
    # Списание с баланса
    update_user_balance(user_id, -total_deduct)
    
    # Генерация ID заявки и datetime
    date_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    id_zayavki = random.randint(100000, 999999)
    
    # Сохранение заявки в БД
    try:
        save_withdrawal(user_id, id_zayavki, "load", None, date_time, amount, rekvizit, method, None)
    except Exception as e:
        logging.error(f"Ошибка в vivod.py при сохранении заявки: {str(e)}")
        await message.answer("❌ Ошибка при сохранении заявки. Обратитесь в поддержку.")
        await state.clear()
        return
    
    # Уведомление в Telegram
    try:
        zayavki_chat_id = get_chat_id("zayavki")
        if zayavki_chat_id:
            notification_text = f"Новая заявка на вывод\n\nUser ID: {user_id}\nID заявки: {id_zayavki}\nСумма: {amount:.2f} рублей\nТип: {method}\nРеквизиты: {rekvizit}\nДата: {date_time}"
            await message.bot.send_message(chat_id=zayavki_chat_id, text=notification_text)
        else:
            logging.error("Не удалось получить chat_id для zayavki")
    except Exception as e:
        logging.error(f"Ошибка отправки уведомления: {str(e)}")
    
    await message.answer(
        f"✅ Заявка на вывод успешно создана!\n\n"
        f"Сумма вывода: {amount:.2f} рублей\n"
        f"Комиссия: {commission:.2f} рублей\n"
        f"Итого списано: {total_deduct:.2f} рублей\n"
        f"ID заявки: {id_zayavki}\n"
        f"Новый баланс: {get_user_balance(user_id):.2f} рублей"
    )
    
    # Возврат в главное меню
    keyboard = get_main_menu_keyboard()
    await message.answer("Операция завершена. Главное меню:", reply_markup=keyboard)
    
    await state.clear()

@router.message(StateFilter(VivdStates.wait_card_number))
async def process_card_number(message: Message, state: FSMContext):
    card_number = message.text.strip().replace(" ", "")
    
    if not card_number.isdigit() or len(card_number) < 16:
        await message.answer("❌ Неверный номер карты. Введите 16-20 цифр:")
        return
    
    await state.update_data(rekvizit=card_number)
    await message.answer("Введите имя владельца карты:")
    await state.set_state(VivdStates.wait_card_name)

@router.message(StateFilter(VivdStates.wait_card_name))
async def process_card_name(message: Message, state: FSMContext):
    card_name = message.text.strip()
    
    if not card_name or len(card_name) < 2:
        await message.answer("❌ Введите корректное имя владельца карты:")
        return
    
    await state.update_data(vivod_name=card_name)
    
    user_id = message.from_user.id
    data = await state.get_data()
    
    amount = data.get('amount')
    commission = data.get('commission')
    total_deduct = data.get('total_deduct')
    method = data.get('method')
    rekvizit = data.get('rekvizit')
    vivod_name = data.get('vivod_name')
    
    # Списание с баланса
    update_user_balance(user_id, -total_deduct)
    
    # Генерация ID заявки и datetime
    date_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    id_zayavki = random.randint(100000, 999999)
    
    # Сохранение заявки в БД
    try:
        save_withdrawal(user_id, id_zayavki, "pending", None, date_time, amount, rekvizit, method, vivod_name)
    except Exception as e:
        logging.error(f"Ошибка в vivod.py при сохранении заявки: {str(e)}")
        await message.answer("❌ Ошибка при сохранении заявки. Обратитесь в поддержку.")
        await state.clear()
        return
    
    # Уведомление в Telegram
    try:
        zayavki_chat_id = get_chat_id("zayavki")
        if zayavki_chat_id:
            notification_text = f"Новая заявка на вывод\n\nUser ID: {user_id}\nID заявки: {id_zayavki}\nСумма: {amount:.2f} рублей\nТип: {method}\nНомер карты: {rekvizit}\nВладелец: {vivod_name}\nДата: {date_time}"
            await message.bot.send_message(chat_id=zayavki_chat_id, text=notification_text)
        else:
            logging.error("Не удалось получить chat_id для zayavki")
    except Exception as e:
        logging.error(f"Ошибка отправки уведомления: {str(e)}")
    
    await message.answer(
        f"✅ Заявка на вывод успешно создана!\n\n"
        f"Сумма вывода: {amount:.2f} рублей\n"
        f"Комиссия: {commission:.2f} рублей\n"
        f"Итого списано: {total_deduct:.2f} рублей\n"
        f"ID заявки: {id_zayavki}\n"
        f"Новый баланс: {get_user_balance(user_id):.2f} рублей"
    )
    
    # Возврат в главное меню
    keyboard = get_main_menu_keyboard()
    await message.answer("Операция завершена. Главное меню:", reply_markup=keyboard)
    
    await state.clear()

@router.callback_query(F.data == "withdraw_funds")
async def withdraw_funds_callback(callback_query: types.CallbackQuery, state: FSMContext):
    """Обработчик кнопки 'Вывод средств' из личного кабинета"""
    await callback_query.answer()
    
    if not get_function_status('vivod'):
        await callback_query.message.answer("Проводятся технические работы")
        return
    
    user_id = callback_query.from_user.id
    balance = get_user_balance(user_id)
    procent_rate = get_procent_rate()
    min_withdrawal = get_min_withdrawal()
    
    # Расчет минимального требуемого баланса
    min_balance_required = min_withdrawal + (min_withdrawal * procent_rate)
    
    if balance < min_balance_required:
        text = f"❌ На вашем балансе не достаточно средств. Пополните свой баланс.\n\nМинимальный баланс для вывода: {min_balance_required:.2f} рублей\nВаш текущий баланс: {balance:.2f} рублей"
        keyboard = InlineKeyboardMarkup(inline_keyboard=[
            [InlineKeyboardButton(text="💰 Пополнить баланс", callback_data="top_up_balance")],
            [InlineKeyboardButton(text="🔙 Назад", callback_data="back_to_menu")]
        ])
        await callback_query.message.answer(text, reply_markup=keyboard)
        return
    
    await callback_query.message.answer("Введите сумму которую хотите вывести:")
    await state.set_state(VivdStates.wait_amount)

@router.callback_query(F.data == "back_to_menu", StateFilter(VivdStates))
async def back_to_menu(callback_query, state: FSMContext):
    await callback_query.answer()
    keyboard = get_main_menu_keyboard()
    await callback_query.message.answer("Главное меню:", reply_markup=keyboard)
    await state.clear()