"""
Feature Management Endpoints for Mitai Jinkendo

Admin-only CRUD for features registry.
User endpoint for feature usage overview (Phase 3).
"""
from typing import Optional
from datetime import datetime

from fastapi import APIRouter, HTTPException, Header, Depends

from db import get_db, get_cursor, r2d
from auth import require_admin, require_auth, check_feature_access
from routers.profiles import get_pid

router = APIRouter(prefix="/api/features", tags=["features"])


@router.get("")
def list_features(session: dict = Depends(require_admin)):
    """Admin: List all features."""
    with get_db() as conn:
        cur = get_cursor(conn)
        cur.execute("""
            SELECT * FROM features
            ORDER BY category, name
        """)
        return [r2d(r) for r in cur.fetchall()]


@router.post("")
def create_feature(data: dict, session: dict = Depends(require_admin)):
    """
    Admin: Create new feature.

    Required fields:
    - id: Feature ID (e.g., 'new_data_source')
    - name: Display name
    - category: 'data', 'ai', 'export', 'integration'
    - limit_type: 'count' or 'boolean'
    - reset_period: 'never', 'daily', 'monthly'
    - default_limit: INT or NULL (unlimited)
    """
    feature_id = data.get('id', '').strip()
    name = data.get('name', '').strip()
    description = data.get('description', '')
    category = data.get('category')
    limit_type = data.get('limit_type', 'count')
    reset_period = data.get('reset_period', 'never')
    default_limit = data.get('default_limit')

    if not feature_id or not name:
        raise HTTPException(400, "ID und Name fehlen")
    if category not in ['data', 'ai', 'export', 'integration']:
        raise HTTPException(400, "Ungültige Kategorie")
    if limit_type not in ['count', 'boolean']:
        raise HTTPException(400, "limit_type muss 'count' oder 'boolean' sein")
    if reset_period not in ['never', 'daily', 'monthly']:
        raise HTTPException(400, "Ungültiger reset_period")

    with get_db() as conn:
        cur = get_cursor(conn)

        # Check if ID already exists
        cur.execute("SELECT id FROM features WHERE id = %s", (feature_id,))
        if cur.fetchone():
            raise HTTPException(400, f"Feature '{feature_id}' existiert bereits")

        # Create feature
        cur.execute("""
            INSERT INTO features (
                id, name, description, category, limit_type, reset_period, default_limit
            )
            VALUES (%s, %s, %s, %s, %s, %s, %s)
        """, (feature_id, name, description, category, limit_type, reset_period, default_limit))

        conn.commit()

        return {"ok": True, "id": feature_id}


@router.put("/{feature_id}")
def update_feature(feature_id: str, data: dict, session: dict = Depends(require_admin)):
    """Admin: Update feature."""
    with get_db() as conn:
        cur = get_cursor(conn)

        updates = []
        values = []

        if 'name' in data:
            updates.append('name = %s')
            values.append(data['name'])
        if 'description' in data:
            updates.append('description = %s')
            values.append(data['description'])
        if 'default_limit' in data:
            updates.append('default_limit = %s')
            values.append(data['default_limit'])
        if 'active' in data:
            updates.append('active = %s')
            values.append(data['active'])

        if not updates:
            return {"ok": True}

        updates.append('updated = CURRENT_TIMESTAMP')
        values.append(feature_id)

        cur.execute(
            f"UPDATE features SET {', '.join(updates)} WHERE id = %s",
            values
        )
        conn.commit()

        return {"ok": True}


@router.delete("/{feature_id}")
def delete_feature(feature_id: str, session: dict = Depends(require_admin)):
    """Admin: Delete feature (soft-delete: set active=false)."""
    with get_db() as conn:
        cur = get_cursor(conn)
        cur.execute("UPDATE features SET active = false WHERE id = %s", (feature_id,))
        conn.commit()
        return {"ok": True}


@router.get("/{feature_id}/check-access")
def check_access(feature_id: str, session: dict = Depends(require_auth)):
    """
    User: Check if current user can access a feature.

    Returns:
    - allowed: bool - whether user can use the feature
    - limit: int|null - total limit (null = unlimited)
    - used: int - current usage
    - remaining: int|null - remaining uses (null = unlimited)
    - reason: str - why access is granted/denied
    """
    profile_id = session['profile_id']
    result = check_feature_access(profile_id, feature_id)
    return result


@router.get("/usage")
def get_feature_usage(x_profile_id: Optional[str]=Header(default=None), session: dict=Depends(require_auth)):
    """
    User: Get usage overview for all active features (Phase 3: Frontend Display).

    Returns list of all features with current usage, limits, and reset info.
    Automatically includes new features from database - no code changes needed.

    Response:
        [
            {
                "feature_id": "weight_entries",
                "name": "Gewichtseinträge",
                "description": "Anzahl der Gewichtseinträge",
                "category": "data",
                "limit_type": "count",
                "reset_period": "never",
                "used": 5,
                "limit": 10,
                "remaining": 5,
                "allowed": true,
                "reset_at": null
            },
            ...
        ]
    """
    pid = get_pid(x_profile_id)

    with get_db() as conn:
        cur = get_cursor(conn)

        # Get all active features (dynamic - picks up new features automatically)
        cur.execute("""
            SELECT id, name, description, category, limit_type, reset_period
            FROM features
            WHERE active = true
            ORDER BY category, name
        """)
        features = [r2d(r) for r in cur.fetchall()]

        result = []
        for feature in features:
            # Use existing check_feature_access to get usage and limits
            # This respects user overrides, tier limits, and feature defaults
            # Pass connection to avoid pool exhaustion
            access = check_feature_access(pid, feature['id'], conn)

            # Get reset date from user_feature_usage
            cur.execute("""
                SELECT reset_at
                FROM user_feature_usage
                WHERE profile_id = %s AND feature_id = %s
            """, (pid, feature['id']))
            usage_row = cur.fetchone()

            # Format reset_at as ISO string
            reset_at = None
            if usage_row and usage_row['reset_at']:
                if isinstance(usage_row['reset_at'], datetime):
                    reset_at = usage_row['reset_at'].isoformat()
                else:
                    reset_at = str(usage_row['reset_at'])

            result.append({
                'feature_id': feature['id'],
                'name': feature['name'],
                'description': feature.get('description'),
                'category': feature.get('category'),
                'limit_type': feature['limit_type'],
                'reset_period': feature['reset_period'],
                'used': access['used'],
                'limit': access['limit'],
                'remaining': access['remaining'],
                'allowed': access['allowed'],
                'reset_at': reset_at
            })

        return result
