from fastapi import FastAPI, HTTPException, Depends, Query, Path, Body, status, APIRouter, Request, BackgroundTasks # type: ignore
from database import RedisDatabase
import hashlib
from logger import logger
from datetime import datetime, timezone
from user_agents import parse  # type: ignore
import json

class DeviceManager:
    def __init__(self, database: RedisDatabase):
        self.database = database
    
    def generate_device_fingerprint(self, request: Request) -> str:
        """Generate device fingerprint from request"""
        user_agent = request.headers.get("user-agent", "")
        ip_address = request.client.host if request.client else "unknown"
        accept_language = request.headers.get("accept-language", "")
        
        # Create fingerprint
        fingerprint_data = f"{user_agent}|{accept_language}"
        fingerprint = hashlib.sha256(fingerprint_data.encode()).hexdigest()[:16]
        
        return fingerprint
    
    def parse_device_info(self, request: Request) -> dict:
        """Parse device information from request"""
        user_agent_string = request.headers.get("user-agent", "")
        user_agent = parse(user_agent_string)
        
        return {
            "device_id": self.generate_device_fingerprint(request),
            "device_name": f"{user_agent.browser.family} on {user_agent.os.family}",
            "browser": user_agent.browser.family,
            "browser_version": user_agent.browser.version_string,
            "os": user_agent.os.family,
            "os_version": user_agent.os.version_string,
            "ip_address": request.client.host if request.client else "unknown",
            "user_agent": user_agent_string
        }
    
    async def is_trusted_device(self, user_id: str, device_id: str) -> bool:
        """Check if device is trusted for user"""
        try:
            key = f"trusted_device:{user_id}:{device_id}"
            exists = await self.database.redis.exists(key)
            return exists > 0
        except Exception as e:
            logger.error(f"Error checking trusted device: {e}")
            return False
    
    async def add_trusted_device(self, user_id: str, device_id: str, device_info: dict):
        """Add device to trusted devices"""
        try:
            key = f"trusted_device:{user_id}:{device_id}"
            device_data = {
                **device_info,
                "added_at": datetime.now(timezone.utc).isoformat(),
                "last_used": datetime.now(timezone.utc).isoformat()
            }
            
            # Store for 90 days
            await self.database.redis.setex(
                key, 
                90 * 24 * 60 * 60,  # 90 days in seconds
                json.dumps(device_data, default=str)
            )
            
            logger.info(f"🔒 Added trusted device {device_id} for user {user_id}")
        except Exception as e:
            logger.error(f"Error adding trusted device: {e}")
    
    async def update_device_last_used(self, user_id: str, device_id: str):
        """Update last used timestamp for device"""
        try:
            key = f"trusted_device:{user_id}:{device_id}"
            device_data = await self.database.redis.get(key)
            if device_data:
                device_info = json.loads(device_data)
                device_info["last_used"] = datetime.now(timezone.utc).isoformat()
                await self.database.redis.setex(
                    key,
                    90 * 24 * 60 * 60,  # Reset 90 day expiry
                    json.dumps(device_info, default=str)
                )
        except Exception as e:
            logger.error(f"Error updating device last used: {e}")
