import imaplib, email, socket, ssl, datetime, re, os, json
from email.header import decode_header

old_getaddrinfo = socket.getaddrinfo
def new_getaddrinfo(*args, **kwargs):
    responses = old_getaddrinfo(*args, **kwargs)
    return [response for response in responses if response[0] == socket.AF_INET]
socket.getaddrinfo = new_getaddrinfo

# Network stability patch
socket.setdefaulttimeout(15) 

try: from binance_email_config import EMAIL_ACCOUNT, EMAIL_PASSWORD
except ImportError: from .binance_email_config import EMAIL_ACCOUNT, EMAIL_PASSWORD

CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
BASE_DIR = os.path.dirname(os.path.dirname(CURRENT_DIR))
PROCESSED_EMAILS_FILE = os.path.join(BASE_DIR, 'processed_emails.json')
LOG_FILE = os.path.join(BASE_DIR, 'history.log')

def log_imap(message):
    try:
        tz = datetime.timezone(datetime.timedelta(hours=4, minutes=30))
        now = datetime.datetime.now(tz).strftime('%Y-%m-%d %H:%M:%S')
        with open(LOG_FILE, 'a', encoding='utf-8') as f:
            f.write(f"[{now}] [SYSTEM_IMAP] {message}\n")
    except: pass

def get_processed_emails():
    if os.path.exists(PROCESSED_EMAILS_FILE):
        try:
            with open(PROCESSED_EMAILS_FILE, 'r') as f: return json.load(f)
        except: return []
    return []

def save_processed_email(msg_id):
    emails = get_processed_emails()
    if msg_id not in emails:
        emails.append(msg_id)
        try:
            with open(PROCESSED_EMAILS_FILE, 'w') as f: json.dump(emails[-2000:], f)
        except: pass

def check_binance_email(expected_amount, expected_username, target_date_str):
    try:
        log_imap(f"Connecting to IMAP... Target: {expected_amount} USDT | User: {expected_username}")
        ctx = ssl.create_default_context()
        mail = imaplib.IMAP4_SSL("imap.gmail.com", 993, ssl_context=ctx)
        mail.login(EMAIL_ACCOUNT, EMAIL_PASSWORD)
        mail.select("inbox")
        
        date_since = (datetime.datetime.now() - datetime.timedelta(days=2)).strftime("%d-%b-%Y")
        status, messages = mail.search(None, f'(SENTSINCE {date_since})')
        
        if status == "OK" and messages[0]:
            msg_nums = messages[0].split()
            log_imap(f"Found {len(msg_nums)} emails in Inbox.")
            processed_emails = get_processed_emails()
            for num in reversed(msg_nums[-30:]):
                res, msg_data = mail.fetch(num, "(RFC822)")
                for response_part in msg_data:
                    if isinstance(response_part, tuple):
                        msg = email.message_from_bytes(response_part[1])
                        msg_id = msg.get("Message-ID", "").strip()
                        sender = str(msg.get("From", "")).lower()
                        if "binance" not in sender: continue
                            
                        subject_encoded = msg.get("Subject", "")
                        subject_decoded, encoding = decode_header(subject_encoded)[0]
                        if isinstance(subject_decoded, bytes): subject = subject_decoded.decode(encoding if encoding else 'utf-8', errors='ignore')
                        else: subject = subject_decoded
                            
                        if "Payment Receive Successful" not in subject: continue
                            
                        body = ""
                        if msg.is_multipart():
                            for part in msg.walk():
                                ctype = part.get_content_type()
                                payload = part.get_payload(decode=True)
                                if not payload: continue
                                decoded_payload = payload.decode(errors='ignore')
                                if ctype == "text/plain": body += decoded_payload + " "
                                elif ctype == "text/html": body += re.sub(r'<[^>]+>', ' ', decoded_payload) + " "
                        else:
                            payload = msg.get_payload(decode=True)
                            if payload:
                                decoded_payload = payload.decode(errors='ignore')
                                if msg.get_content_type() == "text/html": body += re.sub(r'<[^>]+>', ' ', decoded_payload) + " "
                                else: body += decoded_payload + " "
                            
                        body_clean = re.sub(r'\s+', ' ', body).strip()
                        amt_str = f"{float(expected_amount):g}"
                        
                        amount_pattern = re.compile(rf"Amount\s*:?\s*{amt_str}(?:\.0+)?\s*(USDT|USDC)", re.IGNORECASE)
                        user_pattern = re.compile(rf"From\s*:?\s*{re.escape(expected_username)}", re.IGNORECASE)
                        date_pattern = re.compile(rf"Time\s*:?\s*{re.escape(target_date_str)}", re.IGNORECASE)
                        
                        if amount_pattern.search(body_clean) and user_pattern.search(body_clean) and date_pattern.search(body_clean):
                            if msg_id and msg_id in processed_emails: 
                                log_imap(f"Match found but already processed: {msg_id}")
                                continue
                            if msg_id: save_processed_email(msg_id)
                            log_imap("Valid match found and processed.")
                            mail.close(); mail.logout()
                            return True
        else:
            log_imap("No emails matched IMAP criteria.")
        mail.close(); mail.logout()
    except Exception as e:
        log_imap(f"IMAP EXCEPTION: {str(e)}")
    return False