import json
import os
from hashlib import blake2b
from http.cookies import SimpleCookie

import jwt
from jwt.exceptions import PyJWTError

ACAO, ACAC = 'Access-Control-Allow-Origin', 'Access-Control-Allow-Credentials'


def validate_jwt(encoded_jwt, secret):
    try:
        return 200, jwt.decode(encoded_jwt, secret, algorithms='HS256')
    except PyJWTError as e:
        return 401, str(e)


def read_cookie(cookie, cookie_name):
    cookie = SimpleCookie(cookie)
    
    return cookie[cookie_name].value


def origin_verification(headers):
    allowed_origins = ['http://localhost:5173', 'https://stockemy.in', 'https://oms.stockemy.in']
    origin = headers.get('origin') or headers.get('Origin')
    
    if origin not in allowed_origins:
        code, message, origin = 401, 'Invalid origin', '*'
    else:
        code, message, origin = 200, 'Valid origin', origin
    
    return code, message, origin


def request_verification_flow(headers, body=None):
    if body is not None:
        body = json.loads(body)
        
        if body['marker'] != 1421185:
            return {'statusCode': 406, 'body': json.dumps({'message': 'Invalid marker'}),
                    'headers': {ACAO: '*', ACAC: True}}
        else:
            return 'dummy_token', 'dummy_origin'
    
    code, message, origin = origin_verification(headers)
    if code != 200:
        return {'statusCode': code, 'body': json.dumps({'message': message}), 'headers': {ACAO: origin, ACAC: True}}
    
    try:
        cookie = headers.get('cookie') or headers.get('Cookie')
        jwt_token = read_cookie(cookie, 'jwt_token')
    except KeyError:
        code, message = 401, 'Missing jwt_token in cookie'
        return {'statusCode': code, 'body': json.dumps({'message': message}), 'headers': {ACAO: origin, ACAC: True}}
    
    code, message = validate_jwt(jwt_token, secret=os.environ['JWT_KEY'])
    if code != 200:
        return {'statusCode': code, 'body': json.dumps({'message': message}), 'headers': {ACAO: origin, ACAC: True}}
    
    return message, origin


def get_hashed_password(password, key):
    h = blake2b(key=key.encode(), digest_size=16)
    h.update(password.encode())
    
    return h.hexdigest()
