from __future__ import annotations

from dataclasses import dataclass
from pathlib import Path

import pythoncom
from loguru import logger
from win32com.client import Dispatch

from shipaw.config import SHIPAW_SETTINGS
from shipaw.fapi.requests import ShipmentRequest


@dataclass
class Email:
    to_address: str
    subject: str
    body: str
    attachment_paths: list[Path] | None = None

    def __post_init__(self):
        if self.attachment_paths is None:
            self.attachment_paths = []

    def send(self, sender: OutlookHandler) -> None:
        sender.create_open_email(self)


class OutlookHandler:
    """
    Email handler for Outlook (ripped from pawsupport where it has a superclass and siblings for Gmail etc)
    """

    @staticmethod
    def create_open_email(email: Email, html: bool = False):
        """
        Send email via Outlook

        :param email: Email object
        :param html: format email from html input
        :return: None
        """
        try:
            pythoncom.CoInitialize()

            outlook = Dispatch('outlook.application')
            mail = outlook.CreateItem(0)
            mail.To = email.to_address
            mail.Subject = email.subject
            if html:
                mail.HtmlBody = email.body
            else:
                mail.Body = email.body

            for att_path in email.attachment_paths:
                mail.Attachments.Add(str(att_path))
                print('Added attachment')
            mail.Display()
        except Exception as e:
            logger.exception(f'Failed to send email with error: {e}')
            raise ValueError(f'{e.args[0]}')
        finally:
            pythoncom.CoUninitialize()


async def subject(*, invoice_num: str | None = None, missing: bool = False, label: bool = False):
    return (
        f'Amherst Radios'
        f'{f"- Invoice {invoice_num} Attached" if invoice_num else ""} '
        f'{"- We Are Missing Kit" if missing else ""} '
        f'{"- Shipping Label Attached" if label else ""}'
    )


async def send_label_email(shipment_request: ShipmentRequest, label_path: Path):
    body = SHIPAW_SETTINGS.templates.get_template('email_snips/label_email.html').render(
        label=label_path,
        shipment_request=shipment_request,
        home_business_name=SHIPAW_SETTINGS.business_name,
    )
    email = Email(
        to_address=shipment_request.shipment.remote_full_contact.contact.email_address,
        subject='Amherst Radios Shipping - Shipping Label Attached',
        body=body,
        attachment_paths=[label_path],
    )

    OutlookHandler.create_open_email(email, html=True)
