import time
import json
import sys,os
from typing import Dict
from enum import Enum

class Status(Enum):
    SUCCESS = "Success"
    FAILED = "Failed"
class TransactionLogger:
    def __init__(self):
        self.start_time = int(time.time() * 1000)
        self.transaction_log = {
            'statusCode': '200',
            'status': 'Success',
            'backendCall': []
        }
        self.is_initialized = True

    def get_response_time(self):
        return int(time.time() * 1000) - self.start_time

    def set_backend_details(self, backend_call):
        self.transaction_log['backendCall'].append(backend_call)

    def add_bam_attributes(self, key, value):
        self.transaction_log[key] = value

    def set_transaction_status(self, status, status_code, error_description=None):
        self.transaction_log['status'] = status
        self.transaction_log['statusCode'] = status_code
        if error_description:
            self.transaction_log['errorDescription'] = error_description

    def get_service_latency_time(self):
        total_latency = sum(call['latency'] for call in self.transaction_log['backendCall'])
        return total_latency

    def log_transaction(self):
        self.transaction_log['svcLatency'] = self.get_response_time()
        if self.transaction_log['statusCode'] in ['200', '201', '202']:
            print(f'transactionLog: {json.dumps(self.transaction_log)}')
        else:
            print(f'transactionLog: {json.dumps(self.transaction_log)}', file=sys.stderr)
        self.transaction_log = {}

    def log_object(self, obj):
        if obj:
            for key, value in obj.items():
                self.add_bam_attributes(key, value)

    def log_event_attributes(self, event):
        if event:
            authorizer = event.get('requestContext', {}).get('authorizer', {})
            self.add_bam_attributes('client_id', authorizer.get('principalId'))
            self.add_bam_attributes('client_name', authorizer.get('client_name'))
            self.add_bam_attributes('httpMethod', event.get('httpMethod'))
            self.add_bam_attributes('URI', event.get('path'))
            trace_id = os.environ.get('_X_AMZN_TRACE_ID').replace('Root=', '')
            self.add_bam_attributes('traceId', trace_id)

    def update_backend_call_details(self,
        start_time_ms: int,
        status: Status,
        status_code: int,
        url: str,
        environment: str,
        action: str,
        error_code: str = "",
        error_description: str = "",
        identifier: str = ""
    ) -> Dict[str, any]:
        """
        Creates a dictionary of backend call details similar to the JS function.

        Args:
            start_time_ms: Start time in milliseconds (like Date.now() in JS).
            status: Status string.
            status_code: Numeric status code.
            url: Backend URL.
            environment: Environment name.
            action: Action performed.
            error_code: Optional error code.
            error_description: Optional error description.
            identifier: Optional identifier.

        Returns:
            Dict containing backend call details.
        """
        current_time_ms = int(time.time() * 1000)
        backend_call_details = {
            "latency": current_time_ms - start_time_ms,
            "status": status,
            "statusCode": status_code,
            "identifier": identifier,
            "url": url,
            "environment": environment,
            "action": action,
            "errorCode": error_code,
            "errorDescription": error_description
        }
        self.set_backend_details(backend_call_details)