# Released under the MIT License. See LICENSE for details.
#
"""Provides a popup window to continue a game."""

from __future__ import annotations

import weakref
from typing import TYPE_CHECKING

import bauiv1 as bui

if TYPE_CHECKING:
    from typing import Any, Callable

    import bascenev1 as bs


class ContinuesWindow(bui.Window):
    """A window to continue a game."""

    def __init__(
        self,
        activity: bs.Activity,
        cost: int,
        continue_call: Callable[[], Any],
        cancel_call: Callable[[], Any],
    ):
        assert bui.app.classic is not None
        self._activity = weakref.ref(activity)
        self._cost = cost
        self._continue_call = continue_call
        self._cancel_call = cancel_call
        self._start_count = self._count = 20
        self._width = 300
        self._height = 200
        self._transitioning_out = False
        super().__init__(
            bui.containerwidget(
                size=(self._width, self._height),
                background=False,
                toolbar_visibility='menu_currency',
                transition='in_scale',
                scale=1.5,
            )
        )
        txt = (
            bui.Lstr(resource='continuePurchaseText')
            .evaluate()
            .split('${PRICE}')
        )
        t_left = txt[0]
        t_left_width = bui.get_string_width(t_left, suppress_warning=True)
        t_price = bui.charstr(bui.SpecialChar.TICKET) + str(self._cost)
        t_price_width = bui.get_string_width(t_price, suppress_warning=True)
        t_right = txt[-1]
        t_right_width = bui.get_string_width(t_right, suppress_warning=True)
        width_total_half = (t_left_width + t_price_width + t_right_width) * 0.5

        bui.textwidget(
            parent=self._root_widget,
            text=t_left,
            flatness=1.0,
            shadow=1.0,
            size=(0, 0),
            h_align='left',
            v_align='center',
            position=(self._width * 0.5 - width_total_half, self._height - 30),
        )
        bui.textwidget(
            parent=self._root_widget,
            text=t_price,
            flatness=1.0,
            shadow=1.0,
            color=(0.2, 1.0, 0.2),
            size=(0, 0),
            position=(
                self._width * 0.5 - width_total_half + t_left_width,
                self._height - 30,
            ),
            h_align='left',
            v_align='center',
        )
        bui.textwidget(
            parent=self._root_widget,
            text=t_right,
            flatness=1.0,
            shadow=1.0,
            size=(0, 0),
            h_align='left',
            v_align='center',
            position=(
                self._width * 0.5
                - width_total_half
                + t_left_width
                + t_price_width
                + 5,
                self._height - 30,
            ),
        )

        self._tickets_text_base: str | None
        self._tickets_text: bui.Widget | None
        if not bui.app.classic.ui.use_toolbars:
            self._tickets_text_base = bui.Lstr(
                resource='getTicketsWindow.youHaveShortText',
                fallback_resource='getTicketsWindow.youHaveText',
            ).evaluate()
            self._tickets_text = bui.textwidget(
                parent=self._root_widget,
                text='',
                flatness=1.0,
                color=(0.2, 1.0, 0.2),
                shadow=1.0,
                position=(
                    self._width * 0.5 + width_total_half,
                    self._height - 50,
                ),
                size=(0, 0),
                scale=0.35,
                h_align='right',
                v_align='center',
            )
        else:
            self._tickets_text_base = None
            self._tickets_text = None

        self._counter_text = bui.textwidget(
            parent=self._root_widget,
            text=str(self._count),
            color=(0.7, 0.7, 0.7),
            scale=1.2,
            size=(0, 0),
            big=True,
            position=(self._width * 0.5, self._height - 80),
            flatness=1.0,
            shadow=1.0,
            h_align='center',
            v_align='center',
        )
        self._cancel_button = bui.buttonwidget(
            parent=self._root_widget,
            position=(30, 30),
            size=(120, 50),
            label=bui.Lstr(resource='endText', fallback_resource='cancelText'),
            autoselect=True,
            enable_sound=False,
            on_activate_call=self._on_cancel_press,
        )
        self._continue_button = bui.buttonwidget(
            parent=self._root_widget,
            label=bui.Lstr(resource='continueText'),
            autoselect=True,
            position=(self._width - 130, 30),
            size=(120, 50),
            on_activate_call=self._on_continue_press,
        )
        bui.containerwidget(
            edit=self._root_widget,
            cancel_button=self._cancel_button,
            start_button=self._continue_button,
            selected_child=self._cancel_button,
        )

        self._counting_down = True
        self._countdown_timer = bui.AppTimer(
            1.0, bui.WeakCall(self._tick), repeat=True
        )

        # If there is foreground activity, suspend it.
        bui.app.classic.pause()
        self._tick()

    def __del__(self) -> None:
        # If there is suspended foreground activity, resume it.
        assert bui.app.classic is not None
        bui.app.classic.resume()

    def _tick(self) -> None:
        plus = bui.app.plus
        assert plus is not None

        # if our target activity is gone or has ended, go away
        activity = self._activity()
        if activity is None or activity.has_ended():
            self._on_cancel()
            return

        if plus.get_v1_account_state() == 'signed_in':
            sval = bui.charstr(bui.SpecialChar.TICKET) + str(
                plus.get_v1_account_ticket_count()
            )
        else:
            sval = '?'
        if self._tickets_text is not None:
            assert self._tickets_text_base is not None
            bui.textwidget(
                edit=self._tickets_text,
                text=self._tickets_text_base.replace('${COUNT}', sval),
            )

        if self._counting_down:
            self._count -= 1
            bui.getsound('tick').play()
            if self._count <= 0:
                self._on_cancel()
            else:
                bui.textwidget(edit=self._counter_text, text=str(self._count))

    def _on_cancel_press(self) -> None:
        # disallow for first second
        if self._start_count - self._count < 2:
            bui.getsound('error').play()
        else:
            self._on_cancel()

    def _on_continue_press(self) -> None:
        from bastd.ui import getcurrency

        plus = bui.app.plus
        assert plus is not None

        # Disallow for first second.
        if self._start_count - self._count < 2:
            bui.getsound('error').play()
        else:
            # If somehow we got signed out...
            if plus.get_v1_account_state() != 'signed_in':
                bui.screenmessage(
                    bui.Lstr(resource='notSignedInText'), color=(1, 0, 0)
                )
                bui.getsound('error').play()
                return

            # If it appears we don't have enough tickets, offer to buy more.
            tickets = plus.get_v1_account_ticket_count()
            if tickets < self._cost:
                # FIXME: Should we start the timer back up again after?
                self._counting_down = False
                bui.textwidget(edit=self._counter_text, text='')
                bui.getsound('error').play()
                getcurrency.show_get_tickets_prompt()
                return
            if not self._transitioning_out:
                bui.getsound('swish').play()
                self._transitioning_out = True
                bui.containerwidget(
                    edit=self._root_widget, transition='out_scale'
                )
                self._continue_call()

    def _on_cancel(self) -> None:
        if not self._transitioning_out:
            bui.getsound('swish').play()
            self._transitioning_out = True
            bui.containerwidget(edit=self._root_widget, transition='out_scale')
            self._cancel_call()
