from kivymd.app import MDApp
from kivy.lang.builder import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.animation import Animation
from kivy.properties import NumericProperty, ObjectProperty, ListProperty, StringProperty
from kivy.clock import Clock
from kivymd.uix.button import MDIconButton
from kivy.metrics import dp
from kivy.core.window import Window
from kivymd.uix.label import MDLabel
from kivymd.theming import ThemableBehavior

__all__ = ('AKBottomNavigation')

Builder.load_string(
    """
<_AKLabel>
    size_hint:None ,None
    size: dp(48) , dp(48)
    font_style: 'Caption'
    halign: 'center'
    valign: 'center'
    theme_text_color: 'Custom'
    text_color: root.text_color if root.text_color else root.theme_cls.primary_light

<_AKButton>
    theme_text_color: 'Custom'
    text_color: root.icon_color if root.icon_color else root.theme_cls.primary_color

<AKBottomNavigation>:
    orientation: 'vertical'
    size_hint_y: None
    height: self.minimum_height
    BoxLayout:
        size_hint_y: None
        height: dp(14)

        canvas.before:
            Color:
                rgba: root.bar_color if root.bar_color else root.theme_cls.primary_color
            Rectangle:
                pos: self.pos
                size: self.size

    BoxLayout:
        size_hint_y: None
        height: dp(56)

        canvas.before:
            Color:
                rgba: root.bg_color if root.bg_color else root.theme_cls.bg_dark
            Rectangle:
                pos: self.pos
                size: self.size

        Widget:
            id: _bubble
            bubble_x: 0
            size_hint: None , None
            size: root.width , dp(70)
            canvas.before:
                Color:
                    rgba: root.bar_color if root.bar_color else root.theme_cls.primary_color
                Rectangle:
                    pos: self.bubble_x , dp(28)
                    size: dp(112) , dp(28)
                Ellipse:
                    pos: self.bubble_x+dp(28) , 0
                    size: dp(56) , dp(56)
                Color:
                    rgba: root.bg_color if root.bg_color else root.theme_cls.bg_dark
                Ellipse:
                    pos: self.bubble_x - dp(28) , 0
                    size: dp(56) , dp(56)
                Ellipse:
                    pos: self.bubble_x + dp(84) , 0
                    size: dp(56) , dp(56)

            FloatLayout:
                id: _text_bar
                size_hint: None , None
                size: root.width , dp(56)

            FloatLayout:
                id: _buttons_bar
                size_hint: None , None
                size: root.width , dp(70)


"""
)


class _AKLabel(MDLabel):
    text_color = ListProperty()

    def __init__(self, **kwargs):
        super().__init__(**kwargs)


class _AKButton(MDIconButton):
    icon_color = ListProperty()

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        Clock.schedule_once(lambda x: self._update())

    def on_release(self):
        self.root.set_current(self.parent.children.index(self))

    def _update(self):
        self.root = self.parent.parent.parent.parent


class AKBottomNavigation(ThemableBehavior, BoxLayout):
    items = ListProperty()
    bar_color = ListProperty()
    icon_color = ListProperty()
    text_color = ListProperty()
    bg_color = ListProperty()
    transition = StringProperty('out_sine')
    duration = NumericProperty(0.2)

    _selected = -1

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        Window.bind(on_resize=self._on_resize)

    def _clear_bar(self):
        self.ids._buttons_bar.clear_widgets()
        self.ids._text_bar.clear_widgets()

    def _update_items(self, items):
        count = len(self.items)
        section_x = 1 / (count + 1)
        but_pos = section_x
        for x in range(0, count):
            button = _AKButton(
                icon=self.items[x]['icon'],
                pos_hint={'center_x': but_pos},
                icon_color=self.icon_color
            )
            button.bind(on_release=self.items[x]['on_release'])

            label = _AKLabel(
                text=self.items[x]['text'],
                pos_hint={'center_x': but_pos},
                opacity=0,
                text_color=self.text_color
            )

            self.ids._text_bar.add_widget(label)
            self.ids._buttons_bar.add_widget(button)
            but_pos += section_x
        self.ids._bubble.bubble_x = Window.size[0] * \
            self.ids._buttons_bar.children[self._selected].pos_hint['center_x'] - dp(
                56)
        self.ids._buttons_bar.children[self._selected].opacity = 0
        self.ids._text_bar.children[self._selected].opacity = 1

    def _on_resize(self, instance, width, height):
        self.ids._bubble.bubble_x = width * \
            self.ids._buttons_bar.children[self._selected].pos_hint['center_x'] - dp(
                56)

    def on_items(self, *args):
        self._clear_bar()
        return self._update_items(self.items)

    def set_current(self, index):
        current_item_button = self.ids._buttons_bar.children[index]
        current_item_text = self.ids._text_bar.children[index]
        AKBottomNavigation._selected = index

        for x in self.ids._buttons_bar.children:  # button
            x.opacity = 1

        for x in self.ids._text_bar.children:  # text
            x.opacity = 0

        bubble_pos = current_item_button.x - dp(31)
        anim_bubble = Animation(
            bubble_x=bubble_pos,
            t=self.transition,
            duration=self.duration)
        anim_text_opacity = Animation(
            opacity=1, t=self.transition, duration=self.duration)
        anim_icon_opacity = Animation(
            opacity=0, t=self.transition, duration=self.duration)

        anim_icon_opacity.start(current_item_button)
        anim_text_opacity.start(current_item_text)
        anim_bubble.start(self.ids._bubble)
