"""
Licensing Endpoints - License validation, activation, and management.

Updated with PostgreSQL backend and flexible device binding.
"""

from fastapi import APIRouter, HTTPException, Header
from pydantic import BaseModel
from typing import Optional, List
import structlog
import uuid

from app.db.postgres import db
from app.core.auth import jwt_auth

logger = structlog.get_logger(__name__)

router = APIRouter()


class ActivateRequest(BaseModel):
    """Device activation request."""
    license_key: str
    email: str
    hardware_id: str
    device_name: Optional[str] = None


class ActivateResponse(BaseModel):
    """Activation response."""
    status: str
    devices_used: int
    max_devices: int


class LicenseStatusResponse(BaseModel):
    """License status response."""
    license_key: str
    email: str
    tier: str
    period: str
    status: str
    expires_at: Optional[str]
    devices: List[dict]
    max_devices: int


class UsageStatsResponse(BaseModel):
    """Usage statistics response."""
    files_cleaned: int
    bytes_processed: int
    last_used_at: Optional[str]


@router.post("/activate", response_model=ActivateResponse)
async def activate_license(request: ActivateRequest):
    """
    Activate license on a device (flexible binding - allows 2-3 devices).
    """
    logger.info("activation_attempt", email=request.email, device=request.device_name)
    
    # 1. Validate license exists and matches email
    license_row = await db.fetchrow(
        """
        SELECT license_key, email, tier, status, max_devices
        FROM licenses
        WHERE license_key = $1 AND email = $2
        """,
        request.license_key,
        request.email
    )
    
    if not license_row:
        raise HTTPException(status_code=404, detail="License not found or email mismatch")
    
    if license_row['status'] != 'active':
        raise HTTPException(status_code=403, detail=f"License is {license_row['status']}")
    
    # 2. Check current device count
    device_count = await db.fetchval(
        "SELECT COUNT(*) FROM device_activations WHERE license_key = $1",
        request.license_key
    )
    
    # 3. Check if this device is already registered
    existing_device = await db.fetchrow(
        """
        SELECT id FROM device_activations
        WHERE license_key = $1 AND hardware_id = $2
        """,
        request.license_key,
        request.hardware_id
    )
    
    if existing_device:
        # Update last seen
        await db.execute(
            """
            UPDATE device_activations
            SET last_seen_at = NOW()
            WHERE license_key = $1 AND hardware_id = $2
            """,
            request.license_key,
            request.hardware_id
        )
        logger.info("device_reactivated", email=request.email)
        return ActivateResponse(
            status="reactivated",
            devices_used=device_count,
            max_devices=license_row['max_devices']
        )
    
    # 4. Check if we can add a new device
    if device_count >= license_row['max_devices']:
        raise HTTPException(
            status_code=403,
            detail=f"License already activated on {device_count} devices. Maximum is {license_row['max_devices']}. Contact support to add more devices."
        )
    
    # 5. Register new device
    await db.execute(
        """
        INSERT INTO device_activations (license_key, hardware_id, device_name)
        VALUES ($1, $2, $3)
        """,
        request.license_key,
        request.hardware_id,
        request.device_name or "Unknown Device"
    )
    
    logger.info("device_activated", email=request.email, devices_used=device_count + 1)
    
    return ActivateResponse(
        status="activated",
        devices_used=device_count + 1,
        max_devices=license_row['max_devices']
    )


@router.get("/status", response_model=LicenseStatusResponse)
async def get_license_status(authorization: Optional[str] = Header(None)):
    """
    Get license status (requires JWT token).
    """
    if not authorization or not authorization.startswith("Bearer "):
        raise HTTPException(status_code=401, detail="Missing or invalid authorization header")
    
    token = authorization.replace("Bearer ", "")
    payload = jwt_auth.verify_token(token)
    
    if not payload:
        raise HTTPException(status_code=401, detail="Invalid or expired token")
    
    license_key = payload['license_key']
    
    # Get license info
    license_row = await db.fetchrow(
        """
        SELECT license_key, email, tier, period, status, expires_at, max_devices
        FROM licenses
        WHERE license_key = $1
        """,
        license_key
    )
    
    if not license_row:
        raise HTTPException(status_code=404, detail="License not found")
    
    # Get devices
    devices = await db.fetch(
        """
        SELECT hardware_id, device_name, activated_at, last_seen_at
        FROM device_activations
        WHERE license_key = $1
        ORDER BY activated_at DESC
        """,
        license_key
    )
    
    return LicenseStatusResponse(
        license_key=license_row['license_key'],
        email=license_row['email'],
        tier=license_row['tier'],
        period=license_row['period'],
        status=license_row['status'],
        expires_at=str(license_row['expires_at']) if license_row['expires_at'] else None,
        devices=[dict(d) for d in devices],
        max_devices=license_row['max_devices']
    )


@router.get("/usage", response_model=UsageStatsResponse)
async def get_usage_stats(authorization: Optional[str] = Header(None)):
    """
    Get usage statistics (requires JWT token).
    """
    if not authorization or not authorization.startswith("Bearer "):
        raise HTTPException(status_code=401, detail="Missing authorization header")
    
    token = authorization.replace("Bearer ", "")
    payload = jwt_auth.verify_token(token)
    
    if not payload:
        raise HTTPException(status_code=401, detail="Invalid token")
    
    license_key = payload['license_key']
    
    # Get usage stats
    stats = await db.fetchrow(
        """
        SELECT files_cleaned, bytes_processed, last_used_at
        FROM usage_stats
        WHERE license_key = $1
        """,
        license_key
    )
    
    if not stats:
        # Create initial stats row
        await db.execute(
            "INSERT INTO usage_stats (license_key) VALUES ($1)",
            license_key
        )
        return UsageStatsResponse(
            files_cleaned=0,
            bytes_processed=0,
            last_used_at=None
        )
    
    return UsageStatsResponse(
        files_cleaned=stats['files_cleaned'],
        bytes_processed=stats['bytes_processed'],
        last_used_at=str(stats['last_used_at']) if stats['last_used_at'] else None
    )
