import jwt
import os
from firebase.firebase import Firebase
from utility.function import Function
from datetime import datetime, timedelta

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

class Token:
    def __init__(self):
        self.token = os.environ.get("TOKEN_GENERATE")
        self.access_token_expiry_minutes  = 30
        self.refresh_token_expiry_days = 3

    def register(self, user_id, algorithm="HS256"):
        user = fb.get_by_child(f"users/{user_id}")
        user['exp'] = datetime.utcnow() + timedelta(minutes=self.access_token_expiry_minutes)
        user.pop("password")
        heders = {
            "alg": "HS256",
            "typ": "JWT",
            "kid": self.token
        }
        access_token = jwt.encode(user, self.token, algorithm, heders)
        refresh_payload = {
            "user_id": user_id,
            "type": "refresh",
            "exp": datetime.utcnow() + timedelta(days=self.refresh_token_expiry_days)
        }
        refresh_token = jwt.encode(refresh_payload, self.token, algorithm)

        return {
            "access_token": access_token,
            "refresh_token": refresh_token
        }
        

    def login(self, email, password, algorithm="HS256"):

        #Check Fisebase db
        id = Function.text_to_numeric_token(email)
        user = fb.get_by_child(f"users/{id}")
        if user:
            if user['email'] == email and user['password'] == password:
                payload = user
                user_id = id
                payload.pop("password")

                if "property" in payload:
                    for p in payload['property']:
                        property_data = fb.get_by_child(f"property/{p}")
                        payload['property'][p]['name'] = property_data.get("name")
                        payload['property'][p]['image_profile'] = property_data.get("image_profile")

                payload['exp'] = datetime.utcnow() + timedelta(minutes=self.access_token_expiry_minutes)
                access_token = jwt.encode(payload, self.token, algorithm)

                refresh_payload = {
                    "user_id": user_id,
                    "type": "refresh",
                    "exp": datetime.utcnow() + timedelta(days=self.refresh_token_expiry_days)
                }
                refresh_token = jwt.encode(refresh_payload, self.token, algorithm)

                return {
                    "access_token": access_token,
                    "refresh_token": refresh_token
                },200
            
            return {"status": "error", "message": "Wrong password!"},404
        return {"status": "error", "message": "Please registe before login"},400
    
    def validate(self, access_token, algorithm="HS256"):
        try:
            decoded = jwt.decode(access_token, self.token, algorithms=[algorithm])
            return decoded
        except jwt.ExpiredSignatureError:
            return {"error": "Token expired"}
        except jwt.InvalidTokenError:
            return {"error": "Invalid token"}
    
    def new_access_token(self, refresh_token, algorithm="HS256"):
        try:
            decoded = jwt.decode(refresh_token, self.token, algorithms=[algorithm])
            # You can add checks here like if the token has a specific "type": "refresh"

            #get data
            user = fb.get_by_child(f"users/{decoded.get('user_id')}")
            user['exp'] = datetime.utcnow() + timedelta(minutes=self.access_token_expiry_minutes)

            access_token = jwt.encode(user, self.token, algorithm)

            refresh_payload = {
                "user_id": decoded.get("user_id"),
                "type": "refresh",
                "exp": datetime.utcnow() + timedelta(days=self.refresh_token_expiry_days)
            }
            refresh_token = jwt.encode(refresh_payload, self.token, algorithm)

            return {
                    "access_token": access_token,
                    "refresh_token": refresh_token
            }
        except jwt.ExpiredSignatureError:
            return {"error": "Refresh token expired"}
        except jwt.InvalidTokenError:
            return {"error": "Invalid refresh token"}

    def decode(self, encoded, algorithm="HS256"):
        return jwt.decode(encoded,self.token,algorithm)



    
