from fastapi import Request, Query, Depends, Header, APIRouter, HTTPException
from fastapi.responses import JSONResponse
from pydantic import BaseModel
from typing import List, Optional
from utility.function import Function
from connectors.firebase.firebase import Firebase
from utility.token import Token
import os
from models.user import *

import logging
logging.basicConfig(level=logging.INFO)

fb = Firebase(host=os.environ.get("FIREBASE_HOST"))

router = APIRouter()

LOGGING_PREFIX = "api_user"

@router.post("/register",
        response_model=UserRegisterRespone,
        responses={
            400: {"model": ErrorResponse, "description": "Please registe before login"},
            401: {"model": ErrorResponse, "description": "Invalid credentials"},
            404: {"model": ErrorResponse, "description": "Wrong password!"},
            500: {"model": ErrorResponse, "description": "Internal server error"},
        },
        description="Register a new user",)
async def user_register(request: UserRegister):
    try:

        #Gen ID
        id = Function.text_to_numeric_token(request.email)
        request.user_id = id
        fb.db.reference().child(f'users/{id}').set(request.model_dump())

        token = Token()
        user = token.register(user_id=id)
        user['user_id'] = id
        user['status'] = 'ok'
        user['message'] = 'Success'
        return user
    
    except Exception as e:
        logging.error(f"Error parsing {LOGGING_PREFIX}: {e}")
        return JSONResponse(status_code=500, content={'status': 'error', 'message': str(e)})

@router.post(
        "/login",
        response_model=UserLoginRespone,
        responses={
            400: {"model": ErrorResponse, "description": "Please registe before login"},
            401: {"model": ErrorResponse, "description": "Invalid credentials"},
            404: {"model": ErrorResponse, "description": "Wrong password!"},
            500: {"model": ErrorResponse, "description": "Internal server error"},
        },
        description="User login"
        )
async def user_login(request: UserLogin):
    try:
        token = Token()
        data, code = token.login(request.email, request.password)
        if code != 200:
            return JSONResponse(
                status_code=code,
                content={
                    "status": "error", 
                    "message": data.get("message") if isinstance(data, dict) else str(data)
                }
            )
        
        return {
            "access_token": data["access_token"],
            "refresh_token": data["refresh_token"],
            "status": "ok",
            "message": "Success"
        }
    except Exception as e:
        logging.error(f"Error parsing {LOGGING_PREFIX}: {e}")
        return JSONResponse(status_code=500, content={'status': 'error', 'message': str(e)})
    
@router.post("/refresh",
        response_model=UserRefreshTokenRespone,
        responses={
            400: {"model": ErrorResponse},
            401: {"model": ErrorResponse},
            404: {"model": ErrorResponse},
            500: {"model": ErrorResponse},
        },
        description="Refresh access token")
async def user_refresh_token(request: Request):
    try:
        authorization = request.headers.get("Authorization")
        bearerB = authorization.replace("Bearer ", "")
        token = Token()
        data = token.new_access_token(bearerB)
        if data:
            data['status'] = 'ok'
            return data
        return JSONResponse(
                status_code=500,
                content={
                    "status": "error", 
                    "message": data.get("message") if isinstance(data, dict) else str(data)
                }
            )
    except Exception as e:
        logging.error(f"Error parsing {LOGGING_PREFIX}: {e}")
        return JSONResponse(status_code=500, content={'status': 'error', 'message': str(e)})

#Property
@router.post("/property", response_model=UserAssignPropertyRespone, description="Add property to user")
async def add_proeprty_to_user(request: UserAssignProperty, defualt_request: Request):
    user_id = Function.getUserID(defualt_request)
    try:
        for pr in request.properties:
            check = fb.db.reference().child(f"users/{user_id}/property/{pr}").get(shallow=True) #check
            if not check:
                fb.db.reference().child(f"users/{user_id}/property/").set(pr)
        return {"status":"ok", 'message': 'Success'}

    except Exception as e:
        logging.error(f"Error parsing {LOGGING_PREFIX}: {e}")
        return JSONResponse(status_code=500, content={'status': 'error', 'message': str(e)})
    
@router.get("/property", response_model=GetUserPropertyRespone, description="Get property of user")
async def get_proeprty_of_user(
    default_request: Request,
    property_id: str = Query(..., description="Property ID or 'all' to get all properties")
):
    try:
        headers = default_request.headers
        user_id = Function.getUserIDFromHeader(headers)
        if property_id != 'all':
            data = []
            property_details = {
                "property_id" : property_id,
                "property_name" : fb.get_by_child(f"property/{property_id}/name")
            }
            data.append(property_details)
            if data:
                return {'status': 'ok', 'message': 'Success', 'data': data}
            return JSONResponse(status_code=404,content={"status": "not_found", "message": 'Not found'})
        else:
            data = []
            property_list = fb.db.reference().child(f"users/{user_id}/property/").get(shallow=True)
            property_id_list = list(property_list)
            
            for pr in property_id_list:
                property_details = {
                    "property_id" : pr,
                    "property_name" : fb.get_by_child(f"property/{pr}/name")
                }
                data.append(property_details)
            if data:
                return {'status': 'ok', 'message': 'Success', 'data': data}
            return JSONResponse(status_code=404,content={"status": "not_found", "message": 'Not found'})
    except Exception as e:
        logging.error(f"Error parsing {LOGGING_PREFIX}_{default_request.path_params}: {e}")
        return JSONResponse(status_code=500, content={'status': 'error', 'message': str(e)})

#Channel