import imaplib
import email
from email.header import decode_header
from django.core.management.base import BaseCommand
from mail_app.models import EmailAccount, EmailMessage, Client
from django.utils.timezone import make_aware
from datetime import datetime
import email.utils

class Command(BaseCommand):
    help = 'Fetches new emails and assigns them to clients'

    def handle(self, *args, **options):
        accounts = EmailAccount.objects.filter(is_active=True)
        
        if not accounts.exists():
            self.stdout.write(self.style.WARNING("No active accounts found."))
            return

        for account in accounts:
            self.stdout.write(f"Checking account: {account.email_address}...")
            try:
                mail = imaplib.IMAP4_SSL(account.imap_server)
                mail.login(account.email_address, account.password)
                mail.select("inbox")

                status, messages = mail.search(None, "ALL")
                email_ids = messages[0].split()

                if not email_ids:
                    self.stdout.write(self.style.SUCCESS(f"No new messages in: {account.email_address}"))
                    mail.logout()
                    continue

                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
                            subject_header = decode_header(msg.get("Subject", "(No Subject)"))[0]
                            subject = subject_header[0]
                            encoding = subject_header[1]
                            if isinstance(subject, bytes):
                                subject = subject.decode(encoding if encoding else 'utf-8', errors='ignore')
                            
                            # Sender & Auto-Client Creation
                            sender_raw = msg.get("From", "")
                            sender_name, sender_email_address = email.utils.parseaddr(sender_raw)
                            
                            # Message ID
                            message_id = msg.get("Message-ID", f"{account.id}-{e_id.decode()}")
                            
                            if EmailMessage.objects.filter(message_id=message_id).exists():
                                continue

                            # Create or Get Client
                            client_obj = None
                            if sender_email_address:
                                client_obj, created = Client.objects.get_or_create(
                                    email=sender_email_address,
                                    defaults={'name': sender_name}
                                )

                            # Body Text & HTML
                            body_text = ""
                            body_html = ""
                            if msg.is_multipart():
                                for part in msg.walk():
                                    if part.get_content_type() == "text/plain":
                                        try:
                                            body_text += part.get_payload(decode=True).decode('utf-8', errors='ignore')
                                        except:
                                            pass
                                    elif part.get_content_type() == "text/html":
                                        try:
                                            body_html += part.get_payload(decode=True).decode('utf-8', errors='ignore')
                                        except:
                                            pass
                            else:
                                content_type = msg.get_content_type()
                                try:
                                    payload = msg.get_payload(decode=True).decode('utf-8', errors='ignore')
                                    if content_type == "text/html":
                                        body_html = payload
                                    else:
                                        body_text = payload
                                except:
                                    pass
                            
                            # Date
                            date_tuple = email.utils.parsedate_tz(msg.get('Date'))
                            if date_tuple:
                                local_date = datetime.fromtimestamp(email.utils.mktime_tz(date_tuple))
                                aware_date = make_aware(local_date)
                            else:
                                aware_date = make_aware(datetime.now())

                            # Save Email
                            EmailMessage.objects.create(
                                account=account,
                                client=client_obj,
                                message_id=message_id,
                                subject=subject,
                                sender_email=sender_email_address,
                                sender_name=sender_name,
                                body_text=body_text,
                                body_html=body_html,
                                received_at=aware_date
                            )
                            
                            self.stdout.write(self.style.SUCCESS(f"Saved new email for client: {sender_email_address}"))

                mail.logout()
            except Exception as e:
                self.stdout.write(self.style.ERROR(f"Error in account {account.email_address}: {str(e)}"))

        self.stdout.write(self.style.SUCCESS("Fetch process completed successfully!"))
