"""ScreenRenderer class for handling screen updates."""

import sys
from threading import Lock
from typing import List


class ScreenRenderer:
    """
    Handles how the screen is updated. Can do full clears (destructive) or
    simply print appended lines (non-destructive).

    :param non_destructive: If True, do not clear the console on redraw.
    :type non_destructive: bool
    :param thread_safe: If True, locking is used around redraws.
    :type thread_safe: bool
    """

    def __init__(self, non_destructive: bool, thread_safe: bool) -> None:
        """
        Constructor for ScreenRenderer.

        :param non_destructive: If True, do not clear the screen.
        :type non_destructive: bool
        :param thread_safe: If True, operations are locked.
        :type thread_safe: bool
        """
        self.non_destructive = non_destructive
        self._thread_safe = thread_safe
        self._lock = Lock() if thread_safe else None

    def redraw(self, log_lines: List[str], progress_bar_text: str) -> None:
        """
        Redraws the screen by printing logs + progress bar line.
        If non_destructive=False, it clears first.

        :param log_lines: The console log lines to print.
        :type log_lines: List[str]
        :param progress_bar_text: The text of the progress bar.
        :type progress_bar_text: str
        :return: None
        :rtype: None
        """
        if self._thread_safe and self._lock:
            with self._lock:
                self._do_redraw(log_lines, progress_bar_text)
        else:
            self._do_redraw(log_lines, progress_bar_text)

    def _do_redraw(self, log_lines: List[str], bar_text: str) -> None:
        """
        Internal helper that performs the actual console printing.

        :param log_lines: The console log lines to print.
        :type log_lines: List[str]
        :param bar_text: The progress bar line.
        :type bar_text: str
        :return: None
        :rtype: None
        """
        if not self.non_destructive:
            # Move cursor to top-left corner and clear the screen
            sys.stdout.write("\033[H\033[J")

        for line in log_lines:
            sys.stdout.write(line + "\n")

        sys.stdout.write(f"{bar_text}\n")
        sys.stdout.flush()
