import re
from collections import OrderedDict
from math import floor

from .இடஞ்சார் import இடஞ்சார்


class அடிமானம்(இடஞ்சார்):
    def __init__(தன், பெயர், ஒருங்குறி, அடிமானங்கள், குறிகள், பிரிப்பு, அடுக்குக்குறி):
        super().__init__(பெயர், ஒருங்குறி, குறிகள்=குறிகள், பிரிப்பு=பிரிப்பு, அடுக்குக்குறி=அடுக்குக்குறி)

        தன்.அடிமானங்கள் = OrderedDict(sorted(அடிமானங்கள்.items(), key=lambda விசை: (விசை[1], விசை[0])))
        தன்.அடிமானம் = len(தன்.குறிகள்)

    def எண்ணுக்கு(தன், உரை):
        if re.search(rf'[{தன்.அடுக்குக்குறி}]', உரை):
            return super().எண்ணுக்கு(உரை)

        எதிர் = உரை.startswith('-')
        if எதிர்:
            உரை = உரை[1:]
        else:
            உரை = உரை.strip('+')

        try:
            முழு, தசம = re.split(rf'[{தன்.பிரிப்பு}]', உரை)
        except ValueError:
            முழு = உரை
            தசம = None

        எண் = 0
        if முழு:
            பெட்டியல் = list(
                reversed([தன்.அடிமானங்கள்[அ] if அ in தன்.அடிமானங்கள் else தன்.குறிகள்.index(அ) for அ in முழு])
            )

            def படித்தல்(பெ):
                ஆ = பெ[0]
                ஊ = next((இ for இ, ஈ in enumerate(பெ[1:]) if ஈ > ஆ), len(பெ[1:])) + 1
                கீழ் = பெ[1:ஊ]
                கீழ் = படித்தல்(கீழ்) if கீழ் else 1
                மேல் = பெ[ஊ:]
                mel = படித்தல்(மேல்) if மேல் else 0
                return ஆ * கீழ் + mel

            எண் = படித்தல்(பெட்டியல்)

        if தசம is not None:
            if தசம:
                try:
                    எண் += float('.' + ''.join(str(தன்.குறிகள்.index(த)) for த in தசம))
                except ValueError:
                    raise
            else:
                எண் = float(எண்)
        if எதிர்:
            எண் *= -1
        return எண்

    def உரைக்கு(தன், எண்):
        எதிர் = எண் < 0
        எண் = abs(எண்)

        முழு = floor(எண்)
        if 'e' in str(எண்):
            எண், அடு = str(எண்).split('e')
            return தன்.உரைக்கு(float(எண்)) + தன்.அடுக்குக்குறி[0] + தன்.உரைக்கு(int(அடு))

        try:
            தசம = str(எண்).split('.')[1]
        except IndexError:
            தசம = None

        உரை = தன்._அடிமானம்_எழுதல்(முழு)

        if not len(உரை):
            உரை = தன்.குறிகள்[0]

        if எதிர்:
            உரை = '-' + உரை
        if தசம:
            உரை += தன்.பிரிப்பு[0] + ''.join(தன்.குறிகள்[int(த)] for த in தசம)
        return உரை

    def சுருங்குறித்தொடர்(தன், வடிவம்=None):
        முழு = f'{"".join(list(தன்.அடிமானங்கள்))}{தன்.குறிகள்}'
        தொடர் = rf'[-+]?(([{முழு}]+([{தன்.பிரிப்பு}][{தன்.குறிகள்}]*)?)|([{தன்.பிரிப்பு}][{தன்.குறிகள்}]+))'
        return rf'({தொடர்})|([{தன்.குறிகள்}]([{தன்.பிரிப்பு}][{தன்.குறிகள்}]*)?([{தன்.அடுக்குக்குறி}][-+]?[{முழு}]+))'

    def _அடிமானம்_எழுதல்(தன், எண்):
        மீதி = எண்
        உரை = ''

        for அடி, மதிப்பு in reversed(தன்.அடிமானங்கள்.items()):
            ம = int(மீதி // மதிப்பு)
            if ம:
                மீதி -= ம * மதிப்பு
                if ம != 1:
                    உரை += தன்._அடிமானம்_எழுதல்(ம)
                உரை += அடி

        if மீதி:
            உரை += தன்.குறிகள்[int(மீதி)]

        return உரை
