"""SRGB color class."""
import re
from . import color_names
from .. import srgb as base
from ... import parse
from ... import util
from typing import Optional, Union, Any, Tuple, TYPE_CHECKING
from ...util import MutableVector

if TYPE_CHECKING:  # pragma: no cover
    from ...color import Color

RE_COMPRESS = re.compile(r'(?i)^#({hex})\1({hex})\2({hex})\3(?:({hex})\4)?$'.format(**parse.COLOR_PARTS))


class SRGB(base.SRGB):
    """SRGB class."""

    MATCH = re.compile(
        r"""(?xi)
        (?:
            # RGB syntax
            \brgba?\(\s*
            (?:
                # Space separated format
                (?:
                    # Float form
                    (?:{float}{space}){{2}}{float} |
                    # Percent form
                    (?:{percent}{space}){{2}}{percent}
                )({slash}(?:{percent}|{float}))? |
                # Comma separated format
                (?:
                    # Float form
                    (?:{float}{comma}){{2}}{float} |
                    # Percent form
                    (?:{percent}{comma}){{2}}{percent}
                )({comma}(?:{percent}|{float}))?
            )
            \s*\) |
            # Hex syntax
            \#(?:{hex}{{6}}(?:{hex}{{2}})?|{hex}{{3}}(?:{hex})?)\b |
            # Names
            \b(?<!\#)[a-z]{{3,}}(?!\()\b
        )
        """.format(**parse.COLOR_PARTS)
    )

    def to_string(
        self,
        parent: 'Color',
        *,
        alpha: Optional[bool] = None,
        precision: Optional[int] = None,
        fit: Union[bool, str] = True,
        none: bool = False,
        **kwargs: Any
    ) -> str:
        """Convert to CSS."""

        if precision is None:
            precision = parent.PRECISION

        options = kwargs
        if options.get("color"):
            return super().to_string(parent, alpha=alpha, precision=precision, fit=fit, none=none, **kwargs)

        a = util.no_nan(self.alpha) if not none else self.alpha
        alpha = alpha is not False and (alpha is True or a < 1.0 or util.is_nan(a))
        compress = options.get("compress", False)

        # Handle hex and color names
        value = ''
        if options.get("hex") or options.get("names"):
            h = self._get_hex(parent, upper=options.get("upper", False), alpha=alpha, fit=fit)
            if options.get("hex"):
                value = h
                if compress:
                    m = RE_COMPRESS.match(value)
                    if m:
                        value = m.expand(r"#\1\2\3\4") if alpha else m.expand(r"#\1\2\3")
            if options.get("names"):
                length = len(h) - 1
                index = int(length / 4)
                if length in (8, 4) and h[-index:].lower() == ("f" * index):
                    h = h[:-index]
                n = color_names.hex2name(h)
                if n is not None:
                    value = n

        # Handle normal RGB function format.
        if not value:
            percent = options.get("percent", False)
            comma = options.get("comma", False)
            factor = 100.0 if percent else 255.0

            method = None if not isinstance(fit, str) else fit
            coords = parent.fit(method=method).coords() if fit else self.coords()
            if not none:
                coords = util.no_nans(coords)

            fmt = util.fmt_percent if percent else util.fmt_float
            if alpha: