# app/modules/billing/models/feature.py
"""
Feature registry for tier-based access control.

Provides a database-driven feature registry that allows:
- Dynamic feature-to-tier assignment (no code changes needed)
- UI metadata for frontend rendering
- Feature categorization for organization
- Upgrade prompts with tier info

Features are assigned to tiers via the SubscriptionTier.features JSON array.
This model provides the metadata and acts as a registry of all available features.
"""

import enum
from datetime import UTC, datetime

from sqlalchemy import Boolean, Column, DateTime, ForeignKey, Index, Integer, String, Text
from sqlalchemy.orm import relationship

from app.core.database import Base
from models.database.base import TimestampMixin


class FeatureCategory(str, enum.Enum):
    """Feature categories for organization."""

    ORDERS = "orders"
    INVENTORY = "inventory"
    ANALYTICS = "analytics"
    INVOICING = "invoicing"
    INTEGRATIONS = "integrations"
    TEAM = "team"
    BRANDING = "branding"
    CUSTOMERS = "customers"
    CMS = "cms"


class FeatureUILocation(str, enum.Enum):
    """Where the feature appears in the UI."""

    SIDEBAR = "sidebar"  # Main navigation item
    DASHBOARD = "dashboard"  # Dashboard widget/section
    SETTINGS = "settings"  # Settings page option
    API = "api"  # API-only feature (no UI)
    INLINE = "inline"  # Inline feature within a page


class Feature(Base, TimestampMixin):
    """
    Feature registry for tier-based access control.

    Each feature represents a capability that can be enabled/disabled per tier.
    The actual tier assignment is stored in SubscriptionTier.features as a JSON
    array of feature codes. This table provides metadata for:
    - UI rendering (icons, labels, locations)
    - Upgrade prompts (which tier unlocks this?)
    - Admin management (description, categorization)

    Example features:
    - analytics_dashboard: Full analytics with charts
    - api_access: REST API access for integrations
    - team_roles: Role-based permissions for team members
    - automation_rules: Automatic order processing rules
    """

    __tablename__ = "features"

    id = Column(Integer, primary_key=True, index=True)

    # Unique identifier used in code and tier.features JSON
    code = Column(String(50), unique=True, nullable=False, index=True)

    # Display info
    name = Column(String(100), nullable=False)
    description = Column(Text, nullable=True)

    # Categorization
    category = Column(String(50), nullable=False, index=True)

    # UI metadata - tells frontend how to render
    ui_location = Column(String(50), nullable=True)  # sidebar, dashboard, settings, api
    ui_icon = Column(String(50), nullable=True)  # Icon name (e.g., "chart-bar")
    ui_route = Column(String(100), nullable=True)  # Route pattern (e.g., "/vendor/{code}/analytics")
    ui_badge_text = Column(String(20), nullable=True)  # Badge to show (e.g., "Pro", "New")

    # Minimum tier that includes this feature (for upgrade prompts)
    # This is denormalized for performance - the actual assignment is in SubscriptionTier.features
    minimum_tier_id = Column(
        Integer, ForeignKey("subscription_tiers.id"), nullable=True, index=True
    )
    minimum_tier = relationship("SubscriptionTier", foreign_keys=[minimum_tier_id])

    # Status
    is_active = Column(Boolean, default=True, nullable=False)  # Feature available at all
    is_visible = Column(Boolean, default=True, nullable=False)  # Show in UI even if locked
    display_order = Column(Integer, default=0, nullable=False)  # Sort order within category

    # Indexes
    __table_args__ = (
        Index("idx_feature_category_order", "category", "display_order"),
        Index("idx_feature_active_visible", "is_active", "is_visible"),
    )

    def __repr__(self) -> str:
        return f"<Feature(code='{self.code}', name='{self.name}', category='{self.category}')>"

    def to_dict(self) -> dict:
        """Convert to dictionary for API responses."""
        return {
            "id": self.id,
            "code": self.code,
            "name": self.name,
            "description": self.description,
            "category": self.category,
            "ui_location": self.ui_location,
            "ui_icon": self.ui_icon,
            "ui_route": self.ui_route,
            "ui_badge_text": self.ui_badge_text,
            "minimum_tier_code": self.minimum_tier.code if self.minimum_tier else None,
            "minimum_tier_name": self.minimum_tier.name if self.minimum_tier else None,
            "is_active": self.is_active,
            "is_visible": self.is_visible,
            "display_order": self.display_order,
        }


# ============================================================================
# Feature Code Constants
# ============================================================================
# These constants are used throughout the codebase for type safety.
# The actual feature definitions and tier assignments are in the database.


class FeatureCode:
    """
    Feature code constants for use in @require_feature decorator and checks.

    Usage:
        @require_feature(FeatureCode.ANALYTICS_DASHBOARD)
        def get_analytics(...):
            ...

        if feature_service.has_feature(db, vendor_id, FeatureCode.API_ACCESS):
            ...
    """

    # Orders
    ORDER_MANAGEMENT = "order_management"
    ORDER_BULK_ACTIONS = "order_bulk_actions"
    ORDER_EXPORT = "order_export"
    AUTOMATION_RULES = "automation_rules"

    # Inventory
    INVENTORY_BASIC = "inventory_basic"
    INVENTORY_LOCATIONS = "inventory_locations"
    INVENTORY_PURCHASE_ORDERS = "inventory_purchase_orders"
    LOW_STOCK_ALERTS = "low_stock_alerts"

    # Analytics
    BASIC_REPORTS = "basic_reports"
    ANALYTICS_DASHBOARD = "analytics_dashboard"
    CUSTOM_REPORTS = "custom_reports"
    EXPORT_REPORTS = "export_reports"

    # Invoicing
    INVOICE_LU = "invoice_lu"
    INVOICE_EU_VAT = "invoice_eu_vat"
    INVOICE_BULK = "invoice_bulk"
    ACCOUNTING_EXPORT = "accounting_export"

    # Integrations
    LETZSHOP_SYNC = "letzshop_sync"
    API_ACCESS = "api_access"
    WEBHOOKS = "webhooks"
    CUSTOM_INTEGRATIONS = "custom_integrations"

    # Team
    SINGLE_USER = "single_user"
    TEAM_BASIC = "team_basic"
    TEAM_ROLES = "team_roles"
    AUDIT_LOG = "audit_log"

    # Branding
    BASIC_SHOP = "basic_shop"
    CUSTOM_DOMAIN = "custom_domain"
    WHITE_LABEL = "white_label"

    # Customers
    CUSTOMER_VIEW = "customer_view"
    CUSTOMER_EXPORT = "customer_export"
    CUSTOMER_MESSAGING = "customer_messaging"

    # CMS
    CMS_BASIC = "cms_basic"  # Basic CMS functionality (override defaults)
    CMS_CUSTOM_PAGES = "cms_custom_pages"  # Create custom pages beyond defaults
    CMS_UNLIMITED_PAGES = "cms_unlimited_pages"  # No page limit
    CMS_TEMPLATES = "cms_templates"  # Access to page templates
    CMS_SEO = "cms_seo"  # Advanced SEO features
    CMS_SCHEDULING = "cms_scheduling"  # Schedule page publish/unpublish
