"""
Invoice generation utilities for OrderModel and ShopOrderModel.
These functions generate PDF invoices from HTML templates.
"""

from io import BytesIO
from datetime import datetime
from django.template.loader import render_to_string
from weasyprint import HTML
from django.conf import settings
import jdatetime
from django.conf import settings

def generate_order_invoice(order_id):
    """
    Generate a PDF invoice for an OrderModel instance.
    
    Args:
        order_id: The ID of the OrderModel instance
    
    Returns:
        BytesIO: A BytesIO object containing the PDF data
    """
    from .models import OrderModel
    
    try:
        order = OrderModel.objects.select_related(
            'user', 'address', 'discount_code'
        ).prefetch_related('items__product__product').get(pk=order_id)
    except OrderModel.DoesNotExist:
        raise ValueError(f"Order with ID {order_id} does not exist")
    
    # Prepare items with calculated discount amounts using stored values
    items = order.items.all()
    items_with_discount = []
    total_items_discount = 0
    
    for item in items:
        total_items_discount += item.total_product_discount_amount() or 0
        
        items_with_discount.append({
            'item': item,
            'discount_amount': item.total_product_discount_amount() or 0,
            'price_before_discount': item.total_price_before_discount(),
            'unit_price': item.unit_price(),
            'final_price': item.price_after_special_discount(),
        })
    
    # Resolve image paths for the template (absolute file paths for WeasyPrint)
    import os
    template_dir = os.path.join(settings.BASE_DIR, 'templates', 'order')
    logo_path = os.path.join(template_dir, 'logo2.png')
    logo_pattern_path = os.path.join(template_dir, 'logo-pattern.png')
    qr_code_path = os.path.join(template_dir, 'qr-code.png')
    
    # Use stored model fields for accuracy and consistency
    context = {
        'order': order,
        'order_number': order.pk,
        'items': items,
        'items_with_discount': items_with_discount,
        'user': order.user,
        'address': order.address,
        'discount_code': order.discount_code,
        'created_at_jalali': jdatetime.datetime.fromgregorian(datetime=order.created_at) if order.created_at else None,
        'total_items': sum(item.quantity for item in items),
        'subtotal': order.cart_total or 0,  # Stored field: total before any discounts
        'items_discount_amount': total_items_discount,
        'discount_amount': order.discount_amount or 0,  # Stored field: discount code amount
        'special_discount_total': order.special_discount_total or 0,  # Stored field: special discount total
        'tax_rate': settings.DEFAULT_TAX_RATE,
        'tax': order.tax or 0,  # Stored field: tax amount
        'final_price': order.final_price or 0,  # Stored field: final price after all calculations
        'is_paid': order.is_paid,
        'status': order.get_status_display(),
        'logo_path': logo_path,
        'logo_pattern_path': logo_pattern_path,
        'qr_code_path': qr_code_path,
    }
    
    # Render HTML template
    html_string = render_to_string('order/invoice_order2.html', context)
    
    # Generate PDF - use template directory as base_url so images resolve correctly
    html = HTML(string=html_string, base_url=template_dir)
    pdf_file = BytesIO()
    html.write_pdf(pdf_file)
    pdf_file.seek(0)
    
    return pdf_file


def generate_shop_order_invoice(shop_order_id):
    """
    Generate a PDF invoice for a ShopOrderModel instance.
    
    Args:
        shop_order_id: The ID of the ShopOrderModel instance
    
    Returns:
        BytesIO: A BytesIO object containing the PDF data
    """
    from .models import ShopOrderModel
    
    try:
        shop_order = ShopOrderModel.objects.select_related(
            'order', 'shop', 'shop__user', 'customer', 'address'
        ).prefetch_related('items__order_item__product__product').get(pk=shop_order_id)
    except ShopOrderModel.DoesNotExist:
        raise ValueError(f"ShopOrder with ID {shop_order_id} does not exist")
    
    # Prepare items with calculated discount amounts using stored values
    items = shop_order.items.select_related('order_item').all()
    items_with_discount = []
    total_items_discount = 0
    total_special_discount = 0
    
    for shop_item in items:
        order_item = shop_item.order_item
        
        # Calculate discount amount based on stored values
        # discount_amount = shop_item.discount_amount or 0
        # special_discount_amount = shop_item.special_discount_amount or 0
        
        total_items_discount += shop_item.discount_amount or 0
        total_special_discount += shop_item.special_discount_amount or 0
        
        # # Calculate unit price (after product discount, before special discount)
        # unit_price = shop_item.unit_price or 0
        
        # # Calculate price before discount (original unit price)
        # if order_item.discount_percent > 0:
        #     discount_multiplier = (100 - order_item.discount_percent) / 100
        #     if discount_multiplier > 0:
        #         price_before_discount_unit = int(unit_price / discount_multiplier)
        #     else:
        #         price_before_discount_unit = unit_price
        # else:
        #     price_before_discount_unit = unit_price
        
        # price_before_discount = price_before_discount_unit * shop_item.quantity
        
        # # Final price after all discounts
        # final_price = shop_item.total_price or 0
        
        items_with_discount.append({
            'item': shop_item,
            'order_item': order_item,
            'discount_amount': order_item.total_product_discount_amount() or 0,
            'special_discount_amount': order_item.special_discount_amount or 0,
            'price_before_discount': order_item.total_price_before_discount(),
            'unit_price': order_item.unit_price or 0,
            'final_price': order_item.price_after_special_discount() or 0,
        })
    
    # Calculate subtotal (cart total before discounts)
    subtotal = shop_order.subtotal or 0
    
    # Resolve image paths for the template (absolute file paths for WeasyPrint)
    import os
    template_dir = os.path.join(settings.BASE_DIR, 'templates', 'order')
    logo_path = os.path.join(template_dir, 'logo2.png')
    logo_pattern_path = os.path.join(template_dir, 'logo-pattern.png')
    qr_code_path = os.path.join(template_dir, 'qr-code.png')
    
    # Prepare context for the template
    context = {
        'shop_order': shop_order,
        'order_number': shop_order.order.pk,
        'shop_order_id': shop_order.pk,
        'shop': shop_order.shop,
        'customer': shop_order.customer,
        'customer_name': shop_order.customer_name,
        'customer_phone': shop_order.customer_phone,
        'address_text': shop_order.address_text,
        'address_postal_code': shop_order.address_postal_code,
        'address_phone': shop_order.address_phone,
        'address_city': shop_order.address_city,
        'address_province': shop_order.address_province,
        'address_recipient_name': shop_order.address_recipient_name,
        'items': items,
        'items_with_discount': items_with_discount,
        'created_at_jalali': jdatetime.datetime.fromgregorian(datetime=shop_order.order_created_at) if shop_order.order_created_at else None,
        'total_items': shop_order.items_count,
        'subtotal': subtotal,  # Total after product discount
        'items_discount_amount': total_items_discount,  # Product discount amount
        'special_discount_total': total_special_discount,  # Special discount total
        'tax_amount': shop_order.tax_amount,
        'commission_percent': shop_order.commission_percent,
        'commission_amount': shop_order.commission_amount,
        'payable_amount': shop_order.payable_amount,
        'is_paid': shop_order.is_paid,
        'status': shop_order.get_status_display(),
        'is_settled': shop_order.is_settled,
        'logo_path': logo_path,
        'logo_pattern_path': logo_pattern_path,
        'qr_code_path': qr_code_path,
    }
    
    # Render HTML template
    html_string = render_to_string('order/invoice_shop_order2.html', context)
    
    # Generate PDF - use template directory as base_url so images resolve correctly
    html = HTML(string=html_string, base_url=template_dir)
    pdf_file = BytesIO()
    html.write_pdf(pdf_file)
    pdf_file.seek(0)
    
    return pdf_file
