"""
HelaPOS / Bank Email IMAP Auto-Listener
Monitors incoming notification emails in real-time.
When a payment email arrives, it extracts Amount and Reference ID,
and automatically triggers HTG Digital auto-fulfillment!
"""

import imaplib
import email
from email.header import decode_header
import re
import time
import requests
from typing import Optional, Dict, Any

from config import (
    EMAIL_IMAP_SERVER,
    EMAIL_IMAP_PORT,
    EMAIL_USER,
    EMAIL_APP_PASSWORD,
    EMAIL_CHECK_INTERVAL,
)
from database import (
    record_bank_notification,
    find_pending_order_by_amount,
    get_order,
    update_order_payment,
)

LOCAL_API_URL = "http://127.0.0.1:5000/api/payment/sms_webhook"


def clean_header_text(header_val) -> str:
    if not header_val:
        return ""
    decoded_parts = decode_header(header_val)
    text = ""
    for part, enc in decoded_parts:
        if isinstance(part, bytes):
            text += part.decode(enc or "utf-8", errors="ignore")
        else:
            text += str(part)
    return text


def extract_body(msg) -> str:
    """Extracts plain text body from email message."""
    body = ""
    if msg.is_multipart():
        for part in msg.walk():
            content_type = part.get_content_type()
            content_disp = str(part.get("Content-Disposition"))
            if content_type == "text/plain" and "attachment" not in content_disp:
                payload = part.get_payload(decode=True)
                if payload:
                    body += payload.decode("utf-8", errors="ignore")
            elif content_type == "text/html" and not body and "attachment" not in content_disp:
                payload = part.get_payload(decode=True)
                if payload:
                    # Strip simple tags
                    html = payload.decode("utf-8", errors="ignore")
                    body += re.sub(r"<[^>]+>", " ", html)
    else:
        payload = msg.get_payload(decode=True)
        if payload:
            body = payload.decode("utf-8", errors="ignore")
    return body


def parse_and_process_alert(subject: str, body: str, sender: str):
    """Parses email content for Amount and Reference and triggers order fulfillment."""
    combined_text = f"{subject} {body}"

    # Extract Amount
    amt_match = re.search(r"(?:LKR|Rs\.?|Payment of|credited\s+with|Amount:?)\s*([\d,]+\.?\d*)", combined_text, re.IGNORECASE)
    if not amt_match:
        amt_match = re.search(r"([\d,]+\.\d{2})", combined_text)

    # Extract Reference ID (10-14 digits like 120061525716 or CAT-XXXX)
    ref_match = re.search(r"\b(\d{10,14})\b", combined_text)
    ref_code = ref_match.group(1) if ref_match else None

    # Check for CAT order code if present
    cat_match = re.search(r"(CAT-[A-Z0-9]{8})", combined_text, re.IGNORECASE)
    if cat_match:
        ref_code = cat_match.group(1)

    if amt_match:
        try:
            amt = float(amt_match.group(1).replace(",", ""))
            print(f"📧 [EMAIL DETECTED] Amount: LKR {amt:.2f} | Ref: {ref_code} | From: {sender}")

            # 1. Record in database
            record_bank_notification(
                source=f"Email ({sender})",
                amount=amt,
                reference=ref_code,
                raw_text=combined_text[:500],
            )

            # 2. Forward to Web Store API
            payload = {
                "sender": f"Email_{sender}",
                "message": combined_text,
                "amount": amt,
                "reference": ref_code,
            }
            try:
                r = requests.post(LOCAL_API_URL, json=payload, timeout=8)
                print(f"⚡ [EMAIL AUTO-FULFILLMENT]: {r.json()}\n")
            except Exception as e:
                print(f"⚠️ Error notifying Web Store API: {e}")

        except Exception as ex:
            print(f"❌ Error parsing amount from email: {ex}")


def start_email_listener():
    """Main IMAP loop to listen for incoming emails."""
    print("=" * 60)
    print("📬 HelaPOS / Bank Email Auto-Listener Starting...")
    print(f"📧 Connecting to: {EMAIL_USER} on {EMAIL_IMAP_SERVER}...")
    print("=" * 60)

    if not EMAIL_APP_PASSWORD or EMAIL_APP_PASSWORD == "your_app_password_here":
        print("⚠️ Email App Password not configured in config.py yet.")
        print("ℹ️ To use email auto-detection, add your Gmail App Password to config.py.")
        return

    while True:
        try:
            mail = imaplib.IMAP4_SSL(EMAIL_IMAP_SERVER, EMAIL_IMAP_PORT)
            mail.login(EMAIL_USER, EMAIL_APP_PASSWORD)
            mail.select("INBOX")
            print("✅ Email Connected! Listening for HelaPOS & Bank alerts in inbox...\n")

            while True:
                # Search for unread emails
                status, messages = mail.search(None, "UNSEEN")
                if status == "OK" and messages[0]:
                    email_ids = messages[0].split()
                    for e_id in email_ids:
                        res, msg_data = mail.fetch(e_id, "(RFC822)")
                        for response_part in msg_data:
                            if isinstance(response_part, tuple):
                                msg = email.message_from_bytes(response_part[1])
                                subject = clean_header_text(msg.get("Subject"))
                                sender = clean_header_text(msg.get("From"))
                                body = extract_body(msg)

                                # Filter for banking / HelaPOS / payment notifications
                                keywords = ["helapos", "seylan", "payment", "lankaqr", "credited", "received", "transaction"]
                                if any(k in subject.lower() or k in body.lower() for k in keywords):
                                    parse_and_process_alert(subject, body, sender)

                                # Mark as seen so we don't re-process
                                mail.store(e_id, "+FLAGS", "\\Seen")

                time.sleep(EMAIL_CHECK_INTERVAL)

        except Exception as e:
            print(f"⚠️ IMAP Connection lost ({e}). Reconnecting in 10s...")
            time.sleep(10)


if __name__ == "__main__":
    start_email_listener()
