from trezor import config, ui, wire
from trezor.messages.Success import Success
from trezor.pin import pin_to_int
from trezor.ui.text import Text

from apps.common.confirm import require_confirm
from apps.common.layout import show_success
from apps.common.request_pin import (
    request_pin_and_sd_salt,
    request_pin_confirm,
    show_pin_invalid,
)

if False:
    from trezor.messages.ChangePin import ChangePin


async def change_pin(ctx: wire.Context, msg: ChangePin) -> Success:
    # confirm that user wants to change the pin
    await require_confirm_change_pin(ctx, msg)

    # get old pin
    curpin, salt = await request_pin_and_sd_salt(ctx, "Enter old PIN")

    # if changing pin, pre-check the entered pin before getting new pin
    if curpin and not msg.remove:
        if not config.check_pin(pin_to_int(curpin), salt):
            await show_pin_invalid(ctx)
            raise wire.PinInvalid("PIN invalid")

    # get new pin
    if not msg.remove:
        newpin = await request_pin_confirm(ctx)
    else:
        newpin = ""

    # write into storage
    if not config.change_pin(pin_to_int(curpin), pin_to_int(newpin), salt, salt):
        await show_pin_invalid(ctx)
        raise wire.PinInvalid("PIN invalid")

    if newpin:
        if curpin:
            msg_screen = "changed your PIN."
            msg_wire = "PIN changed"
        else:
            msg_screen = "enabled PIN protection."
            msg_wire = "PIN enabled"
    else:
        msg_screen = "disabled PIN protection."
        msg_wire = "PIN removed"

    await show_success(ctx, ("You have successfully", msg_screen))
    return Success(message=msg_wire)


def require_confirm_change_pin(ctx: wire.Context, msg: ChangePin) -> None:
    has_pin = config.has_pin()

    if msg.remove and has_pin:  # removing pin
        text = Text("Remove PIN", ui.ICON_CONFIG)
        text.normal("Do you really want to")
        text.bold("disable PIN protection?")
        return require_confirm(ctx, text)

    if not msg.remove and has_pin:  # changing pin
        text = Text("Change PIN", ui.ICON_CONFIG)
        text.normal("Do you really want to")
        text.bold("change your PIN?")
        return require_confirm(ctx, text)

    if not msg.remove and not has_pin:  # setting new pin
        text = Text("Enable PIN", ui.ICON_CONFIG)
        text.normal("Do you really want to")
        text.bold("enable PIN protection?")
        return require_confirm(ctx, text)

    # removing non-existing PIN
    raise wire.ProcessError("PIN protection already disabled")
