from fastapi import APIRouter, HTTPException, Request, Depends
from sqlalchemy.ext.asyncio import AsyncSession
from datetime import datetime
import time
import uuid
import json
from pydantic import ValidationError
from app.api.v1.crypto_api import decrypt_data, encrypt_data
from app.schemas.guest import GuestLoginPayload
from app.models.user_device import UserDevice
from app.utils.responses import custom_response
from app.services.user_device_login_service import update_or_create_login
from app.services.user_service import get_user_device_data_guest
from app.core.jwt import encode_jwt_token
from app.core.logging import logger
from app.crud import crud
from app.db.session import get_db
from app.core.check_subscription import check_active_subscription_guest


router = APIRouter()

@router.post("/guestlogin")
async def guest_login(request: Request, db: AsyncSession = Depends(get_db)):
    logger.info("Received request for guest login.")
    try:
        encrypted_data: bytes = await request.body()
        if not encrypted_data:
            logger.warning("Empty request body received.")
            return custom_response(400, message="Empty request body")
        
        logger.debug(f"Encrypted request body: {encrypted_data}")

        try:
            decrypted_text: str = decrypt_data(encrypted_data)
            logger.debug(f"Decrypted text: {decrypted_text}")
        except Exception as e:
            logger.error(f"Decryption failed for guest login: {str(e)}", exc_info=True)
            return custom_response(400, message=f"Decryption failed: {str(e)}")

        try:
            data = decrypted_text
        except json.JSONDecodeError:
            logger.warning(f"Decrypted payload is not valid JSON: {decrypted_text}")
            return custom_response(400, message="Decrypted payload is not valid JSON")

        try:
            payload = GuestLoginPayload.model_validate(data)
            logger.info(f"Payload validated for device_unique_id: {payload.device_unique_id}")
        except ValidationError as ve:
            logger.warning(f"Validation failed for guest login payload. Errors: {ve.errors()}")
            return custom_response(422, data=ve.errors(), message="Validation failed")
        
        # Use the functions from the crud.py module
        try:
            # SELECT: Use the generic get_by_unique_id function to check for the device.
            device = await crud.get_by_unique_id(
                db=db,
                model=UserDevice,
                unique_id_column="device_unique_id",
                unique_id_value=payload.device_unique_id
            )

            if device:
                # UPDATE: Use the generic update function
                updated_device = await crud.update(
                    db=db,
                    db_record=device,
                    updated_data=payload
                )
                logger.info(f"Updated existing device with ID: {updated_device.user_device_id}")
                user_device = updated_device
            else:
                # CREATE: Use the generic create function
                created_device = await crud.create(
                    db=db,
                    model=UserDevice,
                    schema=payload
                )
                logger.info(f"Created new device with ID: {created_device.user_device_id}")
                user_device = created_device

        except Exception as e:
            await db.rollback()
            logger.error(f"Database error during device upsert: {e}", exc_info=True)
            return custom_response(500, message=f"Database error during device upsert: {e}")
        
        # NEW: create/update login row after device upsert
        try:
            # user_id is None for guest
            await update_or_create_login(user_device.user_device_id, None, request, db)
            logger.info(f"Login record created/updated for device ID: {user_device.user_device_id}")
        except Exception as e:
            await db.rollback()
            logger.error(f"Database error during login upsert: {e}", exc_info=True)
            return custom_response(500, data=[], message=f"Database error during login upsert: {e}")
        
        try:
            user_device_data = await get_user_device_data_guest(user_device.device_unique_id, db)
        except Exception as e:
            await db.rollback()
            logger.error(f"Error fetching user device data: {str(e)}", exc_info=True)
            return custom_response(500, message=f"Error fetching user device data: {str(e)}")
        

        #check subscription of guest user
        check_sub_guest = await check_active_subscription_guest(device_unique_id=user_device.device_unique_id, db=db)


        print("check_sub_guest ============",check_sub_guest)

        print("user_device_data:", user_device_data)

        if check_sub_guest:
            user_device_data['have_active_subscription'] = True
        else:
            user_device_data['have_active_subscription'] = False
        token = encode_jwt_token(user_device_data)
        print("token:", token)  # Debug log
        user_device_data["token"] = token
        logger.info("Successfully generated JWT token.")
        
        return custom_response(200, data=user_device_data, message="Login successful")

    except HTTPException as e:
        msg = e.detail if isinstance(e.detail, str) else "HTTP error"
        logger.warning(f"HTTP exception: {msg}")
        return custom_response(e.status_code, message=msg)
    except Exception as e:
        logger.error(f"Internal error while processing guest login: {e}", exc_info=True)
        return custom_response(500, message=f"Internal error while parsing encrypted payload: {e}")
