"""Loading bar implementation"""

import threading
import time
from typing import Optional


class LoadingBar:
    """Singleton loading bar for CLI startup"""

    _instance: Optional["LoadingBar"] = None
    _lock = threading.RLock()

    def __new__(cls) -> "LoadingBar":
        with cls._lock:
            if cls._instance is None:
                cls._instance = super().__new__(cls)
                cls._instance._initialized = False
            return cls._instance

    def __init__(self):
        with self._lock:
            if self._initialized:
                return
            self._running = False
            self._thread = None
            self._start_time = 0
            self._initialized = True

    def start(self):
        """Start the loading bar in a separate thread"""
        with self._lock:
            if self._running:
                return
            self._running = True
            self._start_time = time.time()
            self._thread = threading.Thread(target=self._display_loading)
            self._thread.daemon = True
            self._thread.start()

    def stop(self):
        """Stop the loading bar and display 100% with elapsed time"""
        with self._lock:
            if not self._running:
                return
            self._running = False
            if self._thread:
                self._thread.join(timeout=0.5)
            elapsed = time.time() - self._start_time
            print(f"\r{'='*50} 100% - Loaded in {elapsed:.2f}s\n")

    def _display_loading(self):
        """Display the loading bar animation"""
        chars = "|/-\\"
        char_index = 0
        progress = 0
        
        while self._running:
            char = chars[char_index]
            char_index = (char_index + 1) % len(chars)
            
            # Update progress (simulated)
            progress = min(progress + 1, 99)
            
            # Calculate bar length
            bar_length = int(progress * 50 / 100)
            bar = "=" * bar_length + " " * (50 - bar_length)
            
            # Print loading bar
            print(f"\r[{bar}] {progress}% {char}", end="", flush=True)
            
            # Sleep for a short time to control animation speed
            time.sleep(0.1)


def get_loading_bar() -> LoadingBar:
    """Get the singleton loading bar instance

    Returns:
        LoadingBar instance
    """
    return LoadingBar()
