from typing import Any

from django.conf import settings
from crispy_forms.bootstrap import (
    Tab,
    TabHolder,
    Field,
    AppendedText,
    PrependedText,
    PrependedAppendedText,
)
from crispy_forms.utils import TEMPLATE_PACK

AppendedText.template = settings.APPENDED_TEXT_TEMPLATE
PrependedText.template = settings.PREPENDED_TEXT_TEMPLATE
PrependedAppendedText.template = settings.PREPENDED_APPENDED_TEXT_TEMPLATE
Field.template = settings.FIELD_TEMPLATE

# Add "fade in" so transitions are smoother
Tab.css_class = 'tab-pane fade show active'


# ------------------------------------------------------------------------
class LCWizardHolder(TabHolder):
    template = settings.WIZARD_HOLDER_TEMPLATE


# ------------------------------------------------------------------------
class LCWizardSideTabHolder(TabHolder):
    template = settings.WIZARD_SIDE_TAB_HOLDER_TEMPLATE


# ------------------------------------------------------------------------
class ButtonPrependedAppendedText(PrependedAppendedText):
    template = settings.BUTTON_PREPENDED_APPENDED_TEXT_TEMPLATE


# ------------------------------------------------------------------------
class InputButtonGroup(Field):
    """
    Layout object for rendering radio and checkbox elements as button groups::

        RadioButtons('field_name', [option_label_class="btn btn-primary"], [option_btn_group_class="btn-group btn-group-toggle"])
    """

    template = settings.INPUT_BUTTON_GROUP_TEMPLATE

    def __init__(self, *args: Any, **kwargs: Any) -> None:
        try:
            self.input_type
        except AttributeError:
            raise NotImplementedError(
                f'Cannot instantiate {type(self).__name__}.  input_type property must be set'
            ) from None

        self.option_label_class = kwargs.pop('option_label_class', 'btn btn-outline-primary')
        self.option_btn_group_class = kwargs.pop(
            'option_btn_group_class', 'btn-group btn-group-toggle'
        )

        super().__init__(*args, **kwargs)

    def render(self, *args, template_pack=TEMPLATE_PACK, extra_context=None, **kwargs):
        return super().render(
            *args,
            template_pack=template_pack,
            extra_context={
                'input_type': self.input_type,
                'option_label_class': self.option_label_class,
                'option_btn_group_class': self.option_btn_group_class,
            },
            **kwargs,
        )


# ------------------------------------------------------------------------
class CheckboxButtons(InputButtonGroup):
    input_type = 'checkbox'


# ------------------------------------------------------------------------
class RadioButtons(InputButtonGroup):
    input_type = 'radio'


# -------------------------------------------------------------------------
class RadioButtonsBlock(RadioButtons):
    def __init__(self, *args: Any, **kwargs: Any) -> None:
        kwargs['option_btn_group_class'] = 'btn-group btn-block btn-group-toggle'
        super().__init__(*args, **kwargs)


# -------------------------------------------------------------------------
class RadioButtonsVertical(RadioButtons):
    def __init__(self, *args: Any, **kwargs: Any) -> None:
        kwargs['option_btn_group_class'] = 'btn-group-vertical btn-group-toggle'
        super().__init__(*args, **kwargs)


__all__ = (
    'AppendedText',
    'PrependedText',
    'PrependedAppendedText',
    'Field',
    'Tab',
    'LCWizardHolder',
    'LCWizardSideTabHolder',
    'ButtonPrependedAppendedText',
    'CheckboxButtons',
    'RadioButtons',
    'RadioButtonsBlock',
    'RadioButtonsVertical',
)
