"""add features table and seed data

Revision ID: n2c3d4e5f6a7
Revises: ba2c0ce78396
Create Date: 2025-12-31 10:00:00.000000

"""

import json
from collections.abc import Sequence

import sqlalchemy as sa

from alembic import op

# revision identifiers, used by Alembic.
revision: str = "n2c3d4e5f6a7"
down_revision: str | None = "ba2c0ce78396"
branch_labels: str | Sequence[str] | None = None
depends_on: str | Sequence[str] | None = None


# ============================================================================
# Feature Definitions
# ============================================================================
# category, code, name, description, ui_location, ui_icon, ui_route, display_order
FEATURES = [
    # Orders (category: orders)
    ("orders", "order_management", "Order Management", "View and manage orders", "sidebar", "clipboard-list", "/vendor/{code}/orders", 1),
    ("orders", "order_bulk_actions", "Bulk Order Actions", "Process multiple orders at once", "inline", None, None, 2),
    ("orders", "order_export", "Order Export", "Export orders to CSV/Excel", "inline", "download", None, 3),
    ("orders", "automation_rules", "Automation Rules", "Automatic order processing rules", "sidebar", "cog", "/vendor/{code}/automation", 4),

    # Inventory (category: inventory)
    ("inventory", "inventory_basic", "Basic Inventory", "Track product stock levels", "sidebar", "cube", "/vendor/{code}/inventory", 1),
    ("inventory", "inventory_locations", "Warehouse Locations", "Manage multiple warehouse locations", "inline", "map-pin", None, 2),
    ("inventory", "inventory_purchase_orders", "Purchase Orders", "Create and manage purchase orders", "sidebar", "shopping-cart", "/vendor/{code}/purchase-orders", 3),
    ("inventory", "low_stock_alerts", "Low Stock Alerts", "Get notified when stock is low", "inline", "bell", None, 4),

    # Analytics (category: analytics)
    ("analytics", "basic_reports", "Basic Reports", "Essential sales and order reports", "sidebar", "chart-pie", "/vendor/{code}/reports", 1),
    ("analytics", "analytics_dashboard", "Analytics Dashboard", "Advanced analytics with charts and trends", "sidebar", "chart-bar", "/vendor/{code}/analytics", 2),
    ("analytics", "custom_reports", "Custom Reports", "Build custom report configurations", "inline", "document-report", None, 3),
    ("analytics", "export_reports", "Export Reports", "Export reports to various formats", "inline", "download", None, 4),

    # Invoicing (category: invoicing)
    ("invoicing", "invoice_lu", "Luxembourg Invoicing", "Generate compliant Luxembourg invoices", "sidebar", "document-text", "/vendor/{code}/invoices", 1),
    ("invoicing", "invoice_eu_vat", "EU VAT Support", "Handle EU VAT for cross-border sales", "inline", "globe", None, 2),
    ("invoicing", "invoice_bulk", "Bulk Invoicing", "Generate invoices in bulk", "inline", "document-duplicate", None, 3),
    ("invoicing", "accounting_export", "Accounting Export", "Export to accounting software formats", "inline", "calculator", None, 4),

    # Integrations (category: integrations)
    ("integrations", "letzshop_sync", "Letzshop Sync", "Sync orders and products with Letzshop", "settings", "refresh", None, 1),
    ("integrations", "api_access", "API Access", "REST API access for custom integrations", "settings", "code", "/vendor/{code}/settings/api", 2),
    ("integrations", "webhooks", "Webhooks", "Receive real-time event notifications", "settings", "lightning-bolt", "/vendor/{code}/settings/webhooks", 3),
    ("integrations", "custom_integrations", "Custom Integrations", "Connect with any third-party service", "settings", "puzzle", None, 4),

    # Team (category: team)
    ("team", "single_user", "Single User", "One user account", "api", None, None, 1),
    ("team", "team_basic", "Team Access", "Invite team members", "sidebar", "users", "/vendor/{code}/team", 2),
    ("team", "team_roles", "Team Roles", "Role-based permissions for team members", "inline", "shield-check", None, 3),
    ("team", "audit_log", "Audit Log", "Track all user actions", "sidebar", "clipboard-check", "/vendor/{code}/audit-log", 4),

    # Branding (category: branding)
    ("branding", "basic_shop", "Basic Shop", "Your shop on the platform", "api", None, None, 1),
    ("branding", "custom_domain", "Custom Domain", "Use your own domain name", "settings", "globe-alt", None, 2),
    ("branding", "white_label", "White Label", "Remove platform branding entirely", "settings", "color-swatch", None, 3),

    # Customers (category: customers)
    ("customers", "customer_view", "Customer View", "View customer information", "sidebar", "user-group", "/vendor/{code}/customers", 1),
    ("customers", "customer_export", "Customer Export", "Export customer data", "inline", "download", None, 2),
    ("customers", "customer_messaging", "Customer Messaging", "Send messages to customers", "inline", "chat", None, 3),
]

# ============================================================================
# Tier Feature Assignments
# ============================================================================
# tier_code -> list of feature codes
TIER_FEATURES = {
    "essential": [
        "order_management",
        "inventory_basic",
        "basic_reports",
        "invoice_lu",
        "letzshop_sync",
        "single_user",
        "basic_shop",
        "customer_view",
    ],
    "professional": [
        # All Essential features
        "order_management",
        "order_bulk_actions",
        "order_export",
        "inventory_basic",
        "inventory_locations",
        "inventory_purchase_orders",
        "low_stock_alerts",
        "basic_reports",
        "invoice_lu",
        "invoice_eu_vat",
        "letzshop_sync",
        "team_basic",
        "basic_shop",
        "customer_view",
        "customer_export",
    ],
    "business": [
        # All Professional features
        "order_management",
        "order_bulk_actions",
        "order_export",
        "automation_rules",
        "inventory_basic",
        "inventory_locations",
        "inventory_purchase_orders",
        "low_stock_alerts",
        "basic_reports",
        "analytics_dashboard",
        "custom_reports",
        "export_reports",
        "invoice_lu",
        "invoice_eu_vat",
        "invoice_bulk",
        "accounting_export",
        "letzshop_sync",
        "api_access",
        "webhooks",
        "team_basic",
        "team_roles",
        "audit_log",
        "basic_shop",
        "custom_domain",
        "customer_view",
        "customer_export",
        "customer_messaging",
    ],
    "enterprise": [
        # All features
        "order_management",
        "order_bulk_actions",
        "order_export",
        "automation_rules",
        "inventory_basic",
        "inventory_locations",
        "inventory_purchase_orders",
        "low_stock_alerts",
        "basic_reports",
        "analytics_dashboard",
        "custom_reports",
        "export_reports",
        "invoice_lu",
        "invoice_eu_vat",
        "invoice_bulk",
        "accounting_export",
        "letzshop_sync",
        "api_access",
        "webhooks",
        "custom_integrations",
        "team_basic",
        "team_roles",
        "audit_log",
        "basic_shop",
        "custom_domain",
        "white_label",
        "customer_view",
        "customer_export",
        "customer_messaging",
    ],
}

# Minimum tier for each feature (for upgrade prompts)
# Maps feature_code -> tier_code
MINIMUM_TIER = {
    # Essential
    "order_management": "essential",
    "inventory_basic": "essential",
    "basic_reports": "essential",
    "invoice_lu": "essential",
    "letzshop_sync": "essential",
    "single_user": "essential",
    "basic_shop": "essential",
    "customer_view": "essential",
    # Professional
    "order_bulk_actions": "professional",
    "order_export": "professional",
    "inventory_locations": "professional",
    "inventory_purchase_orders": "professional",
    "low_stock_alerts": "professional",
    "invoice_eu_vat": "professional",
    "team_basic": "professional",
    "customer_export": "professional",
    # Business
    "automation_rules": "business",
    "analytics_dashboard": "business",
    "custom_reports": "business",
    "export_reports": "business",
    "invoice_bulk": "business",
    "accounting_export": "business",
    "api_access": "business",
    "webhooks": "business",
    "team_roles": "business",
    "audit_log": "business",
    "custom_domain": "business",
    "customer_messaging": "business",
    # Enterprise
    "custom_integrations": "enterprise",
    "white_label": "enterprise",
}


def upgrade() -> None:
    # Create features table
    op.create_table(
        "features",
        sa.Column("id", sa.Integer(), nullable=False),
        sa.Column("code", sa.String(50), nullable=False),
        sa.Column("name", sa.String(100), nullable=False),
        sa.Column("description", sa.Text(), nullable=True),
        sa.Column("category", sa.String(50), nullable=False),
        sa.Column("ui_location", sa.String(50), nullable=True),
        sa.Column("ui_icon", sa.String(50), nullable=True),
        sa.Column("ui_route", sa.String(100), nullable=True),
        sa.Column("ui_badge_text", sa.String(20), nullable=True),
        sa.Column("minimum_tier_id", sa.Integer(), nullable=True),
        sa.Column("is_active", sa.Boolean(), nullable=False, default=True),
        sa.Column("is_visible", sa.Boolean(), nullable=False, default=True),
        sa.Column("display_order", sa.Integer(), nullable=False, default=0),
        sa.Column("created_at", sa.DateTime(), nullable=False),
        sa.Column("updated_at", sa.DateTime(), nullable=False),
        sa.ForeignKeyConstraint(["minimum_tier_id"], ["subscription_tiers.id"]),
        sa.PrimaryKeyConstraint("id"),
    )
    op.create_index("ix_features_code", "features", ["code"], unique=True)
    op.create_index("ix_features_category", "features", ["category"], unique=False)
    op.create_index("idx_feature_category_order", "features", ["category", "display_order"])
    op.create_index("idx_feature_active_visible", "features", ["is_active", "is_visible"])

    # Get connection for data operations
    conn = op.get_bind()

    # Get tier IDs
    tier_ids = {}
    result = conn.execute(sa.text("SELECT id, code FROM subscription_tiers"))
    for row in result:
        tier_ids[row[1]] = row[0]

    # Insert features
    sa.func.now()
    for category, code, name, description, ui_location, ui_icon, ui_route, display_order in FEATURES:
        minimum_tier_code = MINIMUM_TIER.get(code)
        minimum_tier_id = tier_ids.get(minimum_tier_code) if minimum_tier_code else None

        conn.execute(
            sa.text("""
                INSERT INTO features (code, name, description, category, ui_location, ui_icon, ui_route,
                                      minimum_tier_id, is_active, is_visible, display_order, created_at, updated_at)
                VALUES (:code, :name, :description, :category, :ui_location, :ui_icon, :ui_route,
                        :minimum_tier_id, true, true, :display_order, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
            """),
            {
                "code": code,
                "name": name,
                "description": description,
                "category": category,
                "ui_location": ui_location,
                "ui_icon": ui_icon,
                "ui_route": ui_route,
                "minimum_tier_id": minimum_tier_id,
                "display_order": display_order,
            },
        )

    # Update subscription_tiers with feature arrays
    for tier_code, features in TIER_FEATURES.items():
        features_json = json.dumps(features)
        conn.execute(
            sa.text("UPDATE subscription_tiers SET features = :features WHERE code = :code"),
            {"features": features_json, "code": tier_code},
        )


def downgrade() -> None:
    # Clear features from subscription_tiers
    conn = op.get_bind()
    conn.execute(sa.text("UPDATE subscription_tiers SET features = '[]'"))

    # Drop features table
    op.drop_index("idx_feature_active_visible", table_name="features")
    op.drop_index("idx_feature_category_order", table_name="features")
    op.drop_index("ix_features_category", table_name="features")
    op.drop_index("ix_features_code", table_name="features")
    op.drop_table("features")
