from email.policy import default
import uuid
import os
from datetime import date
from django.conf import settings
from django.db import models
from django.template.loader import render_to_string
from crm.models import Lead, Quote
from lib.sevices import generate_amount_in_words
from lib.choices import choices_the_options
from utils.currency import CurrencyType


class Invoice(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    quote = models.ForeignKey(Quote, on_delete=models.SET_NULL, null=True, blank=True)
    invoice_number = models.CharField(max_length=20, unique=True)
    invoice_date = models.DateField()
    lead = models.ForeignKey(Lead, on_delete=models.CASCADE, related_name='invoices')
    currency = models.CharField(max_length=3, choices=choices_the_options(CurrencyType), default=CurrencyType.INR.value)
    created_at = models.DateTimeField(auto_now_add=True)
    pdf_file = models.FileField(upload_to='media/invoices/', null=True, blank=True)
    mark_as_sent = models.BooleanField(default=False)
    approved = models.BooleanField(default=False)
    pending_amount = models.DecimalField(max_digits=10, decimal_places=2, default=0.0)
    is_paid = models.BooleanField(default=False)

    def __str__(self):
        return str(self.invoice_number)

    class Meta:
        ordering = ['-created_at']

    def save(self, *args, **kwargs):
        super().save(*args, **kwargs)

    def generate_pdf(self):
        items = self.items.all()
        if not items.exists() and self.quote:
            for quote_item in self.quote.items.all():
                from crm.models import InvoiceItem
                InvoiceItem.objects.create(
                    invoice=self,
                    item_name=quote_item.item_name,
                    description=quote_item.description,
                    qty=quote_item.qty,
                    rate=quote_item.rate,
                    amount=quote_item.amount,
                )
            items = self.items.all()

        # Use the standalone PDF generator
        try:
            import sys
            import os
            # Add the pdfTest directory to the Python path
            pdf_test_path = os.path.join(settings.BASE_DIR, 'pdfTest')
            if pdf_test_path not in sys.path:
                sys.path.append(pdf_test_path)
            
            from invoice_pdf_generator import InvoicePDFGenerator
            
            # Create invoices directory
            invoices_dir = os.path.join(settings.MEDIA_ROOT, "invoices")
            os.makedirs(invoices_dir, exist_ok=True)
            pdf_path = os.path.join(invoices_dir, f"{self.invoice_number}.pdf")
            
            # Generate PDF using the standalone generator
            generator = InvoicePDFGenerator(self)
            generator.generate_pdf(pdf_path)
            
            # Update the model's pdf_file field
            self.pdf_file.name = f"invoices/{self.invoice_number}.pdf"
            self.save(update_fields=["pdf_file"])
            
        except ImportError as e:
            print(f"Error importing PDF generator: {e}")
            # Fallback to basic PDF generation if the standalone generator is not available
            self._generate_basic_pdf()

    def _generate_basic_pdf(self):
        """Fallback basic PDF generation method"""
        from reportlab.lib import colors
        from reportlab.lib.pagesizes import A4
        from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
        from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle
        
        items = self.items.all()
        subtotal = sum(float(item.amount) for item in items)
        total = subtotal

        # Generate basic PDF
        invoices_dir = os.path.join(settings.MEDIA_ROOT, "invoices")
        os.makedirs(invoices_dir, exist_ok=True)
        pdf_path = os.path.join(invoices_dir, f"{self.invoice_number}.pdf")
        
        doc = SimpleDocTemplate(pdf_path, pagesize=A4)
        story = []
        styles = getSampleStyleSheet()
        
        # Basic content
        story.append(Paragraph(f"Invoice #{self.invoice_number}", styles['Title']))
        story.append(Paragraph(f"Date: {self.invoice_date}", styles['Normal']))
        story.append(Paragraph(f"Total: ₹{total:,.2f}", styles['Normal']))
        
        doc.build(story)
        
        self.pdf_file.name = f"invoices/{self.invoice_number}.pdf"
        self.save(update_fields=["pdf_file"])

    def ensure_items_from_quote(self):
        if self.quote and self.items.count() == 0:
            for quote_item in self.quote.items.all():
                from crm.models import InvoiceItem
                InvoiceItem.objects.create(
                    invoice=self,
                    item_name=quote_item.item_name,
                    description=quote_item.description,
                    qty=quote_item.qty,
                    rate=quote_item.rate,
                    amount=quote_item.amount,
                )
            self.generate_pdf()


class InvoiceItem(models.Model):
    invoice = models.ForeignKey(Invoice, on_delete=models.CASCADE, related_name='items')
    item_name = models.CharField(max_length=255)
    description = models.TextField(blank=True)
    qty = models.IntegerField()
    rate = models.DecimalField(max_digits=10, decimal_places=2)
    amount = models.DecimalField(max_digits=10, decimal_places=2)

    def __str__(self):
        return str(self.item_name)
