from collections import defaultdict, OrderedDict
from datetime import datetime, timezone
import time as std_time
import pymysql
import json

from API.dataAPI import DataAPI
from API.jupAPI import JupAPI
from API.coingeckoAPI import CoingeckoAPI
from utils.StM import StaticMethod
from utils.logger import *
from utils.config import *

 
async def filter_token_by_candles(token):
    """
    Фильтрует токен на основе свечей: должен достичь mcap без пампа выше pump_percent.
    """
    candles = JupAPI.get_all_candles(token)
    if not candles:
        return False

    start_price = candles[0].get('open')
    if not start_price or start_price == 0:
        return False

    if candles[0].get('close') >= 30000:
        quality = "CO30K" # to docs close over 30k
        app_logger.info("🪙❌ НЕ ПРОШЁЛ — первый close уже выше 30к") 
        return False

    if start_price >= MC_STOP:
        quality = "FCOT" # First candle over target
        app_logger.info("🪙❌ НЕ ПРОШЁЛ — первая свеча уже выше цели") 
        return False

    reached_mcap = False
    had_pump = False

    for candle in candles:
        open_price = candle.get('open')
        close_price = candle.get('close')

        if not open_price or open_price == 0:
            continue

        price_change_percent = ((close_price - open_price) / open_price) * 100

        if price_change_percent >= PUMP_PERCENT:
            had_pump = True

        if open_price >= MC_STOP or close_price >= MC_STOP:
            reached_mcap = True
            break  # цель достигнута, дальше не смотрим

    if reached_mcap:
        if had_pump:
            quality = "TRPB" # Target reach pump before
            app_logger.info("🪙❌ НЕ ПРОШЁЛ — достиг цели, но был памп до этого")
            return quality
        else:
            quality = "good" #good
            app_logger.info("🪙✅ ПРОШЁЛ — достиг цели без пампа") 
            return quality
    else:
        if not had_pump:
            quality = "NOMIG" # 10k not reached no pump
            app_logger.info("НЕ ПРОШЁЛ — не достиг 10000 , но пампов не было ") 
            return quality
        else:
            quality = "TNRPB" # Target not reached pump before
            app_logger.info("🪙❌ НЕ ПРОШЁЛ — не достиг цели, но был памп") 
            return quality
        
        
        
def filter_wallets_by_token_count(wallets):
    """
        Фильтрует кошельки, у которых количество токенов не превышает MAX_TOKENS_FOR_WALLET.
        Также выставляет флаг freshik.
    """
    valid_wallets = []
    max_retries = 3
    retry_delay = 1
    for wallet in wallets:
        for attempt in range(max_retries):
            try:
                response = DataAPI().get_token_accounts_by_owner(wallet)
                if response and "value" in response:
                    break
                else:
                    raise ValueError("[filter_wallets_by_token_count] Некорректный ответ")
            except Exception as e:
                fil_logger.error(f" Ошибка при получении токенов для {wallet}, попытка {attempt + 1}/{max_retries}: {e}")
                std_time.sleep(retry_delay)
        else:
            fil_logger.warning(f"[filter_wallets_by_token_count] Пропускаем {wallet} после {max_retries} попыток")
            continue

        mint_addresses = set()
        for acc in response.get("value", []):
            try:
                mint = acc["account"]["data"]["parsed"]["info"]["mint"]
                mint_addresses.add(mint)
            except KeyError:
                continue

        if len(mint_addresses) <= MAX_TOKENS_FOR_WALLET:
            valid_wallets.append(wallet)

    return valid_wallets