import math
import random
import time

from imgui_bundle import imgui


class CRTFilter:
 def __init__(self):
  self.enabled = True

 def render(self, width: float, height: float):
  """
  [C: tests/test_theme_nerv_alert.py:test_alert_pulsing_render_active, tests/test_theme_nerv_alert.py:test_alert_pulsing_render_inactive, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_alert_pulsing_render, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_crt_filter_disabled, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_crt_filter_render]
  """
  if not self.enabled: return
  draw_list = imgui.get_foreground_draw_list()
  
  # 1. Enhanced Scanlines (Horizontal)
  # Vary thickness and alpha for a more "analog" feel
  for y in range(0, int(height), 2):
   # Thicker/Darker every 4 pixels
   is_major  = (y % 4 == 0)
   alpha     = 0.08 if is_major else 0.04
   thickness = 1.2  if is_major else 0.8
   s_color   = imgui.get_color_u32((0.0, 0.0, 0.0, alpha))
   draw_list.add_line((0.0, float(y)), (float(width), float(y)), s_color, thickness)
  
  # 2. Shadow Mask (Vertical)
  # Simulates aperture grille / phosphor strips
  m_color = imgui.get_color_u32((0.0, 0.0, 0.0, 0.05))
  for x in range(0, int(width), 3):
   draw_list.add_line((float(x), 0.0), (float(x), float(height)), m_color, 1.0)
  
  # 3. Enhanced Curved Vignette / Tube Curvature
  # Multiple rounded rectangles with increasing thickness and alpha
  v_steps = 20
  for i in range(v_steps):
   # Exponential alpha for smoother falloff
   alpha   = (i / v_steps) ** 3.0 * 0.25
   v_color = imgui.get_color_u32((0.0, 0.0, 0.0, alpha))
   # Inset and rounding grow to simulate tube curvature
   inset     = (v_steps - i) * 4.5
   rounding  = 60.0 + (v_steps - i) * 8.0
   thickness = 15.0
   
   if width > inset * 2.0 and height > inset * 2.0:
    draw_list.add_rect(
     (inset, inset), 
     (width - inset, height - inset), 
     v_color, 
     rounding, 
     0, 
     thickness
    )

  # 4. Subtle Random Noise / Static
  t = time.time()
  for _ in range(40):
   nx = random.uniform(0.0, width)
   ny = random.uniform(0.0, height)
   # Flickering noise
   n_alpha = random.uniform(0.01, 0.04) * (0.8 + 0.2 * math.sin(t * 60.0))
   n_color = imgui.get_color_u32((1.0, 1.0, 1.0, n_alpha))
   draw_list.add_rect_filled((nx, ny), (nx + 1.2, ny + 1.2), n_color)

class StatusFlicker:
 def get_alpha(self) -> float:
  # Modulate between 0.7 and 1.0 using sin wave
  """
  [C: tests/test_theme_nerv_fx.py:TestThemeNervFx.test_status_flicker_get_alpha]
  """
  return 0.85 + 0.15 * math.sin(time.time() * 20.0)

class AlertPulsing:
 def __init__(self):
  self.active = False

 def update(self, status: str):
  """
  [C: tests/test_spawn_interception_v2.py:MockDialog.wait, tests/test_theme_nerv_alert.py:test_alert_pulsing_update, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_alert_pulsing_update]
  """
  self.active = status.lower().startswith("error")

 def render(self, width: float, height: float):
  """
  [C: tests/test_theme_nerv_alert.py:test_alert_pulsing_render_active, tests/test_theme_nerv_alert.py:test_alert_pulsing_render_inactive, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_alert_pulsing_render, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_crt_filter_disabled, tests/test_theme_nerv_fx.py:TestThemeNervFx.test_crt_filter_render]
  """
  if not self.active:
   return
  draw_list = imgui.get_foreground_draw_list()
  # sin(t) is between -1 and 1
  # scale to 0 to 1: (sin(t) + 1) / 2
  # multiply by (0.2 - 0.05) = 0.15 and add 0.05
  alpha = 0.05 + 0.15 * ((math.sin(time.time() * 4.0) + 1.0) / 2.0)
  color = imgui.get_color_u32((1.0, 0.0, 0.0, alpha))
  draw_list.add_rect((0.0, 0.0), (width, height), color, 0.0, 0, 10.0)
