#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import imaplib
import email
from email.header import decode_header
from email.utils import parseaddr
import os
import json
from datetime import datetime, timedelta
from anthropic import Anthropic
from gtts import gTTS
import config

def decode_mime_words(s):
    """Dekoduje zakodowane nagłówki MIME"""
    if not s:
        return ""
    decoded_parts = []
    for content, encoding in decode_header(s):
        if isinstance(content, bytes):
            if encoding:
                try:
                    decoded_parts.append(content.decode(encoding))
                except:
                    decoded_parts.append(content.decode('utf-8', errors='ignore'))
            else:
                decoded_parts.append(content.decode('utf-8', errors='ignore'))
        else:
            decoded_parts.append(str(content))
    return ''.join(decoded_parts)

def extract_email_address(from_field):
    """Wyciąga czysty adres email i nazwę"""
    name, email_addr = parseaddr(from_field)
    name = decode_mime_words(name)
    return name if name else email_addr, email_addr

def get_email_body(msg):
    """Wyciąga treść emaila"""
    body = ""
    if msg.is_multipart():
        for part in msg.walk():
            content_type = part.get_content_type()
            if content_type == "text/plain":
                try:
                    body = part.get_payload(decode=True).decode('utf-8', errors='ignore')
                    break
                except:
                    continue
    else:
        try:
            body = msg.get_payload(decode=True).decode('utf-8', errors='ignore')
        except:
            body = ""
    return body.strip()

def summarize_with_claude(sender_name, sender_email, subject, body):
    """Streszcza email i klasyfikuje jego typ używając Claude"""
    client = Anthropic(api_key=config.CLAUDE_API_KEY)
    
    body_preview = body[:1500] if body else "Brak treści"
    
    prompt = f"""Otrzymałem email.

Od: {sender_name} ({sender_email})
Temat: {subject}
Treść: {body_preview}

Przeanalizuj ten email i zwróć odpowiedź w następującym formacie (bez żadnego dodatkowego tekstu):

KATEGORIA: [wybierz jedną: OSOBISTA | PRACA | REKLAMA | OFERTA_WSPÓŁPRACY | NEWSLETTER | SPAM | POWIADOMIENIE | INNA]
PRIORYTET: [WYSOKI | ŚREDNI | NISKI]
STRESZCZENIE: [2-3 zdania po polsku, zwięźle, bez formatowania markdown]

Wytyczne kategorii:
- OSOBISTA: wiadomości od znajomych, rodziny
- PRACA: sprawy służbowe, zadania, projekty
- REKLAMA: typowa reklama produktów/usług
- OFERTA_WSPÓŁPRACY: propozycje biznesowe, partnerstwa
- NEWSLETTER: automatyczne biuletyny, aktualizacje
- SPAM: niechciana poczta, phishing
- POWIADOMIENIE: potwierdzenia, alerty systemowe
- INNA: wszystko inne

Priorytet WYSOKI jeśli wymaga pilnej reakcji."""

    message = client.messages.create(
        model="claude-sonnet-4-20250514",
        max_tokens=400,
        messages=[
            {"role": "user", "content": prompt}
        ]
    )
    
    response_text = message.content[0].text.strip()
    
    category = "INNA"
    priority = "ŚREDNI"
    summary = response_text
    
    lines = response_text.split('\n')
    for line in lines:
        line = line.strip()
        if line.startswith('KATEGORIA:'):
            category = line.replace('KATEGORIA:', '').strip()
        elif line.startswith('PRIORYTET:'):
            priority = line.replace('PRIORYTET:', '').strip()
        elif line.startswith('STRESZCZENIE:'):
            summary = line.replace('STRESZCZENIE:', '').strip()
    
    summary = summary.replace('**', '').replace('*', '').replace('##', '').replace('#', '')
    
    return {
        'category': category,
        'priority': priority,
        'summary': summary.strip()
    }

def generate_audio(text, filename):
    """Generuje plik audio z tekstu"""
    tts = gTTS(text=text, lang='pl', slow=False)
    tts.save(filename)
    print(f"Audio zapisane: {filename}")

def clean_old_emails():
    """Usuwa pliki audio i JSON starsze niż 24 godziny"""
    try:
        output_dir = config.OUTPUT_DIR
        now = datetime.now()
        cutoff_time = now - timedelta(hours=12)  # 24 godziny
        
        for filename in os.listdir(output_dir):
            if filename.endswith('.json'):
                filepath = os.path.join(output_dir, filename)
                try:
                    # Sprawdź czas utworzenia pliku
                    file_time = datetime.fromtimestamp(os.path.getctime(filepath))
                    
                    if file_time < cutoff_time:
                        # Plik starszy niż 24h - usuń
                        with open(filepath, 'r', encoding='utf-8') as f:
                            data = json.load(f)
                        
                        # Usuń JSON
                        os.remove(filepath)
                        print(f"Usunięto stary email (>24h): {filename}")
                        
                        # Usuń powiązany MP3
                        audio_file = data.get('audio_file')
                        if audio_file and os.path.exists(audio_file):
                            os.remove(audio_file)
                            print(f"Usunięto: {os.path.basename(audio_file)}")
                
                except Exception as e:
                    print(f"Błąd przetwarzania {filename}: {e}")
                    continue
        
        print("Czyszczenie starych emaili zakończone.")
        
    except Exception as e:
        print(f"Błąd podczas czyszczenia: {e}")

def process_unread_emails():
    """Główna funkcja - przetwarza nieprzeczytane emaile"""
    
    # Najpierw wyczyść stare (>24h)
    clean_old_emails()
    
    # Połącz z serwerem IMAP
    print("Łączę z serwerem pocztowym...")
    mail = imaplib.IMAP4_SSL(config.EMAIL_HOST, config.EMAIL_PORT)
    mail.login(config.EMAIL_LOGIN, config.EMAIL_PASSWORD)
    mail.select(config.EMAIL_FOLDER)
    
    # Szukaj nieprzeczytanych emaili
    status, messages = mail.search(None, 'UNSEEN')
    email_ids = messages[0].split()
    
    if not email_ids:
        print("Brak nowych emaili.")
        mail.logout()
        return
    
    print(f"Znaleziono {len(email_ids)} nowych emaili.")
    
    # Utwórz folder output jeśli nie istnieje
    os.makedirs(config.OUTPUT_DIR, exist_ok=True)
    
    for email_id in email_ids:
        try:
            # Pobierz email z UID
            status, msg_data = mail.fetch(email_id, '(RFC822 UID)')
            
            # Wyciągnij UID
            uid_pattern = b'UID '
            uid = None
            for response_part in msg_data:
                if isinstance(response_part, tuple):
                    continue
                if uid_pattern in response_part:
                    uid = response_part.split()[2].decode()
            
            msg = email.message_from_bytes(msg_data[0][1])
            
            # Dekoduj dane
            subject_raw = msg['Subject'] or "Brak tematu"
            subject = decode_mime_words(subject_raw)
            
            from_raw = msg['From']
            sender_name, sender_email = extract_email_address(from_raw)
            
            body = get_email_body(msg)
            
            print(f"\nPrzetwarzam: {subject}")
            print(f"Od: {sender_name} <{sender_email}>")
            
            # Sprawdź czy nie przetwarzaliśmy już tego emaila (po UID)
            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            json_filename = os.path.join(config.OUTPUT_DIR, f"email_{timestamp}.json")
            
            # Sprawdź czy email o tym UID już istnieje
            existing = False
            for filename in os.listdir(config.OUTPUT_DIR):
                if filename.endswith('.json'):
                    filepath = os.path.join(config.OUTPUT_DIR, filename)
                    try:
                        with open(filepath, 'r', encoding='utf-8') as f:
                            data = json.load(f)
                            if data.get('email_uid') == uid:
                                existing = True
                                print(f"Email już przetworzony (UID: {uid}), pomijam.")
                                break
                    except:
                        continue
            
            if existing:
                # Email już był przetworzony, ale wciąż jest UNSEEN - oznacz jako przeczytany
                mail.store(email_id, '+FLAGS', '\\Seen')
                continue
            
            # Streszczenie przez Claude
            claude_response = summarize_with_claude(sender_name, sender_email, subject, body)
            
            category = claude_response['category']
            priority = claude_response['priority']
            summary = claude_response['summary']
            
            print(f"Kategoria: {category} | Priorytet: {priority}")
            
            # Mapowanie kategorii
            category_map = {
                'OSOBISTA': {'emoji': '💬', 'name': 'Wiadomość osobista'},
                'PRACA': {'emoji': '💼', 'name': 'Praca'},
                'REKLAMA': {'emoji': '📢', 'name': 'Reklama'},
                'OFERTA_WSPÓŁPRACY': {'emoji': '🤝', 'name': 'Oferta współpracy'},
                'NEWSLETTER': {'emoji': '📰', 'name': 'Newsletter'},
                'SPAM': {'emoji': '🚫', 'name': 'Spam'},
                'POWIADOMIENIE': {'emoji': '🔔', 'name': 'Powiadomienie'},
                'INNA': {'emoji': '📧', 'name': 'Inna'}
            }
            
            category_info = category_map.get(category, category_map['INNA'])
            
            # Przygotuj tekst do odczytania
            category_intro = ""
            if category in ['REKLAMA', 'SPAM', 'OFERTA_WSPÓŁPRACY', 'NEWSLETTER']:
                category_intro = f"Uwaga, to prawdopodobnie {category_info['name'].lower()}. "
            
            read_text = f"{category_intro}Nowa wiadomość od {sender_name}. Temat: {subject}. {summary}"
            
            # Wygeneruj unikalna nazwę pliku
            audio_filename = os.path.join(config.OUTPUT_DIR, f"email_{timestamp}.mp3")
            
            # Generuj audio
            generate_audio(read_text, audio_filename)
            
            # Zapisz metadata
            metadata = {
                "timestamp": timestamp,
                "sender_name": sender_name,
                "sender_email": sender_email,
                "sender": f"{sender_name} <{sender_email}>",
                "subject": subject,
                "summary": summary,
                "category": category,
                "category_emoji": category_info['emoji'],
                "category_name": category_info['name'],
                "priority": priority,
                "audio_file": audio_filename,
                "email_uid": uid,
                "created_at": datetime.now().isoformat()
            }
            
            with open(json_filename, 'w', encoding='utf-8') as f:
                json.dump(metadata, f, ensure_ascii=False, indent=2)
            
            # Oznacz jako przeczytany
            mail.store(email_id, '+FLAGS', '\\Seen')
            print(f"Email przetworzony i oznaczony jako przeczytany.")
            
        except Exception as e:
            print(f"Błąd podczas przetwarzania emaila: {e}")
            import traceback
            traceback.print_exc()
            continue
    
    mail.logout()
    print("\nZakończono przetwarzanie.")

if __name__ == "__main__":
    process_unread_emails()