from celery import shared_task
from utils.celery.celery_base_task import *
from django.conf import settings
from django.core.mail import get_connection, EmailMultiAlternatives
from django.template.loader import render_to_string
import logging, os
from openpyxl import Workbook
from openpyxl.styles import Font
from .models import Inquiries
from django.utils import timezone
from django.core.cache import cache
from pathlib import Path
from datetime import datetime
from django.utils.timezone import localtime
from utils.email_templates import inquiry_sender_copy, inquirer_receiver_copy

logging.basicConfig(
    level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s"
)

BASE_DIR = Path(__file__).resolve().parent
BASE_REPORTS_DIRECTORY = f"{BASE_DIR}/reports"


def apply_download_filters_of_inquiries(filters_dict):
    start_date = filters_dict.get("start_date", None)  # YYYY-MM-DD format
    end_date = filters_dict.get("end_date", None)
    inquiry_status = filters_dict.get("status", None)

    queryset = Inquiries.objects.order_by("-created_at")

    if start_date:
        start_date = datetime.strptime(start_date, "%Y-%m-%d")
        queryset = queryset.filter(created_at__gte=start_date)

    if end_date:
        end_date = datetime.strptime(end_date, "%Y-%m-%d")
        queryset = queryset.filter(created_at__lte=end_date)

    if inquiry_status:
        queryset = queryset.filter(status__iexact=end_date)

    return queryset


@shared_task
def download_report_of_inquiries(filters_dict=None):
    if not os.path.isdir(BASE_REPORTS_DIRECTORY):
        os.makedirs(BASE_REPORTS_DIRECTORY)
    else:
        files = os.listdir(BASE_REPORTS_DIRECTORY)

        for f in files:
            try:
                file_path = f"{BASE_REPORTS_DIRECTORY}/{f}"
                if os.path.isfile(file_path):
                    os.remove(file_path)
            except PermissionError:
                error_message = (
                    "Close any related files or previous file before downloading."
                )
                cache.set("inquiry_download_status", "error", timeout=300)
                cache.set("inquiry_download_errors", error_message, timeout=300)
                return

    cache.set("inquiry_download_status", "downloading", timeout=300)

    try:
        inquiries = apply_download_filters_of_inquiries(filters_dict=filters_dict)

        wb = Workbook()
        ws = wb.active
        ws.title = "Product Inquiries"

        bold_font = Font(bold=True)

        ws.append(
            [
                "Date Inquired",
                "Inquirer",
                "Email",
                "Contact Number",
                "Product Inquired",
                "Inquiry",
                "Status",
            ]
        )

        for cell in ws[1]:  # make headers bold
            cell.font = bold_font

        for i in inquiries:
            local_created_at = localtime(i.created_at)
            formatted_date = local_created_at.strftime("%B %-d, %Y %-I:%M%p")
            full_name = f"{i.first_name} {i.last_name}"
            article_number = getattr(i.product, "article_number", "N/A")
            product_details = f"""
            Name: {i.product.name}\n
            EDP #: {i.product.edp_number}\n
            Article #: {article_number}
            """

            ws.append(
                [
                    formatted_date,
                    full_name,
                    i.email,
                    i.contact_number,
                    product_details,
                    i.inquiry,
                    i.status.upper(),
                ]
            )

        time_now = timezone.localtime().strftime("%m%d%Y%H%M%S")
        file_name = f"{time_now}_productinquiries.xlsx"
        file_path = f"{BASE_REPORTS_DIRECTORY}/{file_name}"

        wb.save(file_path)
        cache.set("inquiry_download_status", "finished", timeout=300)
        cache.set("inquiry_download_path", file_path, timeout=300)
    except Exception as e:
        cache.set("inquiry_download_status", "error", timeout=300)
        cache.set("inquiry_download_errors", str(e), timeout=300)


@shared_task
def send_emails(created_inquiry):  # pragma: no cover
    # Send inquiry copy to sender
    is_temp_email_service = bool(os.environ.get("IS_TEMP_EMAIL_SERVICE", False))

    if is_temp_email_service:
        inquiry_sender_copy(details=created_inquiry)
        inquirer_receiver_copy(details=created_inquiry)
        return

    logging.info(f"Sending copy of inquiry to sender {created_inquiry["email"]}")
    context = {
        "name": created_inquiry["name"],
        "inquiry": created_inquiry["inquiry"],
        "product": created_inquiry["product"],
        "product_subcategory": created_inquiry["product_subcategory"],
    }

    email_connection = get_connection(
        username=settings.EMAIL_HOST_USER,
        password=settings.EMAIL_HOST_PASSWORD,
    )

    email_html_message = render_to_string("email/inquiry_sender.html", context)
    email = EmailMultiAlternatives(
        subject=f"Your '{created_inquiry["product"]}' Inquiry - Caracole Philippines",
        body="An email for dexterton appointment",
        from_email=settings.EMAIL_HOST_USER,
        to=[created_inquiry["email"]],
        connection=email_connection,
    )
    email.attach_alternative(email_html_message, "text/html")
    email.send()

    # Send inquiry copy to receiver
    logging.info(f"Sending copy of inquiry to receiver {settings.INQUIRY_RECEIVER}")
    context = {
        "email": created_inquiry["email"],
        "contact_number": created_inquiry["contact_number"],
        "date": created_inquiry["created_at"].strftime("%B %d, %Y"),
        "inquiry": created_inquiry["inquiry"],
        "product": created_inquiry["product"],
    }
    email_html_message = render_to_string("email/inquiry_receiver.html", context)
    email = EmailMultiAlternatives(
        subject=f"Inquiry From {created_inquiry["email"]}",
        body="An email for dexterton appointment",
        from_email=created_inquiry["email"],
        to=settings.INQUIRY_RECEIVER,
        cc=[settings.EMAIL_WEBDEV],
        connection=email_connection,
    )
    email.attach_alternative(email_html_message, "text/html")
    email.send()
