import csv
import re
import os

class SindhiLemmatizer:
    def __init__(self, wordnet_path=None):
        if wordnet_path is None:
            base_path = os.path.dirname(__file__)
            wordnet_path = os.path.join(base_path, "data", "wordnet.csv")
        self.WORDNET = {}
        self._load_wordnet(wordnet_path)

        # Linguistic rules
        self.VERB_SUFFIXES = {
            "ائيندا": "verb (future habitual)",
            "ائيندي": "verb (future feminine)",
            "ائينداسين": "verb (future plural)",
            "ندو": "verb (present)",
            "ندي": "verb (present feminine)",
            "يو": "verb (past)",
            "يندڙ":"verb (habitual)"
        }

        self.PLURAL_NOUN_RULES = {
            "يون": ("ي", "feminine", "plural"),
            "ون": ("و", "masculine", "plural"),
            "ن": ("", "-", "plural")   # added generic plural suffix
        }

        self.COLLECTIVE_NOUNS = {"ماڻهو", "لوڪ", "قوم"}

    @staticmethod
    def normalize(text):
        if not text: return ""
        return re.sub(r'[\u064B-\u0652\u0670]', '', str(text)).strip()

    def _load_wordnet(self, path):
        if not os.path.exists(path):
            return
        with open(path, encoding="utf-8-sig") as f:
            for row in csv.DictReader(f):
                w = self.normalize(row.get("word", ""))
                if w:
                    self.WORDNET[w] = {
                        "tag": row.get("tags", "unknown"),
                        "gender": row.get("gender", "-"),
                        "number": row.get("invariants", "-"),
                        "syn": row.get("synonyms", "")
                    }

    def _analyze_verb(self, word):
        for suf, tag in self.VERB_SUFFIXES.items():
            if word.endswith(suf):
                stem = word[:-len(suf)]
                candidates = [
                    stem + "ائڻ",
                    stem + "ڻ",
                    stem
                ]
                for c in candidates:
                    if c in self.WORDNET:
                        return {
                            "root": c,
                            "tag": tag,
                            "gender": "-",
                            "number": "-",
                            "synonyms": self.WORDNET[c]["syn"].split("،") if self.WORDNET[c]["syn"] else []
                        }
                return {
                    "root": stem,
                    "tag": tag,
                    "gender": "-",
                    "number": "-",
                    "synonyms": []
                }
        return None

    def lemmatize(self, word):
        clean = self.normalize(word)

        # 1️⃣ Verb override
        verb = self._analyze_verb(clean)
        if verb:
            return {"word": word, **verb}

        # 2️⃣ Collective nouns
        if clean in self.COLLECTIVE_NOUNS:
            return {
                "word": word,
                "root": clean,
                "tag": "noun (collective)",
                "gender": "-",
                "number": "plural",
                "synonyms": self.WORDNET.get(clean, {}).get("syn", "").split("،")
            }

        # 3️⃣ Plural noun normalization
        for suf, (rep, gen, num) in sorted(self.PLURAL_NOUN_RULES.items(), key=lambda x: -len(x[0])):
            if clean.endswith(suf):
                root_candidate = clean[:-len(suf)] + rep
                # If root exists in WordNet, return full info
                if root_candidate in self.WORDNET:
                    info = self.WORDNET[root_candidate]
                    return {
                        "word": word,
                        "root": root_candidate,
                        "tag": "noun",
                        "gender": gen,
                        "number": num,
                        "synonyms": info["syn"].split("،") if info["syn"] else []
                    }
                else:
                    # Fallback: return the local root even if not in WordNet
                    return {
                        "word": word,
                        "root": root_candidate,
                        "tag": "noun",
                        "gender": gen,
                        "number": num,
                        "synonyms": []
                    }

        # 4️⃣ Direct WordNet lookup
        if clean in self.WORDNET:
            info = self.WORDNET[clean]
            return {
                "word": word,
                "root": clean,
                "tag": info["tag"],
                "gender": info["gender"],
                "number": info["number"],
                "synonyms": info["syn"].split("،") if info["syn"] else []
            }

        # 5️⃣ Unknown
        return {
            "word": word,
            "root": clean,
            "tag": "unknown",
            "gender": "-",
            "number": "-",
            "synonyms": []
        }