Repository: pallets/click

Issue:
Flag option with secondary opts: show_default=True does not show value from default_map in "help" output
I'm setting the `default_map` from a config file, and it seems the values from the `default_map` are not correctly shown in the `--help` output if I set `show_default=True` on my option.

My Option looks like this:

```python
@click.option(
    "--long/--short",
    "-l/-s",
    is_flag=True,
    show_default=True,
    help="show additional information like size and creation date",
)
```

I initialize the `default_map` with a custom command class that I attach via the `@click.command` decorator like this `@click.command(cls=ConfigAwareCommand)`

```python
from click import Command as _Command


class ConfigAwareCommand(_Command):
    def __init__(self, *args, **kwargs):
        kwargs["context_settings"] = {
            "default_map": CONFIG.get_cli_command_defaults(kwargs["name"])
        }
        super().__init__(*args, **kwargs)

```

The `default_map` value is in my example `{'long': True}`. In the `--help` output, the default value is shown like this

```
  -l, --long / -s, --short        show additional information like size and
                                  creation date  [default: short]
```

When executing the command, the default value from the `default_map` is used correctly (`long` defaults to `True`).

During debugging, I might have found the culprit inside [src/click/core.py](https://github.com/pallets/click/blob/main/src/click/core.py#L2746)

```python
            elif self.is_bool_flag and self.secondary_opts:
                # For boolean flags that have distinct True/False opts,
                # use the opt without prefix instead of the value.
                default_string = _split_opt(
                    (self.opts if self.default else self.secondary_opts)[0]
                )[1]
```

As you can see, `self.default` is used instead of the `default_value` variable that is initialized [further above](https://github.com/pallets/click/blob/main/src/click/core.py#L2720) this code snippet.

If I change the part of the code above and use `default_value` instead of `self.default` the help output shows the correct default values from the `default_map`.

```python
            elif self.is_bool_flag and self.secondary_opts:
                # For boolean flags that have distinct True/False opts,
                # use the opt without prefix instead of the value.
                default_string = _split_opt(
                    (self.opts if default_value else self.secondary_opts)[0]
                )[1]
```

I am not sure if I do something wrong or if this is indeed a bug.

Environment:

- Python version: 3.10.12
- Click version: 8.1.7



Discussion:
Hi, I'm at PyCon 2024 and picked up this issue.  I wrote a unit tests to re-produce this issue and I believe this is a bug in latest main.  I also think the OP is correct about what is causing it, when I replace `self.default` with `default_value` in this line of `core.py` the tests pass: https://github.com/pallets/click/blob/9f63c3b477d444245b0cc21ac23c28f6e8f4c385/src/click/core.py#L2725

Resolving patch:
diff --git a/src/click/core.py b/src/click/core.py
--- a/src/click/core.py
+++ b/src/click/core.py
@@ -2800,7 +2800,7 @@ def _write_opts(opts: t.Sequence[str]) -> str:
                 # For boolean flags that have distinct True/False opts,
                 # use the opt without prefix instead of the value.
                 default_string = split_opt(
-                    (self.opts if self.default else self.secondary_opts)[0]
+                    (self.opts if default_value else self.secondary_opts)[0]
                 )[1]
             elif self.is_bool_flag and not self.secondary_opts and not default_value:
                 default_string = ""


Test patch:
diff --git a/tests/test_defaults.py b/tests/test_defaults.py
--- a/tests/test_defaults.py
+++ b/tests/test_defaults.py
@@ -59,3 +59,28 @@ def cli(y, f, v):
 
     result = runner.invoke(cli, ["-y", "-n", "-f", "-v", "-q"], standalone_mode=False)
     assert result.return_value == ((True, False), (True,), (1, -1))
+
+
+def test_flag_default_map(runner):
+    """test flag with default map"""
+
+    @click.group()
+    def cli():
+        pass
+
+    @cli.command()
+    @click.option("--name/--no-name", is_flag=True, show_default=True, help="name flag")
+    def foo(name):
+        click.echo(name)
+
+    result = runner.invoke(cli, ["foo"])
+    assert "False" in result.output
+
+    result = runner.invoke(cli, ["foo", "--help"])
+    assert "default: no-name" in result.output
+
+    result = runner.invoke(cli, ["foo"], default_map={"foo": {"name": True}})
+    assert "True" in result.output
+
+    result = runner.invoke(cli, ["foo", "--help"], default_map={"foo": {"name": True}})
+    assert "default: name" in result.output