from textual.widgets import DataTable, Static
from textual.reactive import Reactive
from textual.message import Message
from textual import events, log
from jinja2.filters import do_filesizeformat

from fhost import File
from modui import mime


class FileTable(DataTable):
    query = Reactive(None)
    order_col = Reactive(0)
    order_desc = Reactive(True)
    limit = 10000
    colmap = [File.id, File.removed, File.nsfw_score, None, File.ext,
              File.size, File.mime]

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.add_columns("#", "☣️", "🔞", "📂", "name", "size", "mime")
        self.base_query = File.query.filter(File.size != None)
        self.query = self.base_query

    class Selected(Message):
        def __init__(self, f: File) -> None:
            self.file = f
            super().__init__()

    def watch_order_col(self, old, value) -> None:
        self.watch_query(None, None)

    def watch_order_desc(self, old, value) -> None:
        self.watch_query(None, None)

    def watch_query(self, old, value) -> None:
        def fmt_file(f: File) -> tuple:
            mimemoji = mime.mimemoji.get(f.mime.split('/')[0],
                                         mime.mimemoji.get(f.mime)) or '  '
            return (
                str(f.id),
                "🔴" if f.removed else "  ",
                "🚩" if f.is_nsfw else "  ",
                "👻" if not f.getpath().is_file() else "  ",
                f.getname(),
                do_filesizeformat(f.size, True),
                f"{mimemoji} {f.mime}",
            )

        if (self.query):
            order = FileTable.colmap[self.order_col]
            q = self.query
            if order:
                q = q.order_by(order.desc() if self.order_desc
                               else order, File.id)
            qres = list(map(fmt_file, q.limit(self.limit)))

            ri = 0
            row = self.cursor_coordinate.row
            if row < self.row_count and row >= 0:
                ri = int(self.get_row_at(row)[0])

            self.clear()
            self.add_rows(qres)

            for i, v in enumerate(qres):
                if int(v[0]) == ri:
                    self.move_cursor(row=i)
                    break

            self.on_selected()

    def on_selected(self) -> Selected:
        row = self.cursor_coordinate.row
        if row < self.row_count and row >= 0:
            f = File.query.get(int(self.get_row_at(row)[0]))
            self.post_message(self.Selected(f))

    def watch_cursor_coordinate(self, old, value) -> None:
        super().watch_cursor_coordinate(old, value)
        if old != value:
            self.on_selected()

    def on_click(self, event: events.Click) -> None:
        meta = self.get_style_at(event.x, event.y).meta
        if meta:
            if meta["row"] == -1:
                qi = FileTable.colmap[meta["column"]]
                if meta["column"] == self.order_col:
                    self.order_desc = not self.order_desc
                self.order_col = meta["column"]