import os
import time
from .styleOBJ import Style

class Loading:
    def __init__(self, style: Style = None, bar_fil="-", end='>', bar_unfil='-', ACTION='CHILLING', M='Complete', finish=100, LOADING=True, val=True, UNIT='MB', MARGIN=1):
        """
        Initialize the Loading Bar Vibe.
        
        Args:
            style (Style): The snake/bar aesthetic from styleOBJ.
            bar_fil (str): The char that fills the bar (default: '-').
            end (str): The "head" of the snake (default: '>').
            bar_unfil (str): The empty space char (default: '-').
            ACTION (str): The loud text on the left (e.g., 'DOWNLOADING').
            M (str): The status label (default: 'Complete').
            finish (int/float): The goal line (e.g., total MBs).
            LOADING (bool): Toggle for the ETA and speed logic.
            val (bool): Toggle for showing the (10/100) raw values.
            UNIT (str): The unit label (default: 'MB').
            MARGIN (int): Extra space to prevent overflow on small terminals.
        """
        
        self.finish = finish
        self.bar = bar_fil
        self.end = end
        self.ACTION = ACTION
        self.M = M
        self.LOADING = LOADING
        self.start_time = time.time()
        self.bar_unfil = bar_unfil
        self.value = val
        self.unit = UNIT
        self.margin = MARGIN
        
        if style is not None: # Use 'is not None' for the pro vibe
            self.bar = style.bar_fil
            self.end = style.end 
            self.bar_unfil = style.bar_unfil

    def update(self, progress):
        self.__display__(progress, self.finish)
    
    def __display__(self, progress, finish):
        
        
        # Clamp progress
        if progress < 0: progress = 0
        if progress > finish: progress = finish

        # Calculate ETA
        if progress > 0 and self.LOADING:
            elapsed = time.time() - self.start_time
            speed = progress / elapsed
            remaining = (finish - progress) / speed
            eta_str = f" | ETA: {remaining:.1f}s"
        else:
            eta_str = ""
        self.columns = os.get_terminal_size().columns
        # Adjust text overhead to include ETA length
        percent = (progress / finish) * 100 if finish != 0 and progress != 0 else 0
        
        static_text_len = (len(self.ACTION) + len(eta_str) + len(self.M) + 
                        len(f"{percent:.2f}") + len(f"{progress:.1f}") + 
                        len(f"{finish:.1f}") + (self.margin*2) + 11)

        bar_length = self.columns - static_text_len
        if bar_length < 5: bar_length = 5
        
        
        filled_length = int(bar_length * progress // finish) if finish != 0 and progress != 0 else 0
        unfilled_len = bar_length - filled_length
        
        bar = f'{self.bar}' * filled_length + self.end + f'{self.bar_unfil}' * unfilled_len
        
        # Keep the bar in the brackets, put ETA outside!
        print(f'\r{" " * self.margin}{self.ACTION} [{bar}] {percent:.2f}% ({progress:.1f}/{finish:.1f} {self.M}){eta_str}{" " * self.margin}', end='', flush=True)
        
        if self.LOADING and progress >= finish:
            print()
    def __enter__(self):
        # This makes 'with' work!
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        # This cleans up the vibe when the 'with' block ends
        self.update(self.finish) 
        print(f"\nDone!")
    