import os
import mailbox
import email.utils
from email import policy
from email.parser import BytesParser
from tqdm import tqdm
from datetime import datetime
import typer

app = typer.Typer()

@app.command()
def convert_eml_to_mbox(
    eml_folder: str = typer.Option(..., help="Path to the folder containing .eml files"),
    output_mbox: str = typer.Option(..., help="Path to the output .mbox file"),
):
    """
    Converts .eml files from a specified folder into a single .mbox file.

    This version preserves the original MIME structure of each message so
    Thunderbird can display the message body, HTML, attachments, and inline
    content correctly.
    """
    converted_count = 0
    failed_files = []

    eml_files = sorted(
        os.path.join(eml_folder, f)
        for f in os.listdir(eml_folder)
        if f.lower().endswith(".eml")
    )

    if not eml_files:
        print(f"No .eml files found in: {eml_folder}")
        raise typer.Exit(code=1)

    # Create/open the mbox file
    mbox = mailbox.mbox(output_mbox, create=True)
    mbox.lock()

    try:
        for eml_file in tqdm(eml_files, desc="Converting", unit="file"):
            try:
                with open(eml_file, "rb") as f:
                    eml_content = f.read()

                # Parse using compat32 for best mailbox compatibility
                msg = BytesParser(policy=policy.compat32).parsebytes(eml_content)

                # Build a proper Unix From_ line for mbox
                from_addr = email.utils.parseaddr(msg.get("From", ""))[1] or "unknown@example.com"

                date_hdr = msg.get("Date")
                try:
                    parsed_date = email.utils.parsedate_to_datetime(date_hdr) if date_hdr else None
                except Exception:
                    parsed_date = None

                if parsed_date is None:
                    unix_from_date = datetime.now().ctime()
                else:
                    unix_from_date = parsed_date.ctime()

                msg.set_unixfrom(f"From {from_addr} {unix_from_date}")

                # Add the message directly to mbox without rebuilding headers/body
                mbox.add(msg)
                converted_count += 1

            except Exception as e:
                failed_files.append((eml_file, str(e)))

        mbox.flush()

    finally:
        mbox.unlock()
        mbox.close()

    print(f"Conversion complete. Saved to {output_mbox}")
    print(f"Total emails converted: {converted_count}")

    if failed_files:
        print("\nFailed to convert the following files:")
        for file, error in failed_files:
            print(f"File: {file}, Error: {error}")


if __name__ == "__main__":
    app()
