# app/services/appwrite_client.py
from __future__ import annotations
import os
from typing import Optional, Dict, Any, Mapping, Union, List

from flask import session, redirect, url_for
from appwrite.client import Client
from appwrite.services.account import Account
from appwrite.id import ID


ENDPOINT = os.getenv("APPWRITE_ENDPOINT")
PROJECT_ID = os.getenv("APPWRITE_PROJECT_ID")
API_KEY = os.getenv("APPWRITE_API_KEY")

# SESSION USER OBJECT DICT NOTES
# {
# 	"$id": "6902663c000efa514a81",
# 	"$createdAt": "2025-10-29T19:08:44.483+00:00",
# 	"$updatedAt": "2025-10-31T00:28:26.422+00:00",
# 	"name": "Test Account",
# 	"registration": "2025-10-29T19:08:44.482+00:00",
# 	"status": true,
# 	"labels": [],
# 	"passwordUpdate": "2025-10-29T19:08:44.482+00:00",
# 	"email": "ptarrant@gmail.com",
# 	"phone": "",
# 	"emailVerification": false,
# 	"phoneVerification": false,
# 	"mfa": false,
# 	"prefs": {},
# 	"targets": [
# 		{
# 			"$id": "6902663c81f9f1a63f4c",
# 			"$createdAt": "2025-10-29T19:08:44.532+00:00",
# 			"$updatedAt": "2025-10-29T19:08:44.532+00:00",
# 			"name": "",
# 			"userId": "6902663c000efa514a81",
# 			"providerId": null,
# 			"providerType": "email",
# 			"identifier": "ptarrant@gmail.com",
# 			"expired": false
# 		}
# 	],
# 	"accessedAt": "2025-10-31T00:28:26.418+00:00"
# }

class AppWriteClient:
    def __init__(self):
        self.session_key = f"a_session_{PROJECT_ID}"

    def _get_admin_client(self):
        return (Client()
                .set_endpoint(ENDPOINT)
                .set_project(PROJECT_ID)
                .set_key(API_KEY)  
                )
    
    def _get_user_client(self):
        client = (Client()
                .set_endpoint(ENDPOINT)
                .set_project(PROJECT_ID)
                )
        
        if session[self.session_key] is not None:
            client.set_session(session[self.session_key])

        return client

    def create_new_user(self, email:str, password:str, name:Optional[str]):
        admin_client = self._get_admin_client()
        try:
            admin_account = Account(admin_client)
            admin_account.create(user_id=ID.unique(),email=email,password=password,name=name)
            return True, ""
        except Exception as e:
            return False, e
        
    def _refresh_user_session_data(self):
        user_client = self._get_user_client()
        user_account = Account(user_client)
        user = user_account.get()
        session['user']=user

    def log_user_in(self, email:str,password:str):
        admin_client = self._get_admin_client()
        try:
            admin_account = Account(admin_client)
            user_session = admin_account.create_email_password_session(email,password)
            session[self.session_key]=user_session['secret']

            self._refresh_user_session_data()
            
            return True, ""
        except Exception as e:
            return False, str(e)
    
    def log_user_out(self):
        try:
            user_client = self._get_user_client()
            user_account = Account(user_client)
            user_account.delete_sessions()
            return True
        except Exception as e:
            return True

    def send_email_verification(self):
        user_client = self._get_user_client()
        user_account = Account(user_client)
        callback_url = url_for('auth.callback', _external=True)
        user_account.create_verification(url=callback_url)
        
    def verify_email(self, user_id:str, secret:str):
        if session[self.session_key] is None:
            return False
        try:
            user_client = self._get_user_client()
            user_account = Account(user_client)
            user_account.update_email_verification(user_id,secret)
            self._refresh_user_session_data()
            return True
        except Exception as e:
            return False