class Solution:
    def fullJustify(self, words: List[str], maxWidth: int) -> List[str]:
        output = []
        line = []
        line_len = 0
        i = 0
 
        def justify(line, line_len, is_last) -> str:
            nonlocal maxWidth
            justify_len = maxWidth - line_len
            text = " ".join(line) if is_last else line[0]
            if not is_last and len(line) > 1:
                # fixed between words
                justify_between = justify_len // (len(line) - 1)
                # variable to add
                justify_mod = justify_len % (len(line) - 1)
                for j in range(1, len(line)):
                    text += " " * (justify_between + (1 if justify_mod else 0))
                    text += line[j]
                    justify_mod = max(0, justify_mod - 1)
 
            text += " " * (maxWidth - len(text))
            return text
 
        while i < len(words):
            if (len(words[i]) + line_len + len(line) <= maxWidth):
                line.append(words[i])
                line_len += len(words[i])
                i += 1
            else:    
                output.append(justify(line, line_len, False))
                line = []
                line_len = 0
 
        # Process last line
        output.append(justify(line, line_len, True))
 
        return output