# ruff: noqa: D100, D101, D102, D103, D104, D107
from __future__ import annotations

import datetime
from functools import cached_property
from typing import TYPE_CHECKING, Any, Sequence

from kivy.clock import Clock
from kivy.metrics import dp
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.stencilview import StencilView
from kivy.uix.widget import Widget
from ubo_gui.app import UboApp

from ubo_app.store import autorun

if TYPE_CHECKING:
    from ubo_app.store.status_icons import IconState


class MenuAppFooter(UboApp):
    def _set_temperature_value(self: MenuAppFooter, value: float | None = None) -> None:
        if value is None:
            self.temperature.text = '-'
        else:
            self.temperature.text = f'{value:0.1f}°C'

    @cached_property
    def temperature_widget(self: MenuAppFooter) -> BoxLayout:
        layout = BoxLayout(
            orientation='horizontal',
            spacing=0,
            padding=0,
            size_hint=(None, 1),
        )

        self.temperature = Label(font_size=dp(14), size_hint=(None, 1), valign='middle')
        self.temperature.bind(
            texture_size=lambda temperature, texture_size: setattr(
                temperature,
                'width',
                texture_size[0],
            )
            or setattr(layout, 'width', temperature.width + dp(12)),
        )

        autorun(lambda state: state.sensors.temperature.value)(
            self._set_temperature_value,
        )

        icon = Label(
            text='device_thermostat',
            color='#ffffff',
            font_name='material_symbols',
            font_size=dp(16),
            font_features='fill=0',
            size_hint=(None, 1),
            width=dp(12),
        )
        layout.add_widget(icon)
        layout.add_widget(self.temperature)

        return layout

    def _set_light_value(self: MenuAppFooter, value: float | None = None) -> None:
        if value is None:
            self.light.color = (0.5, 0, 0, 1)
        else:
            v = min(value, 140) / 140
            self.light.color = (1, 1, 1, v)

    @cached_property
    def light_widget(self: MenuAppFooter) -> Label:
        self.light = Label(
            text='light_mode',
            color='#ffffff',
            font_name='material_symbols',
            font_size=dp(16),
            font_features='fill=0',
            size_hint=(None, 1),
            width=dp(16),
        )
        self.light.bind(
            texture_size=lambda light, texture_size: setattr(
                light,
                'width',
                texture_size[0],
            ),
        )

        autorun(lambda state: state.sensors.light.value)(self._set_light_value)

        return self.light

    @cached_property
    def clock_widget(self: MenuAppFooter) -> Label:
        clock = Label(font_size=dp(20), size_hint=(None, 1), valign='middle')
        clock.bind(
            texture_size=lambda clock, texture_size: setattr(
                clock,
                'width',
                texture_size[0],
            ),
        )
        local_timzone = datetime.datetime.now(datetime.timezone.utc).astimezone().tzinfo

        def now() -> datetime.datetime:
            return datetime.datetime.now(local_timzone)

        def set_value(_: int | None = None) -> None:
            clock.text = now().strftime('%H:%M')

        def update(_: int | None = None) -> None:
            set_value()
            now_ = now()
            Clock.schedule_once(
                update,
                60 - now_.second - now_.microsecond / 1000000 + 0.05,
            )

        update()

        return clock

    def _render_icons(
        self: MenuAppFooter,
        selector_result: Sequence[IconState],
    ) -> None:
        icons = selector_result
        self.icons_layout.clear_widgets()
        for icon in list(reversed(icons))[:4]:
            label = Label(
                text=icon.symbol,
                color=icon.color,
                font_name='material_symbols',
                font_size=dp(20),
                font_features='fill=0',
                size_hint=(None, 1),
                width=dp(22),
            )
            self.icons_layout.add_widget(label)
        self.icons_layout.add_widget(Widget(size_hint=(None, 1), width=dp(2)))
        self.icons_layout.bind(minimum_width=self.icons_layout.setter('width'))

    def _handle_depth_change(self: MenuAppFooter, _: Sequence[str]) -> None:
        is_fullscreen = False
        if not is_fullscreen:
            if self.normal_footer_layout in self.footer_layout.children:
                self.footer_layout.remove_widget(self.normal_footer_layout)
                self.footer_layout.add_widget(self.home_footer_layout)
        elif self.home_footer_layout in self.footer_layout.children:
            self.footer_layout.remove_widget(self.home_footer_layout)
            self.footer_layout.add_widget(self.normal_footer_layout)

    def set_icons_layout_x(self: MenuAppFooter, *_: list[Any]) -> None:
        self.icons_layout.x = (
            self.icons_widget.x + self.icons_widget.width - self.icons_layout.width
        )

    @cached_property
    def footer(self: MenuAppFooter) -> Widget | None:
        self.footer_layout = BoxLayout()

        self.normal_footer_layout = BoxLayout(
            orientation='horizontal',
            spacing=0,
            padding=0,
        )
        self.normal_footer_layout.add_widget(
            Label(
                text='reply',
                font_name='material_symbols',
                font_size=dp(20),
                font_features='fill=1',
                size_hint=(None, 1),
            ),
        )
        self.normal_footer_layout.add_widget(Widget(size_hint=(1, 1)))

        self.home_footer_layout = BoxLayout(
            orientation='horizontal',
            spacing=0,
            padding=0,
        )

        self.home_footer_layout.add_widget(Widget(size_hint=(None, 1), width=dp(2)))
        self.home_footer_layout.add_widget(self.clock_widget)
        self.home_footer_layout.add_widget(Widget(size_hint=(None, 1), width=dp(2)))
        self.home_footer_layout.add_widget(self.temperature_widget)
        self.home_footer_layout.add_widget(Widget(size_hint=(None, 1), width=dp(2)))
        self.home_footer_layout.add_widget(self.light_widget)
        self.home_footer_layout.add_widget(Widget(size_hint=(None, 1), width=dp(2)))

        self.icons_widget = StencilView(size_hint=(1, 1))
        self.home_footer_layout.add_widget(self.icons_widget)

        self.icons_layout = BoxLayout(
            orientation='horizontal',
            spacing=dp(4),
            padding=0,
        )
        self.icons_widget.add_widget(self.icons_layout)

        self.icons_widget.bind(
            width=self.set_icons_layout_x,
            x=self.set_icons_layout_x,
            height=self.icons_layout.setter('height'),
            y=self.icons_layout.setter('y'),
        )
        self.icons_layout.bind(
            width=self.set_icons_layout_x,
            x=self.set_icons_layout_x,
        )

        autorun(lambda state: state.status_icons.icons)(self._render_icons)

        autorun(lambda state: state.main.path)(self._handle_depth_change)

        self.footer_layout.add_widget(self.home_footer_layout)

        return self.footer_layout
