import os
from pathlib import Path
import numpy as np

from Orange.widgets import widget
from Orange.widgets.utils.signals import Input, Output
from Orange.data import Domain, StringVariable, Table
from AnyQt.QtWidgets import QCheckBox

try:
    from Orange.widgets.orangecontrib.AAIT.utils.import_uic import uic
    from Orange.widgets.orangecontrib.IO4IT.utils import utils_md
except ImportError:
    from orangecontrib.IO4IT.utils import utils_md
    from orangecontrib.AAIT.utils.import_uic import uic


class OWMarkdownLoader(widget.OWWidget):
    name = "Markdown Loader"
    description = "Charge tous les fichiers Markdown d’un dossier (récursif)"
    icon = "icons/load_md.png"
    if "site-packages/Orange/widgets" in os.path.dirname(os.path.abspath(__file__)).replace("\\", "/"):
        icon = "icons_dev/load_md.png"
    gui = os.path.join(os.path.dirname(os.path.abspath(__file__)), "designer/owmarkdownloader.ui")
    want_control_area = False
    priority = 1001

    class Inputs:
        data = Input("Data", Table)

    class Outputs:
        md_files = Output("Markdown Files", Table)  # -> (file_path, content)
        data = Output("Data", Table)  # passthrough de l'entrée

    def __init__(self):
        super().__init__()

        self.in_data = None
        self.input_dir = None
        uic.loadUi(self.gui, self)
        self.checkBoxRecursive = self.findChild(QCheckBox, 'checkBoxRecursive')
        # These lines MUST be after super().__init__()
        self.recursive = self.checkBoxRecursive.isChecked()
        self.checkBoxRecursive.stateChanged.connect(self._on_recursive_toggled)

        self.warning("")

    def _on_recursive_toggled(self, _state):
        self.recursive = self.checkBoxRecursive.isChecked()
        # If a directory is already set, re-run the production
        if self.input_dir:
            self._produce()

    @Inputs.data
    def set_data(self, in_data: Table | None):
        self.in_data = in_data
        self.warning("")

        # Always pass through the input data
        self.Outputs.data.send(in_data)

        if not in_data:
            # If no input data, send an empty table
            self.Outputs.md_files.send(self._empty_md_table())
            self.Description.setText(
                "This widget loads Markdown files from a folder. The path must be in a column named 'input_dir'.")
            return

        # Look for the 'input_dir' column and get the first folder
        try:
            input_dir_column = in_data.domain["input_dir"]
            self.input_dir = str(in_data[0, input_dir_column].value)
        except (KeyError, IndexError, AttributeError):
            self.warning('"input_dir" (Text) is required in the input data.')
            self.Outputs.md_files.send(self._empty_md_table())
            self.Description.setText("Error: 'input_dir' (Text) column not found or is empty.")
            return

        self.Description.setText(f"Dossier : {self.input_dir}")
        self._produce()

    def _empty_md_table(self) -> Table:
        domain = Domain([], metas=[StringVariable("file_path"), StringVariable("content")])
        X = np.empty((0, 0))
        metas = np.empty((0, 2), dtype=object)
        return Table.from_numpy(domain, X, metas=metas)

    def _produce(self):
        if not self.input_dir or not os.path.isdir(self.input_dir):
            self.warning(f"Invalid directory path: '{self.input_dir}'")
            self.Outputs.md_files.send(self._empty_md_table())
            return
        base = Path(self.input_dir)
        patterns = ["*.md"]
        paths = []

        for patt in patterns:
            if self.recursive:
                paths.extend(base.rglob(patt))
            else:
                paths.extend(base.glob(patt))

        md_rows = []
        for p in sorted(set(paths)):
            try:
                md_rows.append([str(p), utils_md.try_read_text(p)])
            except Exception:
                md_rows.append([str(p), ""])
        domain = Domain([], metas=[StringVariable("file_path"), StringVariable("content")])
        X = np.empty((len(md_rows), 0))
        metas = np.array(md_rows, dtype=object) if md_rows else np.empty((0, 2), dtype=object)
        md_table = Table.from_numpy(domain, X, metas=metas)

        self.Outputs.md_files.send(md_table)