import re
from dataclasses import dataclass
from typing import List, Optional, Tuple

from .number_pronunciation import normalize_with_3_pattern

mapping = {
    "০": "শূন্য",
    "১": "এক",
    "২": "দুই",
    "৩": "তিন",
    "৪": "চার",
    "৫": "পাঁচ",
    "৬": "ছয়",
    "৭": "সাত",
    "৮": "আট",
    "৯": "নয়",
    "0": "জিরো",
    "1": "ওয়ান",
    "2": "টু",
    "3": "থ্রি",
    "4": "ফোর",
    "5": "ফাইভ",
    "6": "সিক্স",
    "7": "সেভেন",
    "8": "এইট",
    "9": "নাইন",
}


@dataclass
class NIDMatch:
    """Class to represent a matched NID number with its position in text"""

    value: str
    start: int
    end: int
    bengali_value: str

    def __str__(self) -> str:
        return f"NID(value='{self.value}', span=({self.start}, {self.end}), bengali='{self.bengali_value}')"


@dataclass
class NIDNumber:
    """Class to represent and validate Bangladesh National ID numbers"""

    value: str

    # Class constants
    BENGALI_DIGITS = str.maketrans("0123456789", "০১২৩৪৫৬৭৮৯")
    BENGALI_TO_ENGLISH = str.maketrans("০১২৩৪৫৬৭৮৯", "0123456789")

    # Updated pattern to match both Bengali and English digits

    # NID_PATTERNS = [
    #     r"(?:NID|NID নম্বর|জাতীয় পরিচয়পত্র নং|জাতীয় পরিচয়পত্র নম্বর|জাতীয় পরিচয়পত্র|পরিচয়পত্র|লাইসেন্স|ড্রাইভিং লাইসেন্স|জাতীয় পরিচয় নম্বর|"
    #     r"জাতীয় পরিচয় নম্বর|NID Number|NID নং|এনআইডি|এনআইডি নম্বর|এনআইডি Number|এনআইডি নং)\s*[:ঃ]?\s*([০-৯0-9]+(?:\s+[০-৯0-9]+)*)"
    # ]

    NID_PATTERNS = [
        r"(?:NID|NID নম্বর|জাতীয় পরিচয়পত্র নং|জাতীয় পরিচয়পত্র নম্বর|জাতীয় পরিচয়পত্র|পরিচয়পত্র|লাইসেন্স|ড্রাইভিং লাইসেন্স|জাতীয় পরিচয় নম্বর|"
        r"জাতীয় পরিচয় নম্বর|NID Number|NID নং|এনআইডি|এনআইডি নম্বর|এনআইডি Number|এনআইডি নং)\s*[:ঃ]?\s*([০-৯0-9]+(?:[\s\-][০-৯0-9]+)*)"
    ]

    # Compile the pattern

    def __post_init__(self) -> None:
        """Validate the NID number format after initialization"""
        # if not self._is_valid_format():
        #     raise ValueError("Invalid NID number format")

    # def _is_valid_format(self) -> bool:
    #     """Check if the NID number has valid format"""
    #     # Convert Bengali digits to English first if needed
    #     english_value = self.value.translate(self.BENGALI_TO_ENGLISH)
    #     return len(english_value) >= 10 and len(english_value) <= 17 and english_value.isdigit()

    def to_bengali(self) -> str:
        """Convert the NID number to Bengali digits"""
        # First ensure we have English digits

        english_value = self.value.translate(self.BENGALI_TO_ENGLISH)
        # return english_value.translate(self.BENGALI_DIGITS)
        return english_value

    @classmethod
    def from_bengali(cls, bengali_number: str) -> "NIDNumber":
        """Create NIDNumber from Bengali digits"""
        english_number = bengali_number.translate(cls.BENGALI_TO_ENGLISH)
        return cls(english_number)


class NIDNormalizer:
    """Class to normalize NID numbers in text"""

    def __init__(self) -> None:
        # self.nid_pattern = re.compile("|".join(NIDNumber.NID_PATTERNS))
        self.nid_pattern = re.compile(NIDNumber.NID_PATTERNS[0], re.IGNORECASE)

    def extract_nids(self, text: str) -> List[NIDMatch]:
        """Extract all NID numbers with their positions from text"""
        matches = []
        for match in self.nid_pattern.finditer(text):
            # try:
            nid_number = NIDNumber(match.group(1))
            # print("nid_number", nid_number)
            # Get the span of the actual number, not the whole match
            number_start = match.start(1)
            number_end = match.end(1)

            if nid_number.value.isdigit():
                bengali_value = nid_number.value
            else:
                bengali_value = nid_number.to_bengali()

            bengali_value = " ".join(mapping.get(char, char) for char in bengali_value)
            # print("bengali_value", bengali_value)

            norm_bengali_value = normalize_with_3_pattern(bengali_value.split(" "))

            matches.append(
                NIDMatch(
                    value=nid_number.value,
                    start=number_start,
                    end=number_end,
                    bengali_value=norm_bengali_value,
                )
            )
            # except ValueError:
            #     # Skip invalid NID numbers
            #     continue
        return matches

    def normalize(self, text: str) -> str:
        """Normalize NID numbers in the given text to Bengali digits"""
        result = text
        # print("result----> ", result)
        # Process matches in reverse order to avoid position shifts
        for match in reversed(self.extract_nids(text)):
            # print("match----> ", match)

            # print("match.bengali_value : ", match.bengali_value)
            result = result[: match.start] + match.bengali_value + " " + result[match.end :]
        return result


def main() -> None:
    """Example usage of the NID classes"""
    sample_texts = [
        "তার NID নম্বর 1234567890123।",
        "জাতীয় পরিচয়পত্র নং: 987654321098।",
        "আপনার এনআইডি ৩২১০৯৮৭৬৫৪৩২।",
        "NID নং: 110022334455",
        "জাতীয় পরিচয়পত্র নম্বর: 76543210987",
        "আপনার NID: ৭৬৫৪৩২১০৯৮৭ যাচাই করুন।",
        "NID Number: 1234567890",
        "জাতীয় পরিচয় নম্বরঃ 0987654321 জাতীয় পরিচয় নম্বরঃ 0987654321",
        "এনআইডি নম্বরঃ 1234567890",
        "এনআইডি নম্বরঃ ১২৩৪৫৬৭৮৯০ hello 12345" "জাতীয় পরিচয়পত্র ৪৫৬৭",
    ]

    normalizer = NIDNormalizer()

    for text in sample_texts:
        print(f"\nOriginal: {text}")
        # Extract and print NID matches with positions
        # matches = normalizer.extract_nids(text)
        normalized = normalizer.normalize(text)
        print(f"Normalized: {normalized}")


if __name__ == "__main__":
    main()
