from typing import Any, Dict, Optional, Tuple, List
from app.core.database.operations import get_items_from_database
from app.core.security import create_code, check_validation_code, generate_tokens, remove_refresh_token
from app.utils.email import send_email


# Generates a 4-digit code, stores it and sends it to the hub user via email
def generate_hub_validation_code_service(
        id: int) -> Tuple[Dict[str, Any], List[int]]:
    if not id:
        return ({'error': 'Neophodan je ID korisnika'}, [400])

    validation_code = create_code(user_id=id)

    # Get user email
    response = get_items_from_database(
        table_name='hub_users', conditions={'id': id})
    # If error or empty list
    if 'error' in response:
        return (response, [500])
    if not response or not isinstance(
            response, list) or not response[0].get('email'):
        return {'error': 'Email korisnika nije pronađen'}, [404]

    user_email = response[0]['email']

    # Send code via email
    response = send_email(
        receiver_email=user_email,
        message_body=f'Vaš login kod je {validation_code}',
        message_subject='Vaš kod za PropertyHUB login'
    )
    if 'error' in response:
        return (response, [500])

    return ({}, [200])


# Checks if the code matches the one from the email, generates tokens for
# the user
def validate_hub_login_service(
        submitted_code: str, id: int) -> Tuple[Dict[str, Any], List[int], Optional[Dict[str, Any]]]:
    if not id or not submitted_code:
        return ({'error': 'Neophodni su kod i id korisnika'}, [400], None)

    # Check user's code
    response, status_codes = check_validation_code(
        submitted_code=submitted_code, user_id=id)
    if 'error' in response:
        return (response, status_codes, None)

    # Fetch user role
    response = get_items_from_database(
        table_name='hub_users', conditions={'id': id})
    # If error or empty list
    if 'error' in response:
        return (response, [500], None)
    if not response or not isinstance(
            response, list) or not response[0].get('role'):
        return ({'error': 'Uloga korisnika nije pronađena'}, [404], None)

    user_role = response[0]['role']

    # Generate Access and Refresh tokens
    response, status_codes, tokens = generate_tokens(
        user_role=user_role, user_id=id)

    return (response, status_codes, tokens)


# Logs out the user by removing the Refresh token from Redis and clearing
# cookies
def logout_hub_user_service(
        refresh_token: str) -> Tuple[Dict[str, Any], List[int], Optional[Dict[str, Any]]]:
    if not refresh_token:
        return ({'error': 'Nije dohvaćen refresh token'}, [401], None)

    response, status_codes, tokens = remove_refresh_token(
        refresh_token=refresh_token)

    return (response, status_codes, tokens)
