# app/modules/cms/services/cms_features.py
"""
CMS feature provider for the billing feature system.

Declares CMS-related billable features (page limits, SEO, scheduling, templates)
and provides usage tracking queries for feature gating. Quantitative features
track content page counts at both store and merchant levels.
"""

from __future__ import annotations

import logging
from typing import TYPE_CHECKING

from sqlalchemy import func

from app.modules.contracts.features import (
    FeatureDeclaration,
    FeatureScope,
    FeatureType,
    FeatureUsage,
)

if TYPE_CHECKING:
    from sqlalchemy.orm import Session

logger = logging.getLogger(__name__)


class CmsFeatureProvider:
    """Feature provider for the CMS module.

    Declares:
    - cms_pages_limit: quantitative per-store limit on total content pages
    - cms_custom_pages_limit: quantitative per-store limit on custom pages
    - cms_basic: binary merchant-level feature for basic CMS editing
    - cms_seo: binary merchant-level feature for SEO metadata
    - cms_scheduling: binary merchant-level feature for content scheduling
    - cms_templates: binary merchant-level feature for page templates
    """

    @property
    def feature_category(self) -> str:
        return "cms"

    def get_feature_declarations(self) -> list[FeatureDeclaration]:
        return [
            FeatureDeclaration(
                code="cms_pages_limit",
                name_key="cms.features.cms_pages_limit.name",
                description_key="cms.features.cms_pages_limit.description",
                category="cms",
                feature_type=FeatureType.QUANTITATIVE,
                scope=FeatureScope.STORE,
                default_limit=5,
                unit_key="cms.features.cms_pages_limit.unit",
                ui_icon="file-text",
                display_order=10,
            ),
            FeatureDeclaration(
                code="cms_custom_pages_limit",
                name_key="cms.features.cms_custom_pages_limit.name",
                description_key="cms.features.cms_custom_pages_limit.description",
                category="cms",
                feature_type=FeatureType.QUANTITATIVE,
                scope=FeatureScope.STORE,
                default_limit=2,
                unit_key="cms.features.cms_custom_pages_limit.unit",
                ui_icon="layout",
                display_order=20,
            ),
            FeatureDeclaration(
                code="cms_basic",
                name_key="cms.features.cms_basic.name",
                description_key="cms.features.cms_basic.description",
                category="cms",
                feature_type=FeatureType.BINARY,
                scope=FeatureScope.MERCHANT,
                ui_icon="edit-3",
                display_order=30,
            ),
            FeatureDeclaration(
                code="cms_seo",
                name_key="cms.features.cms_seo.name",
                description_key="cms.features.cms_seo.description",
                category="cms",
                feature_type=FeatureType.BINARY,
                scope=FeatureScope.MERCHANT,
                ui_icon="search",
                display_order=40,
            ),
            FeatureDeclaration(
                code="cms_scheduling",
                name_key="cms.features.cms_scheduling.name",
                description_key="cms.features.cms_scheduling.description",
                category="cms",
                feature_type=FeatureType.BINARY,
                scope=FeatureScope.MERCHANT,
                ui_icon="calendar",
                display_order=50,
            ),
            FeatureDeclaration(
                code="cms_templates",
                name_key="cms.features.cms_templates.name",
                description_key="cms.features.cms_templates.description",
                category="cms",
                feature_type=FeatureType.BINARY,
                scope=FeatureScope.MERCHANT,
                ui_icon="grid",
                display_order=60,
            ),
        ]

    def get_store_usage(
        self,
        db: Session,
        store_id: int,
    ) -> list[FeatureUsage]:
        from app.modules.cms.models.content_page import ContentPage

        # Count all content pages for this store
        pages_count = (
            db.query(func.count(ContentPage.id))
            .filter(ContentPage.store_id == store_id)
            .scalar()
            or 0
        )

        # Count custom pages (store overrides that are not platform or default pages)
        custom_count = (
            db.query(func.count(ContentPage.id))
            .filter(
                ContentPage.store_id == store_id,
                ContentPage.is_custom == True,  # noqa: E712
            )
            .scalar()
            or 0
        )

        return [
            FeatureUsage(
                feature_code="cms_pages_limit",
                current_count=pages_count,
                label="Content pages",
            ),
            FeatureUsage(
                feature_code="cms_custom_pages_limit",
                current_count=custom_count,
                label="Custom pages",
            ),
        ]

    def get_merchant_usage(
        self,
        db: Session,
        merchant_id: int,
        platform_id: int,
    ) -> list[FeatureUsage]:
        from app.modules.cms.models.content_page import ContentPage
        from app.modules.tenancy.services.platform_service import platform_service
        from app.modules.tenancy.services.store_service import store_service

        # Get store IDs for this merchant that are on the given platform
        merchant_stores = store_service.get_stores_by_merchant_id(db, merchant_id)
        store_ids = []
        for s in merchant_stores:
            pids = platform_service.get_active_platform_ids_for_store(db, s.id)
            if platform_id in pids:
                store_ids.append(s.id)

        if not store_ids:
            return [
                FeatureUsage(feature_code="cms_pages_limit", current_count=0, label="Content pages"),
                FeatureUsage(feature_code="cms_custom_pages_limit", current_count=0, label="Custom pages"),
            ]

        # Aggregate content pages across all merchant's stores on this platform
        pages_count = (
            db.query(func.count(ContentPage.id))
            .filter(ContentPage.store_id.in_(store_ids))
            .scalar()
            or 0
        )

        custom_count = (
            db.query(func.count(ContentPage.id))
            .filter(
                ContentPage.store_id.in_(store_ids),
                ContentPage.is_custom == True,  # noqa: E712
            )
            .scalar()
            or 0
        )

        return [
            FeatureUsage(
                feature_code="cms_pages_limit",
                current_count=pages_count,
                label="Content pages",
            ),
            FeatureUsage(
                feature_code="cms_custom_pages_limit",
                current_count=custom_count,
                label="Custom pages",
            ),
        ]


# Singleton instance for module registration
cms_feature_provider = CmsFeatureProvider()

__all__ = [
    "CmsFeatureProvider",
    "cms_feature_provider",
]
