import uuid
import os
from datetime import date
from django.conf import settings
from django.db import models
from crm.models import Lead
from lib.sevices import generate_amount_in_words
from utils.currency import CurrencyType
from lib.choices import choices_the_options


class Quote(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    quote_number = models.CharField(max_length=20, unique=True)
    quote_date = models.DateField()
    lead = models.ForeignKey(Lead, on_delete=models.CASCADE, related_name="quotes")
    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/quotes/", null=True, blank=True)
    mark_as_sent = models.BooleanField(default=False)
    is_invoice_converted = models.BooleanField(default=False)
    total_amount = models.DecimalField(max_digits=10, decimal_places=2, default=0.0)

    def __str__(self):
        return self.quote_number

    class Meta:
        ordering = ["-created_at"]

    @classmethod
    def generate_quote_number(cls):
        last_quote = cls.objects.order_by("-created_at").first()
        if last_quote:
            try:
                last_number = int(last_quote.quote_number.replace("QT-", ""))
                new_number = last_number + 1
            except (ValueError, AttributeError):
                new_number = cls.objects.count() + 1
        else:
            new_number = 1
        return f"QT-{new_number:06d}"

    def save(self, *args, **kwargs):
        if not self.quote_number:
            self.quote_number = self.generate_quote_number()

        # Calculate total amount from items
        items_total = sum(float(item.amount) for item in self.items.all()) if self.pk else 0.0
        self.total_amount = round(items_total, 2)
        super().save(*args, **kwargs)

        # Generate PDF if not exists
        if not self.pdf_file:
            self.generate_pdf()

    def generate_pdf(self):
        # 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 quote_pdf_generator import QuotePDFGenerator
            
            # Create quotes directory
            quotes_dir = os.path.join(settings.MEDIA_ROOT, "quotes")
            os.makedirs(quotes_dir, exist_ok=True)
            pdf_path = os.path.join(quotes_dir, f"{self.quote_number}.pdf")
            
            # Generate PDF using the standalone generator
            generator = QuotePDFGenerator(self)
            generator.generate_pdf(pdf_path)
            
            # Update the model's pdf_file field
            self.pdf_file.name = f"quotes/{self.quote_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.pagesizes import A4
        from reportlab.lib.styles import getSampleStyleSheet
        from reportlab.platypus import SimpleDocTemplate, Paragraph
        
        # Generate basic PDF
        quotes_dir = os.path.join(settings.MEDIA_ROOT, "quotes")
        os.makedirs(quotes_dir, exist_ok=True)
        pdf_path = os.path.join(quotes_dir, f"{self.quote_number}.pdf")
        
        doc = SimpleDocTemplate(pdf_path, pagesize=A4)
        story = []
        styles = getSampleStyleSheet()
        
        # Basic content
        story.append(Paragraph(f"Quote #{self.quote_number}", styles['Title']))
        story.append(Paragraph(f"Date: {self.quote_date}", styles['Normal']))
        story.append(Paragraph(f"Total: ₹{self.total_amount:,.2f}", styles['Normal']))
        
        doc.build(story)
        
        self.pdf_file.name = f"quotes/{self.quote_number}.pdf"
        self.save(update_fields=["pdf_file"])

    def convert_to_invoice(self):
        from crm.models import Invoice, InvoiceItem
        from lib.sevices import generate_invoice_number

        existing_invoice = Invoice.objects.filter(quote=self).first()
        if existing_invoice:
            if existing_invoice.items.count() == 0:
                for item in self.items.all():
                    InvoiceItem.objects.create(
                        invoice=existing_invoice,
                        item_name=item.item_name,
                        description=item.description,
                        qty=item.qty,
                        rate=item.rate,
                        amount=item.amount,
                    )
                existing_invoice.generate_pdf()
            return existing_invoice

        invoice = Invoice.objects.create(
            quote=self,
            invoice_number=generate_invoice_number(),
            invoice_date=date.today(),
            lead=self.lead,
            currency=self.currency,
        )

        for item in self.items.all():
            InvoiceItem.objects.create(
                invoice=invoice,
                item_name=item.item_name,
                description=item.description,
                qty=item.qty,
                rate=item.rate,
                amount=item.amount,
            )

        invoice.generate_pdf()
        return invoice

    def get_lead_data(self):
        lead = self.lead
        if not lead:
            return {}
        return {
            "lead_id": str(lead.id),
            "company": lead.company,
            "first_name": lead.first_name,
            "last_name": lead.last_name,
            "mobile": lead.mobile,
            "address": lead.address,
            "city": lead.city,
            "state": lead.state,
            "zip_code": lead.zip_code,
            "country": lead.country,
        }


class QuoteItem(models.Model):
    quote = models.ForeignKey(Quote, 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 self.item_name
