defmodule Raxol.UI.Components.Input.TextFieldTest do
  use ExUnit.Case, async: true

  alias Raxol.UI.Components.Input.TextField
  alias Raxol.Core.Renderer.Element

  defp create_state(props) do
    state = TextField.init(props)
    state = Map.put_new(state, :style, %{})
    Map.put_new(state, :type, :text_field)
  end

  describe "theming, style, and lifecycle" do
    test "applies style and theme props to text field" do
      theme_map = %{
        text_field: %{
          border: "2px solid #00ff00",
          color: "#123456",
          layout: %{}
        }
      }

      style_prop = %{border_radius: "8px", color: "#654321"}

      state =
        create_state(%{value: "Styled", theme: theme_map, style: style_prop})

      rendered_element = TextField.render(state, %{theme: theme_map})

      assert %Element{attributes: rendered_attrs_list} = rendered_element
      actual_merged_style = Keyword.get(rendered_attrs_list, :style, %{})

      # Prop style assertions
      assert actual_merged_style.color == "#654321"
      assert actual_merged_style.border_radius == "8px"

      # Check for theme's border. Given the warning "Theme missing component style for :text_field",
      # we expect this to be nil for now. Once the theme application is fixed in the component,
      # this assertion should be updated to check for the actual themed border.
      assert Map.get(actual_merged_style, :border) == "2px solid #00ff00"
    end

    test "mount/1 and unmount/1 return state unchanged" do
      state = create_state(%{value: "foo"})
      assert TextField.mount(state) == {state, []}
      assert TextField.unmount(state) == state
    end
  end

  describe "render/2" do
    test "renders value and placeholder" do
      state = create_state(%{value: "Hello"})

      rendered =
        TextField.render(state, %{theme: %{text_field: %{layout: %{}}}})

      [text_elem] = rendered.children
      assert text_elem.tag == :text
      assert String.trim(text_elem.content) == "Hello"

      state2 = create_state(%{value: "", placeholder: "Type here"})

      rendered2 =
        TextField.render(state2, %{theme: %{text_field: %{layout: %{}}}})

      [text_elem2] = rendered2.children
      assert text_elem2.tag == :text
      assert String.trim(text_elem2.content) == "Type here"
      assert text_elem2.attributes[:color] == "#888"
      assert :italic in (text_elem2.attributes[:text_decoration] || [])
    end

    test "renders masked value if secret is true" do
      state = create_state(%{value: "secret", secret: true})

      rendered =
        TextField.render(state, %{theme: %{text_field: %{layout: %{}}}})

      [text_elem] = rendered.children
      assert text_elem.tag == :text
      assert String.trim(text_elem.content) == String.duplicate("•", 6)
    end
  end
end
