defmodule Towerops.Accounts.PolicyVersionTest do
  use Towerops.DataCase, async: true

  alias Towerops.Accounts.PolicyVersion

  @valid_attrs %{
    policy_type: "privacy_policy",
    version: "1.0",
    content: "This is the full privacy policy content.",
    effective_date: ~U[2025-01-01 00:00:00Z]
  }

  describe "policy_types/0" do
    test "returns list of valid policy types" do
      assert PolicyVersion.policy_types() == ["privacy_policy", "terms_of_service"]
    end
  end

  describe "changeset/2" do
    test "valid changeset with all required fields" do
      changeset = PolicyVersion.changeset(%PolicyVersion{}, @valid_attrs)

      assert changeset.valid?
    end

    test "requires policy_type" do
      attrs = Map.delete(@valid_attrs, :policy_type)
      changeset = PolicyVersion.changeset(%PolicyVersion{}, attrs)

      refute changeset.valid?
      assert "can't be blank" in errors_on(changeset).policy_type
    end

    test "requires version" do
      attrs = Map.delete(@valid_attrs, :version)
      changeset = PolicyVersion.changeset(%PolicyVersion{}, attrs)

      refute changeset.valid?
      assert "can't be blank" in errors_on(changeset).version
    end

    test "requires content" do
      attrs = Map.delete(@valid_attrs, :content)
      changeset = PolicyVersion.changeset(%PolicyVersion{}, attrs)

      refute changeset.valid?
      assert "can't be blank" in errors_on(changeset).content
    end

    test "requires effective_date" do
      attrs = Map.delete(@valid_attrs, :effective_date)
      changeset = PolicyVersion.changeset(%PolicyVersion{}, attrs)

      refute changeset.valid?
      assert "can't be blank" in errors_on(changeset).effective_date
    end

    test "rejects invalid policy_type" do
      attrs = Map.put(@valid_attrs, :policy_type, "invalid_type")
      changeset = PolicyVersion.changeset(%PolicyVersion{}, attrs)

      refute changeset.valid?
      assert "is invalid" in errors_on(changeset).policy_type
    end

    test "accepts privacy_policy as policy_type" do
      attrs = Map.put(@valid_attrs, :policy_type, "privacy_policy")
      changeset = PolicyVersion.changeset(%PolicyVersion{}, attrs)

      assert changeset.valid?
    end

    test "accepts terms_of_service as policy_type" do
      attrs = Map.put(@valid_attrs, :policy_type, "terms_of_service")
      changeset = PolicyVersion.changeset(%PolicyVersion{}, attrs)

      assert changeset.valid?
    end

    test "rejects empty version" do
      attrs = Map.put(@valid_attrs, :version, "")
      changeset = PolicyVersion.changeset(%PolicyVersion{}, attrs)

      refute changeset.valid?
      assert "can't be blank" in errors_on(changeset).version
    end

    test "rejects version longer than 20 characters" do
      attrs = Map.put(@valid_attrs, :version, String.duplicate("a", 21))
      changeset = PolicyVersion.changeset(%PolicyVersion{}, attrs)

      refute changeset.valid?
      assert "should be at most 20 character(s)" in errors_on(changeset).version
    end

    test "accepts version at maximum length of 20 characters" do
      attrs = Map.put(@valid_attrs, :version, String.duplicate("a", 20))
      changeset = PolicyVersion.changeset(%PolicyVersion{}, attrs)

      assert changeset.valid?
    end

    test "rejects content shorter than 10 characters" do
      attrs = Map.put(@valid_attrs, :content, "short")
      changeset = PolicyVersion.changeset(%PolicyVersion{}, attrs)

      refute changeset.valid?
      assert "should be at least 10 character(s)" in errors_on(changeset).content
    end

    test "accepts content at minimum length of 10 characters" do
      attrs = Map.put(@valid_attrs, :content, String.duplicate("a", 10))
      changeset = PolicyVersion.changeset(%PolicyVersion{}, attrs)

      assert changeset.valid?
    end
  end
end
