import pprint
import re
import textwrap
import kutil
import klammer_base
import itertools
import math
from html_util import E

class List(klammer_base.Klammer_base):
    def __init__(self, K, list_type):
        super().__init__(K)
        self.list_type = list_type
        self.items = self.list_items
        word_count = max([len(e.strip().split()) for e in self.items])
        self.compressed = False #and word_count < int(self.List_compressed_word_max)
        
    def html(self):
        body = ""
        word_count = 0
        for e in self.items:
            body += f"<li>\n{kutil.format_for_paragraphs(e.strip())}\n</li>\n"
        cls = "compressed" if self.compressed else ""
        result = E(self.list_type).cls(cls).body(body.strip()).str().strip() + "\n"
        return result
    
    def tex(self):
        body = "\n\n".join([f"\\item {e}" for e in self.items])
        command = {'ol' : 'enumerate', 'ul' : 'itemize'}[self.list_type]
        init = ""
        if self.__dict__.get("initial") and self.initial != 1:
            init = "\\addtocounter{enumi}{" + str(self.initial - 1) + "}"
        #topsep = '[noitemsep,topsep=0pt]'
        topsep = "[noitemsep,topsep=0pt," if self.compressed else "[topsep=0pt,itemsep=2pt,"
        topsep += "leftmargin=16pt]"
        listsep = '\\setlist{nolistsep}' if self.cmp else ''
        result = f'{listsep}\n\\begin{{{command}}}{topsep}{init}\n{body}\n\\end{{{command}}}\n'
        return result

    def txt(self):
        n = 1
        result = ""
        for item in self.items:
            prefix = f"{n:3}. " if self.list_type == "ol" else "  • " # U+2022
            print("prefix", prefix)
            formatted_item = "\n".join(
                textwrap.wrap(item.strip(), width=80, subsequent_indent=" "*(len(prefix))))
            result += f"{prefix}{formatted_item}\n"
            if not self.compressed:
                result += "\n"
            n += 1
        return result


class Define(klammer_base.Klammer_base):
    def __init__(self, K):
        super().__init__(K)
        self.items = self.descriptions
        #self.show()
        #pprint.pprint(self.items)

    def html(self):
        def fontify(s):
            return {"r" : s,
                    "i" : f"<i>{s}</i>",
                    "b" : f"<b>{s}</b>",
                    "t" : f'<span class="monospace">{s}</span>',
                    "c" : f'<span class="monospace">{s}</span>',
                    "s" : f'<span class="sansserif">{s}</span>'}[self.font]
        result = "\n\n".join([f"<dt>{fontify(term)}</dt>\n<dd>{definition}</dd>"
                              for term,definition in self.items])
        result = f"<dl>\n{result}\n</dl>"
        return result

    def tex(self):
        def fontify(s):
            font = {'r' : r'\normalfont',
                    'i' : r'\normalfont\itshape',
                    'b' : r'\normalfont\bfseries',
                    't' : r'\normalfont\ttfamily',
                    'c' : r'\normalfont\ttfamily',
                    's' : r'\normalfont\sffamily'}[self.font]
            return f"{font} {s}"
        # The "\hfill\newline" was to force the description to the next line even if the item was small:
        # result = "\n\n".join([f"\\item[{{{fontify(term)}}}]\\hfill\n\\newline {definition}"
        strut = r"\rule[-8pt]{0pt}{8pt}"
        result = "\n\n".join([f"\\item[{{{fontify(term)}{strut}}}] {definition}"
                              for term,definition in self.items])
        result = f"\\begin{{description}}[labelindent=12pt,nosep,itemsep=6pt,parsep=.5\\parskip,style=nextline]\n{result}\n\\end{{description}}"
        return result

# Needs to be implemented:
#    def txt(self):
#        return "TXT DEFINITIONS"


class Lines(klammer_base.Klammer_base):
    def __init__(self, K):
        super().__init__(K)

    def html(self):
        #return " <br/>".join(self.s.strip().split("\n"))        
        #return f'<pre style="font-family: var(--serif)">{self.s}</pre>'
        #return f'<pre>{self.s}</pre>'
        result = self.s
        result = re.sub("\n", "<br/>\n", result)
        result = re.sub(" ", "&^#160;", result)
        return result

    def tex(self):
        return r"\\\newline\n".join(self.s.strip().split("\n"))

    def txt(self):
        return self.s.strip()



def make_column_lists(lst, count):
    cols = math.ceil(len(lst) / count)
    result = []
    for i in range(count):
        #print(i * cols, (i + 1) * cols)
        result.append(lst[i * cols : (i+1) * cols])
    return list(itertools.zip_longest(*result, fillvalue=""))

def xmake_column_lists(lst, column_count):
    count = len(lst)
    row_count = math.ceil(count / column_count)
    print(count, column_count, row_count)
    i = 0
    while i < count:
        i += 1

def columns(K):
    rows = make_column_lists(K.items.split(), K.n)
    result = "@table\n"    # :lines false :header_line false :leading 1.1 :vmargin false |\n"
    for row in rows:
        #print("row:", row)
        result += " | ".join(row) + " ||\n"
    result += "table@\n"
    if K.K_target == "latex":
        result = f"\\vspace*{{-12pt}}\n{result}"
    return result
