from dataclasses import dataclass, field
from enum import Enum
from typing import Any, NotRequired, Self, TypedDict, override

from archinstall.lib.models.config import SubConfig
from archinstall.lib.models.users import Password, User
from archinstall.lib.translationhandler import tr


class U2FLoginConfigSerialization(TypedDict):
	u2f_login_method: str
	passwordless_sudo: bool


class AuthenticationSerialization(TypedDict):
	u2f_config: NotRequired[U2FLoginConfigSerialization]


class U2FLoginMethod(Enum):
	Passwordless = 'passwordless'
	SecondFactor = 'second_factor'

	def display_value(self) -> str:
		match self:
			case U2FLoginMethod.Passwordless:
				return tr('Passwordless login')
			case U2FLoginMethod.SecondFactor:
				return tr('Second factor login')
			case _:
				raise ValueError(f'Unknown type: {self}')


@dataclass
class U2FLoginConfiguration:
	u2f_login_method: U2FLoginMethod
	passwordless_sudo: bool = False

	def json(self) -> U2FLoginConfigSerialization:
		return {
			'u2f_login_method': self.u2f_login_method.value,
			'passwordless_sudo': self.passwordless_sudo,
		}

	@classmethod
	def parse_arg(cls, args: U2FLoginConfigSerialization) -> Self | None:
		u2f_login_method = args.get('u2f_login_method')

		if not u2f_login_method:
			return None

		u2f_config = cls(u2f_login_method=U2FLoginMethod(u2f_login_method))

		u2f_config.u2f_login_method = U2FLoginMethod(u2f_login_method)

		if passwordless_sudo := args.get('passwordless_sudo') is not None:
			u2f_config.passwordless_sudo = passwordless_sudo

		return u2f_config


@dataclass
class AuthenticationConfiguration(SubConfig):
	root_enc_password: Password | None = None
	users: list[User] = field(default_factory=list)
	u2f_config: U2FLoginConfiguration | None = None

	@classmethod
	def parse_arg(cls, args: dict[str, Any]) -> Self:
		auth_config = cls()

		if (u2f_config := args.get('u2f_config')) is not None:
			auth_config.u2f_config = U2FLoginConfiguration.parse_arg(u2f_config)

		if enc_password := args.get('root_enc_password'):
			auth_config.root_enc_password = Password(enc_password=enc_password)

		return auth_config

	@override
	def json(self) -> AuthenticationSerialization:
		config: AuthenticationSerialization = {}

		if self.u2f_config:
			config['u2f_config'] = self.u2f_config.json()

		return config

	@override
	def summary(self) -> list[str]:
		out: list[str] = []

		if self.root_enc_password:
			out.append(tr('Root password set'))

		if self.users:
			out.append(tr('Configured {} user(s)').format(len(self.users)))

		if self.u2f_config:
			out.append(tr('U2F set up'))

		return out

	def has_superuser(self) -> bool:
		return any(u.sudo for u in self.users)

	def has_regular_user(self) -> bool:
		return len(self.users) > 0
