# companies/models.py
from django.db import models
from django.utils import timezone
from django.utils.text import slugify


class Plan(models.Model):
    """
    Subscription plan that controls what features a company can access
    and how many resources they can use.
    """
    name = models.CharField(max_length=100, unique=True)

    # Pricing for each billing cycle
    price_monthly    = models.DecimalField(max_digits=10, decimal_places=2, default=0, help_text="Price per month")
    price_bimonthly  = models.DecimalField(max_digits=10, decimal_places=2, default=0, help_text="Price per 2 months")
    price_trimonthly = models.DecimalField(max_digits=10, decimal_places=2, default=0, help_text="Price per 3 months")
    price_yearly     = models.DecimalField(max_digits=10, decimal_places=2, default=0, help_text="Price per year")

    # Usage limits (0 = unlimited)
    max_orders_per_day = models.PositiveIntegerField(default=0, help_text="0 = unlimited")
    max_products = models.PositiveIntegerField(default=0, help_text="0 = unlimited")
    max_customers = models.PositiveIntegerField(default=0, help_text="0 = unlimited")
    max_categories = models.PositiveIntegerField(default=0, help_text="0 = unlimited")
    max_staff = models.PositiveIntegerField(default=0, help_text="0 = unlimited")
    max_branches = models.PositiveIntegerField(default=1, help_text="Max branches allowed")

    # Feature flags
    feature_pos_terminal_v1 = models.BooleanField(default=True)
    feature_pos_terminal_v2_grid = models.BooleanField(default=False)
    feature_barcode_pos = models.BooleanField(default=False)
    feature_bulk_import = models.BooleanField(default=False)
    feature_export = models.BooleanField(default=True)
    feature_profit_loss = models.BooleanField(default=False)
    feature_audit_logs = models.BooleanField(default=False)
    feature_suspicious_activity = models.BooleanField(default=False)
    feature_multi_branch = models.BooleanField(default=False)
    feature_wholesale_price = models.BooleanField(default=False)
    feature_discount = models.BooleanField(default=True)
    feature_promo = models.BooleanField(default=False)
    feature_android_app = models.BooleanField(default=False)
    feature_credit_sales = models.BooleanField(default=True)
    feature_advanced_reports = models.BooleanField(default=False)

    # ── New Feature Flags ──────────────────────────────────────────
    feature_product_variants  = models.BooleanField(default=False, help_text="Product size/color variants")
    feature_stock_transfers   = models.BooleanField(default=False, help_text="Inter-branch stock transfers")
    feature_online_store      = models.BooleanField(default=False, help_text="Public-facing online storefront")
    feature_price_lists       = models.BooleanField(default=False, help_text="Customer-specific pricing")
    feature_bundles           = models.BooleanField(default=False, help_text="Sellable product bundles")
    feature_2fa               = models.BooleanField(default=False, help_text="Two-factor authentication for staff")
    feature_whatsapp_sms      = models.BooleanField(default=False, help_text="WhatsApp/SMS receipts & alerts")

    # Visibility & ordering on pricing page
    is_public      = models.BooleanField(default=True, help_text="Show on public pricing page")
    display_order  = models.PositiveIntegerField(default=0, help_text="Order on pricing page (lower = first)")

    is_active = models.BooleanField(default=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        verbose_name = "Plan"
        verbose_name_plural = "Plans"
        ordering = ["display_order", "price_monthly"]

    def __str__(self):
        return f"{self.name} (₦{self.price_monthly}/mo)"

    def get_price_for_cycle(self, billing_cycle: str):
        """Return the correct price for the given billing cycle."""
        prices = {
            'monthly':    self.price_monthly,
            'bimonthly':  self.price_bimonthly  if self.price_bimonthly  else self.price_monthly * 2,
            'trimonthly': self.price_trimonthly if self.price_trimonthly else self.price_monthly * 3,
            'yearly':     self.price_yearly     if self.price_yearly     else self.price_monthly * 12,
        }
        return prices.get(billing_cycle, self.price_monthly)


class Company(models.Model):
    """
    A tenant company. All business data belongs to one company.
    URL routing: /<slug>/dashboard/, /<slug>/inventory/, etc.
    """
    name = models.CharField(max_length=200)
    slug = models.SlugField(max_length=100, unique=True, help_text="URL identifier e.g. acme-pos")
    email = models.EmailField(blank=True)
    phone = models.CharField(max_length=20, blank=True)
    address = models.TextField(blank=True)
    logo = models.ImageField(upload_to="company_logos/", blank=True, null=True)

    plan = models.ForeignKey(
        Plan,
        on_delete=models.PROTECT,
        null=True,
        blank=True,
        related_name="companies",
    )
    is_active = models.BooleanField(default=True, help_text="Inactive = suspended access")
    activation_code = models.CharField(max_length=100, blank=True)
    expiry_date = models.DateField(null=True, blank=True, help_text="Subscription expiry. Null = never expires.")

    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        verbose_name = "Company"
        verbose_name_plural = "Companies"
        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)

    @property
    def is_expired(self):
        if not self.expiry_date:
            return False
        return self.expiry_date < timezone.now().date()

    @property
    def is_accessible(self):
        """True if company is active and not expired."""
        return self.is_active and not self.is_expired

    @property
    def whatsapp_number(self):
        """Get the admin user's phone for super admin WhatsApp contact."""
        admin = self.users.filter(role='admin').first()
        return admin.phone if admin else ''


class CompanySettings(models.Model):
    """
    Per-company display and operational settings.
    Replaces the old global SystemSettings singleton.
    """
    CURRENCY_CHOICES = [
        ('NGN', 'Naira (₦)'),
        ('USD', 'Dollar ($)'),
        ('EUR', 'Euro (€)'),
        ('GBP', 'Pound (£)'),
    ]
    POS_INTERFACE_CHOICES = [
        ('classic', 'Classic POS (V1)'),
        ('grid', 'Smart Grid POS (V2)'),
    ]

    company = models.OneToOneField(Company, on_delete=models.CASCADE, related_name="settings")

    # Business identity
    business_name = models.CharField(max_length=200, default="My Business")
    business_address = models.TextField(blank=True)
    business_phone = models.CharField(max_length=20, blank=True)
    business_email = models.EmailField(blank=True)
    logo = models.ImageField(upload_to="company_logos/", blank=True, null=True)

    # Currency & tax
    currency = models.CharField(max_length=3, choices=CURRENCY_CHOICES, default="NGN")
    currency_symbol = models.CharField(max_length=5, default="₦")
    decimal_places = models.PositiveSmallIntegerField(default=2)
    use_comma_separator = models.BooleanField(default=True)
    vat_rate = models.DecimalField(max_digits=5, decimal_places=2, default=0.00)

    # POS
    pos_interface_mode = models.CharField(max_length=10, choices=POS_INTERFACE_CHOICES, default='classic')
    enable_camera_scanner = models.BooleanField(default=False)
    enable_unlimited_stock = models.BooleanField(default=False)
    enable_audit_log = models.BooleanField(default=False, help_text="Override plan: grant this company access to Audit Log")

    # Receipt
    receipt_header = models.TextField(blank=True)
    receipt_footer = models.TextField(blank=True)
    show_receipt_logo = models.BooleanField(default=True)

    # Theme
    primary_color = models.CharField(max_length=7, default="#667eea")
    secondary_color = models.CharField(max_length=7, default="#764ba2")
    accent_color = models.CharField(max_length=7, default="#f093fb")

    # Toggles
    show_inventory = models.BooleanField(default=True)
    show_receipts = models.BooleanField(default=True)
    show_analytics = models.BooleanField(default=True)
    show_reports = models.BooleanField(default=True)
    enable_sms   = models.BooleanField(default=False)
    enable_email = models.BooleanField(default=False)

    # ── WhatsApp / SMS Integration ─────────────────────────────────
    whatsapp_api_url           = models.CharField(max_length=300, blank=True, help_text="WhatsApp HTTP API endpoint")
    whatsapp_api_key           = models.CharField(max_length=200, blank=True, help_text="WhatsApp API key")
    sms_api_key                = models.CharField(max_length=200, blank=True, help_text="Termii or other SMS gateway key")
    sms_sender_id              = models.CharField(max_length=20, blank=True, default='SwiftPOS')
    send_receipt_via_whatsapp  = models.BooleanField(default=False, help_text="Send order receipt to customer via WhatsApp")
    send_credit_via_whatsapp   = models.BooleanField(default=False, help_text="Send credit balance reminder via WhatsApp")
    send_lowstock_via_whatsapp = models.BooleanField(default=False, help_text="Alert admin on low stock via WhatsApp")

    # ── Thermal Printer ────────────────────────────────────────────
    thermal_printer_name = models.CharField(max_length=100, blank=True, help_text="QZ Tray printer name for direct thermal printing")
    auto_print_on_sale   = models.BooleanField(default=False, help_text="Auto-print receipt on order completion")
    receipt_width_mm     = models.PositiveSmallIntegerField(default=80, help_text="Thermal paper width: 58 or 80mm")

    # ── Security ───────────────────────────────────────────────────
    require_2fa_for_admin   = models.BooleanField(default=False)
    require_2fa_for_manager = models.BooleanField(default=False)

    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        verbose_name = "Company Settings"
        verbose_name_plural = "Company Settings"

    def __str__(self):
        return f"Settings for {self.company.name}"


# ─────────────────────────────────────────────────────────────────────────────
# SUPERADMIN TWO-FACTOR AUTHENTICATION
# ─────────────────────────────────────────────────────────────────────────────

class SuperAdmin2FA(models.Model):
    """
    Per-superuser 2FA configuration, managed via Django admin.

    method choices:
      'email' – a 6-digit OTP is emailed on every login
      'totp'  – Google Authenticator / any TOTP app (RFC 6238)

    Only enforced when is_enabled=True.
    The totp_secret is a Base32 string generated once during setup;
    it powers the QR code the superadmin scans in Google Authenticator.
    """
    METHOD_EMAIL = 'email'
    METHOD_TOTP  = 'totp'
    METHOD_CHOICES = [
        (METHOD_EMAIL, 'Email OTP (6-digit code sent to your email)'),
        (METHOD_TOTP,  'Google Authenticator / TOTP App'),
    ]

    user = models.OneToOneField(
        'accounts.CustomUser',
        on_delete=models.CASCADE,
        related_name='superadmin_2fa',
        limit_choices_to={'is_superuser': True},
        help_text='Must be a superuser account.',
    )
    is_enabled  = models.BooleanField(
        default=False,
        help_text='Enable 2FA enforcement for this superuser on every login.',
    )
    method = models.CharField(
        max_length=10,
        choices=METHOD_CHOICES,
        default=METHOD_EMAIL,
        help_text='Which second factor to use.',
    )
    totp_secret = models.CharField(
        max_length=64,
        blank=True,
        editable=False,   # generated automatically; shown as QR in admin
        help_text='Auto-generated Base32 TOTP secret (do not edit manually).',
    )
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        verbose_name = 'Superadmin 2FA Config'
        verbose_name_plural = 'Superadmin 2FA Configs'

    def __str__(self):
        status = 'ON' if self.is_enabled else 'OFF'
        return f'2FA [{status}] ({self.get_method_display()}) — {self.user.username}'

    def get_or_create_totp_secret(self):
        """Generate and save a new TOTP secret if one doesn't exist yet."""
        import pyotp
        if not self.totp_secret:
            self.totp_secret = pyotp.random_base32()
            self.save(update_fields=['totp_secret'])
        return self.totp_secret

    def get_totp_uri(self):
        """Return the otpauth:// URI used to generate a QR code for Authenticator apps."""
        import pyotp
        secret = self.get_or_create_totp_secret()
        return pyotp.totp.TOTP(secret).provisioning_uri(
            name=self.user.email or self.user.username,
            issuer_name='SwiftPOS Superadmin',
        )

    def verify_totp(self, code):
        """Verify a TOTP code. Accepts ±30-second window."""
        import pyotp
        if not self.totp_secret:
            return False
        totp = pyotp.TOTP(self.totp_secret)
        return totp.verify(code, valid_window=1)
