from __future__ import annotations

import typing

if typing.TYPE_CHECKING:
	from rich.console import Console


class Print:
	"""Class to handle print primitives"""

	@classmethod
	def info(cls, console: "Console", message: str, **kwargs) -> None:
		console.print(f"{message}", style="cyan", **kwargs)

	@classmethod
	def success(cls, console: "Console", message: str, **kwargs) -> None:
		console.print(f"✓ {message}", style="bold green", **kwargs)

	@classmethod
	def error(cls, console: "Console", message: str | Exception, **kwargs) -> None:
		console.print(f"✗ {message}", style="bold red", **kwargs)

	@classmethod
	def warn(cls, console: "Console", message: str, **kwargs) -> None:
		"""Non-fatal warning message."""
		console.print(f"! {message}", style="bold yellow", **kwargs)

	@classmethod
	def header(cls, console: "Console", title: str) -> None:
		"""Print a section header."""
		console.print(f"[bold cyan]{title}[/bold cyan]")

	@classmethod
	def field(cls, console: "Console", label: str, value: typing.Any, indent: int = 0) -> None:
		"""Print a labeled field with optional indentation."""
		spaces = "  " * indent
		console.print(f"{spaces}[bold]{label}:[/bold] {value}")


def print_plan_details(plan: dict[str, typing.Any], console: "Console") -> None:
	"""Pretty-print plan details using a rich Console instance."""
	Print.header(console, "Plan Details")
	Print.field(console, "Name", plan.get("name", "-"))
	Print.field(console, "Price", f"{fmt_inr(plan.get('price_inr'))} /mo")
	Print.field(console, "vCPUs", fmt_cpu(plan.get("vcpu")))
	Print.field(console, "Memory", fmt_gb(plan.get("memory")))
	Print.field(console, "Disk", fmt_gb(plan.get("disk")))


def print_full_plan_details(plan: dict[str, typing.Any], console: "Console") -> None:
	"""Print an extended set of plan fields like title, owner, prices, etc."""
	Print.header(console, "Current Plan")
	Print.field(console, "Title", plan.get("title", "-"))
	Print.field(console, "Name", plan.get("name", "-"))
	Print.field(console, "Owner", plan.get("owner", "-"))
	Print.field(console, "Modified By", plan.get("modified_by", "-"))
	Print.field(console, "Price INR", fmt_inr(plan.get("price_inr")))
	Print.field(console, "Price USD", plan.get("price_usd", "-"))
	Print.field(console, "Premium", "Yes" if plan.get("premium") else "No")
	Print.field(console, "Price/Day INR", fmt_inr(plan.get("price_per_day_inr")))
	Print.field(console, "Price/Day USD", plan.get("price_per_day_usd", "-"))


def show_usage(
	vcpu: str | float | int,
	mem_mb: str | float | int,
	disk_gb: str | float | int,
	free_mem_bytes: str | float | int,
	console: "Console",
) -> None:
	Print.header(console, "Server Usage")
	Print.field(console, "vCPU", fmt_cpu(vcpu))
	Print.field(console, "Memory Used", fmt_mb(mem_mb))
	Print.field(console, "Disk Used", fmt_gb(disk_gb, 2))
	# free_mem_bytes is bytes; show as MB
	if isinstance(free_mem_bytes, (int, float)):
		free_mb = free_mem_bytes / 1024 / 1024
	else:
		free_mb = free_mem_bytes
	Print.field(console, "Free Memory (avg 10m)", fmt_mb(free_mb))


# ---------- formatting helpers ----------
def _fmt_number(value: typing.Any, decimals: int = 0) -> str:
	"""Format numbers with thousand separators and optional decimals; strip trailing zeros."""
	if isinstance(value, (int, float)):
		# Round to desired precision to avoid long floats like 2.826424479...
		rounded = round(float(value), decimals)
		if decimals > 0:
			return f"{rounded:,.{decimals}f}".rstrip("0").rstrip(".")
		return f"{int(rounded):,}"
	return str(value)


def fmt_gb(value: typing.Any, decimals: int = 0) -> str:
	if value is None or value == "-":
		return "-"
	return f"{_fmt_number(value, decimals)} GB"


def fmt_mb(value: typing.Any, decimals: int = 2) -> str:
	if value is None or value == "-":
		return "-"
	return f"{_fmt_number(value, decimals)} MB"


def fmt_cpu(value: typing.Any, decimals: int = 2) -> str:
	if value is None or value == "-":
		return "-"
	return _fmt_number(value, decimals)


def fmt_inr(value: typing.Any) -> str:
	if value is None or value == "-":
		return "-"
	return f"₹{_fmt_number(value, 0)}"
