"""
Multi-Vendor Marketplace Models
Sellers can create stores, manage products, with subscription/commission plans
"""
from django.db import models
from django.utils.text import slugify
from django.conf import settings
from decimal import Decimal
import os
import re
import random
import string


class SubscriptionPlan(models.Model):
    """
    Subscription plans for vendors
    """
    PLAN_TYPE_CHOICES = [
        ('FREE', 'Free - Commission Only'),
        ('BASIC', 'Basic Monthly'),
        ('PROFESSIONAL', 'Professional Monthly'),
        ('ENTERPRISE', 'Enterprise Monthly'),
        ('YEARLY_BASIC', 'Basic Yearly'),
        ('YEARLY_PRO', 'Professional Yearly'),
    ]
    
    name = models.CharField(max_length=100)
    plan_type = models.CharField(max_length=20, choices=PLAN_TYPE_CHOICES, unique=True)
    description = models.TextField()
    
    # Pricing
    monthly_fee = models.DecimalField(max_digits=10, decimal_places=2, default=0)
    yearly_fee = models.DecimalField(max_digits=10, decimal_places=2, default=0)
    
    # Commission rates (percentage)
    commission_rate = models.DecimalField(
        max_digits=5, 
        decimal_places=2,
        help_text="Commission percentage on each sale (0-100)"
    )
    
    # Plan Features
    max_products = models.IntegerField(help_text="Maximum products allowed (-1 for unlimited)")
    max_images_per_product = models.IntegerField(default=5)
    can_use_ai_tools = models.BooleanField(default=False)
    priority_support = models.BooleanField(default=False)
    custom_store_url = models.BooleanField(default=False)
    analytics_access = models.BooleanField(default=False)
    
    # Status
    is_active = models.BooleanField(default=True)
    created_at = models.DateTimeField(auto_now_add=True)
    
    class Meta:
        ordering = ['monthly_fee']
    
    def __str__(self):
        return self.name + " - Rs." + str(self.monthly_fee) + "/mo"


def _sanitize_filename(filename):
    name, ext = os.path.splitext(filename)
    name = re.sub(r'[^A-Za-z0-9_.-]+', '_', name).strip('_')
    return f"{name}{ext.lower()}"


def _ensure_vendor_code(instance):
    if getattr(instance, 'vendor_code', None):
        return instance.vendor_code
    chars = string.ascii_uppercase + string.digits
    from .models import Vendor
    for _ in range(10):
        code = ''.join(random.choices(chars, k=8))
        if not Vendor.objects.filter(vendor_code=code).exists():
            instance.vendor_code = code
            return code
    instance.vendor_code = ''.join(random.choices(chars, k=12))
    return instance.vendor_code


def upload_kyc_profile_picture(instance, filename):
    code = _ensure_vendor_code(instance)
    return f"vendors/{code}/KYC/profile_pictures/{_sanitize_filename(filename)}"


def upload_kyc_address_proof(instance, filename):
    code = _ensure_vendor_code(instance)
    return f"vendors/{code}/KYC/address_proofs/{_sanitize_filename(filename)}"


def upload_vendor_consent_form(instance, filename):
    code = _ensure_vendor_code(instance)
    return f"vendors/{code}/vendors_docs/consent_forms/{_sanitize_filename(filename)}"


def upload_vendor_gst_photo(instance, filename):
    code = _ensure_vendor_code(instance)
    return f"vendors/{code}/vendors_docs/gst_photos/{_sanitize_filename(filename)}"


def upload_vendor_cheque_photo(instance, filename):
    code = _ensure_vendor_code(instance)
    return f"vendors/{code}/vendors_docs/cheque_photos/{_sanitize_filename(filename)}"


class Vendor(models.Model):
    """
    Vendor/Seller account - can manage own store
    """
    STATUS_CHOICES = [
        ('PENDING', 'Pending Approval'),
        ('ACTIVE', 'Active'),
        ('SUSPENDED', 'Suspended'),
        ('CLOSED', 'Closed'),
    ]
    
    # User association
    user = models.OneToOneField(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name='vendor_profile'
    )
    
    # Store Information
    store_name = models.CharField(max_length=200, unique=True)
    store_slug = models.SlugField(max_length=200, unique=True, blank=True)
    store_description = models.TextField()
    store_logo = models.ImageField(upload_to='vendor_logos/', blank=True, null=True)
    store_banner = models.ImageField(upload_to='vendor_banners/', blank=True, null=True)
    vendor_code = models.CharField(max_length=16, unique=True, blank=True, null=True, editable=False)
    
    # Contact
    business_email = models.EmailField()
    business_phone = models.CharField(max_length=20)
    website = models.URLField(blank=True)
    
    # Business Details
    business_name = models.CharField(max_length=200)
    business_type = models.CharField(max_length=100)
    tax_id = models.CharField(max_length=50, blank=True)
    aadhaar_no = models.CharField(max_length=12, blank=True)
    pan_no = models.CharField(max_length=10, blank=True)
    gst_no = models.CharField(max_length=15, blank=True)
    consent_form = models.FileField(upload_to=upload_vendor_consent_form, blank=True, null=True)
    gst_photo = models.ImageField(upload_to=upload_vendor_gst_photo, blank=True, null=True)
    kyc_photo = models.ImageField(upload_to=upload_kyc_profile_picture, blank=True, null=True)
    kyc_address_proof = models.ImageField(upload_to=upload_kyc_address_proof, blank=True, null=True)
    
    # Address
    address_line1 = models.CharField(max_length=255)
    address_line2 = models.CharField(max_length=255, blank=True)
    city = models.CharField(max_length=100)
    state = models.CharField(max_length=100)
    country = models.CharField(max_length=100)
    postal_code = models.CharField(max_length=20)
    kyc_submitted = models.BooleanField(default=False)
    kyc_approved = models.BooleanField(default=False)
    
    # Subscription
    subscription_plan = models.ForeignKey(
        SubscriptionPlan,
        on_delete=models.SET_NULL,
        null=True,
        related_name='vendors'
    )
    subscription_start_date = models.DateTimeField(null=True, blank=True)
    subscription_end_date = models.DateTimeField(null=True, blank=True)
    
    # Payment Information
    bank_account_name = models.CharField(max_length=200, blank=True)
    bank_account_number = models.CharField(max_length=50, blank=True)
    bank_name = models.CharField(max_length=100, blank=True)
    bank_routing_number = models.CharField(max_length=50, blank=True)
    crossed_cheque_photo = models.ImageField(upload_to=upload_vendor_cheque_photo, blank=True, null=True)
    
    # Statistics
    total_sales = models.DecimalField(max_digits=12, decimal_places=2, default=0)
    total_orders = models.IntegerField(default=0)
    rating = models.DecimalField(max_digits=3, decimal_places=2, default=0)
    total_reviews = models.IntegerField(default=0)
    
    # Status
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='PENDING')
    is_verified = models.BooleanField(default=False)
    store_limit = models.IntegerField(default=1)

    # Billing Configuration
    BILLING_CHOICES = [
        ('PLATFORM', 'AiBiMagics (Platform)'),
        ('VENDOR', 'Vendor'),
    ]
    billing_policy = models.CharField(
        max_length=20, 
        choices=BILLING_CHOICES, 
        default='VENDOR',
        help_text="Choose who appears as the billing entity on invoices"
    )
    
    # Timestamps
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    approved_at = models.DateTimeField(null=True, blank=True)
    
    class Meta:
        ordering = ['-created_at']
    
    def __str__(self):
        return self.store_name
    
    def save(self, *args, **kwargs):
        if not self.store_slug:
            self.store_slug = slugify(self.store_name)
        if not self.vendor_code:
            _ensure_vendor_code(self)
        super().save(*args, **kwargs)
    
    @property
    def is_subscription_active(self):
        """Check if subscription is active"""
        if not self.subscription_end_date:
            return False
        from django.utils import timezone
        return timezone.now() < self.subscription_end_date
    
    @property
    def product_count(self):
        """Count active products"""
        return self.products.filter(is_active=True).count()

class VendorStore(models.Model):
    vendor = models.ForeignKey(
        Vendor,
        on_delete=models.CASCADE,
        related_name='stores'
    )
    name = models.CharField(max_length=200)
    slug = models.SlugField(max_length=200, blank=True)
    description = models.TextField(blank=True)
    logo = models.ImageField(upload_to='vendor_store_logos/', blank=True, null=True)
    banner = models.ImageField(upload_to='vendor_store_banners/', blank=True, null=True)
    email = models.EmailField(blank=True)
    phone = models.CharField(max_length=20, blank=True)
    website = models.URLField(blank=True)
    is_active = models.BooleanField(default=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    class Meta:
        unique_together = ('vendor', 'slug')
        ordering = ['name']
    def __str__(self):
        return self.name
    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.name)
        super().save(*args, **kwargs)

class VendorSubscriptionPayment(models.Model):
    """
    Track vendor subscription payments
    """
    PAYMENT_STATUS_CHOICES = [
        ('PENDING', 'Pending'),
        ('PAID', 'Paid'),
        ('FAILED', 'Failed'),
        ('REFUNDED', 'Refunded'),
    ]
    
    vendor = models.ForeignKey(
        Vendor,
        on_delete=models.CASCADE,
        related_name='subscription_payments'
    )
    subscription_plan = models.ForeignKey(SubscriptionPlan, on_delete=models.SET_NULL, null=True)
    
    amount = models.DecimalField(max_digits=10, decimal_places=2)
    payment_method = models.CharField(max_length=50)
    transaction_id = models.CharField(max_length=200, unique=True)
    
    # Period covered by this payment
    period_start = models.DateTimeField()
    period_end = models.DateTimeField()
    
    status = models.CharField(max_length=20, choices=PAYMENT_STATUS_CHOICES, default='PENDING')
    paid_at = models.DateTimeField(null=True, blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    
    class Meta:
        ordering = ['-created_at']
    
    def __str__(self):
        return self.vendor.store_name + " - Rs." + str(self.amount) + " - " + self.status


class VendorCommission(models.Model):
    """
    Commission tracking for each sale
    """
    vendor = models.ForeignKey(
        Vendor,
        on_delete=models.CASCADE,
        related_name='commissions'
    )
    order = models.ForeignKey(
        'orders.Order',
        on_delete=models.CASCADE,
        related_name='vendor_commissions'
    )
    
    # Amounts
    order_total = models.DecimalField(max_digits=10, decimal_places=2)
    commission_rate = models.DecimalField(max_digits=5, decimal_places=2)
    commission_amount = models.DecimalField(max_digits=10, decimal_places=2)
    vendor_payout = models.DecimalField(max_digits=10, decimal_places=2)
    
    # Payout status
    is_paid = models.BooleanField(default=False)
    paid_at = models.DateTimeField(null=True, blank=True)
    payout_reference = models.CharField(max_length=200, blank=True)
    
    created_at = models.DateTimeField(auto_now_add=True)
    
    class Meta:
        ordering = ['-created_at']
    
    def __str__(self):
        return self.vendor.store_name + " - " + str(self.order.order_code) + " - Rs." + str(self.commission_amount)
    
    def save(self, *args, **kwargs):
        # Calculate commission
        self.commission_amount = (self.order_total * self.commission_rate) / 100
        self.vendor_payout = self.order_total - self.commission_amount
        super().save(*args, **kwargs)
    
    @property
    def is_received(self):
        return self.payout.filter(status='COMPLETED').exists()


class VendorPayout(models.Model):
    """
    Payouts to vendors
    """
    STATUS_CHOICES = [
        ('PENDING', 'Pending'),
        ('PROCESSING', 'Processing'),
        ('COMPLETED', 'Completed'),
        ('FAILED', 'Failed'),
    ]
    
    vendor = models.ForeignKey(
        Vendor,
        on_delete=models.CASCADE,
        related_name='payouts'
    )
    
    amount = models.DecimalField(max_digits=10, decimal_places=2)
    commissions = models.ManyToManyField(VendorCommission, related_name='payout')
    
    # Payment details
    payment_method = models.CharField(max_length=50, default='Bank Transfer')
    transaction_reference = models.CharField(max_length=200, blank=True)
    
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='PENDING')
    
    created_at = models.DateTimeField(auto_now_add=True)
    processed_at = models.DateTimeField(null=True, blank=True)
    completed_at = models.DateTimeField(null=True, blank=True)
    
    notes = models.TextField(blank=True)
    
    class Meta:
        ordering = ['-created_at']
    
    def __str__(self):
        return "Payout #" + str(self.id) + " - " + self.vendor.store_name + " - Rs." + str(self.amount)
