"""
Quick reference cheatsheet for regex syntax
"""

CHEATSHEET = r"""
╔══════════════════════════════════════════════════════════════════════════════╗
║                           REGEX CHEATSHEET                                   ║
╠══════════════════════════════════════════════════════════════════════════════╣
║                                                                              ║
║  BASICS                          QUANTIFIERS                                 ║
║  ───────                         ───────────                                 ║
║  .     Any character             *      Zero or more                         ║
║  \d    Digit (0-9)               +      One or more                          ║
║  \D    Not a digit               ?      Zero or one (optional)               ║
║  \w    Word char (a-z, 0-9, _)   {3}    Exactly 3                            ║
║  \W    Not a word char           {3,}   3 or more                            ║
║  \s    Whitespace                {3,5}  Between 3 and 5                      ║
║  \S    Not whitespace            *?     Zero or more (lazy)                  ║
║                                  +?     One or more (lazy)                   ║
║                                                                              ║
║  ANCHORS                         GROUPS                                      ║
║  ───────                         ──────                                      ║
║  ^     Start of string           (abc)    Capture group                      ║
║  $     End of string             (?:abc)  Non-capture group                  ║
║  \b    Word boundary             (?P<n>)  Named group                        ║
║  \B    Not word boundary         \1       Backreference                      ║
║                                                                              ║
║  CHARACTER CLASSES               LOOKAROUND (don't consume)                  ║
║  ─────────────────               ─────────────────────────                   ║
║  [abc]    a, b, or c             (?=...)  Lookahead (followed by)            ║
║  [^abc]   Not a, b, or c         (?!...)  Negative lookahead (not followed)  ║
║  [a-z]    Range a to z           (?<=...) Lookbehind (preceded by)           ║
║  [0-9]    Range 0 to 9           (?<!...) Negative lookbehind (not preceded) ║
║                                                                              ║
║  FLAGS                           SPECIAL                                     ║
║  ─────                           ───────                                     ║
║  (?i)     Case insensitive       |        OR (alternation)                   ║
║  (?m)     Multiline (^$ lines)   \        Escape special char                ║
║  (?s)     Dotall (. = newline)   (?:...)  Non-capture group                  ║
║                                                                              ║
║  COMMON PATTERNS                                                             ║
║  ───────────────                                                             ║
║  Email:     [a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}                   ║
║  URL:       https?://[^\s]+                                                  ║
║  Phone:     \d{3}[-.]?\d{3}[-.]?\d{4}                                        ║
║  IP:        \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}                               ║
║  Date:      \d{4}-\d{2}-\d{2}                                                ║
║                                                                              ║
║  ESCAPING - These need \\ to match literally:                                ║
║  . * + ? ^ $ { } [ ] ( ) | \\                                                ║
║                                                                              ║
╚══════════════════════════════════════════════════════════════════════════════╝
"""

QUICK_REF = {
    "digit": {"pattern": r"\d", "example": "Matches: 0, 1, 2, ..., 9"},
    "digits": {"pattern": r"\d+", "example": "Matches: 42, 123, 9999"},
    "word": {"pattern": r"\w+", "example": "Matches: hello, test_123"},
    "whitespace": {"pattern": r"\s+", "example": "Matches: spaces, tabs, newlines"},
    "any": {"pattern": r".", "example": "Matches any single character"},
    "start": {"pattern": r"^", "example": "^hello matches 'hello world'"},
    "end": {"pattern": r"$", "example": "world$ matches 'hello world'"},
    "boundary": {"pattern": r"\b", "example": r"\bcat\b matches 'cat' not 'catch'"},
    "optional": {"pattern": r"?", "example": "colou?r matches 'color' and 'colour'"},
    "or": {"pattern": r"|", "example": "cat|dog matches 'cat' or 'dog'"},
    "group": {"pattern": r"(...)", "example": "(ab)+ matches 'abab'"},
    "range": {"pattern": r"[a-z]", "example": "[a-z] matches any lowercase letter"},
    "not": {"pattern": r"[^...]", "example": "[^0-9] matches non-digits"},
    "repeat": {"pattern": r"{n,m}", "example": r"\d{2,4} matches 2-4 digits"},
    "lazy": {"pattern": r"*? +?", "example": ".*? matches as few as possible"},
    "escape": {"pattern": r"\\", "example": r"\. matches literal dot"},
    "lookahead": {"pattern": r"(?=...)", "example": r"foo(?=bar) matches 'foo' only if followed by 'bar'"},
    "lookbehind": {"pattern": r"(?<=...)", "example": r"(?<=@)\w+ matches word after @ symbol"},
    "negative-lookahead": {"pattern": r"(?!...)", "example": r"foo(?!bar) matches 'foo' not followed by 'bar'"},
    "negative-lookbehind": {"pattern": r"(?<!...)", "example": r"(?<!un)happy matches 'happy' not preceded by 'un'"},
}

ESCAPE_GUIDE = r"""
WHAT TO ESCAPE
══════════════

ALWAYS escape these to match them literally:
  .  →  \\.     (dot)
  *  →  \\*     (asterisk)
  +  →  \\+     (plus)
  ?  →  \\?     (question mark)
  ^  →  \\^     (caret)
  $  →  \\$     (dollar)
  |  →  \\|     (pipe)
  \\  →  \\\\   (backslash)
  [  →  \\[     (bracket)
  ]  →  \\]     (bracket)
  (  →  \\(     (parenthesis)
  )  →  \\)     (parenthesis)
  {  →  \\{     (brace)
  }  →  \\}     (brace)

INSIDE CHARACTER CLASS [...]:
  Only these need escaping: ^ - ] \\

  [\\^] → literal caret
  [\\-] → literal hyphen (or put at start/end: [-a] or [a-])
  [\\]] → literal closing bracket
  [\\\\] → literal backslash

COMMON MISTAKES:
  www.google.com  →  www\\.google\\.com  (escape the dots!)
  $100            →  \\$100              (escape the dollar!)
  file.txt        →  file\\.txt          (escape the dot!)
"""


def print_cheatsheet():
    """Print the full cheatsheet"""
    print(CHEATSHEET)


def print_escape_guide():
    """Print the escape guide"""
    print(ESCAPE_GUIDE)


def quick_lookup(term):
    """Quick lookup of a regex concept"""
    term = term.lower().strip()

    if term in QUICK_REF:
        ref = QUICK_REF[term]
        return {
            "term": term,
            "pattern": ref["pattern"],
            "example": ref["example"]
        }

    # Fuzzy match
    for key in QUICK_REF:
        if term in key or key in term:
            ref = QUICK_REF[key]
            return {
                "term": key,
                "pattern": ref["pattern"],
                "example": ref["example"]
            }

    return None
