from pathlib import Path
from sys import stderr
from typing import List, Optional, Union

from rich.console import Console
from rich.panel import Panel
from rich.text import Text
from rich.theme import Theme

from clown_sort.config import Config

ARROW_BULLET = '➤ '
INDENTED_BULLET = f"  {ARROW_BULLET}"
NOT = Text('').append('(Not) ', style='dim')
WARNING = Text('').append('WARNING', style='bright_yellow').append(': ')

### Printing ###
BYTES = 'color(100) dim'
BYTES_NO_DIM = 'color(100)'
BYTES_BRIGHTEST = 'color(220)'
BYTES_BRIGHTER = 'orange1'
BYTES_HIGHLIGHT = 'color(136)'
DARK_GREY = 'color(236)'
GREY = 'color(239)'
GREY_ADDRESS = 'color(238)'
PEACH = 'color(215)'
PURPLE = 'color(20)'

COLOR_THEME_DICT = {
    # colors
    'dark_orange': 'color(58)',
    'grey': GREY,
    'grey.dark': DARK_GREY,
    'grey.dark_italic': f"{DARK_GREY} italic",
    'grey.darker_italic': 'color(8) dim italic',
    'grey.darkest': 'color(235) dim',
    'grey.light': 'color(248)',
    'mild_warning': 'color(228) dim',
    'off_white': 'color(245)',
    'social_media': 'color(82)',
    'author': 'color(178)',
    'sort_destination': 'magenta',
    'sort_folder': 'color(62)'
}

COLOR_THEME = Theme(COLOR_THEME_DICT)
INDENT_SPACES = 4

# Main rich text output object.
console = Console(theme=COLOR_THEME, color_system='256')
stderr_console = Console(theme=COLOR_THEME, color_system='256', file=stderr)


def indented_bullet(msg: Union[str, Text], style: Optional[str] = None) -> Text:
    return Text('  ') + bullet_text(msg, style)


def bullet_text(msg: Union[str, Text], style: Optional[str] = None) -> Text:
    if isinstance(msg, str):
        msg = Text(msg, style=style)

    return Text(ARROW_BULLET).append(msg)


def print_dim_bullet(msg: Union[str, Text]) -> None:
    console.print(indented_bullet(msg), style='dim')


def print_headline(headline: str) -> None:
    console.line(2)
    console.print(Panel(headline, style='reverse', width=60))
    console.line()


def print_indented(msg: str, style: str = '', indent_level: int = 1) -> None:
    console.print(f"{indent_whitespace(indent_level)}{msg}", style=style)


def ask_for_confirmation(msg: Text) -> None:
    """Primitive user confirmation"""
    console.print(msg.append("\n('y' to continue, any other key to exit)", style='white dim'))

    if input().lower() != 'y':
        exit()


def indent_whitespace(indent_level: int = 1):
    return ' ' * INDENT_SPACES * indent_level


def copying_file_log_message(basename: str, new_file: Path) -> Text:
    return _file_operation_log_message(basename, new_file, 'Copying')


def moving_file_log_message(basename: str, new_file: Path) -> Text:
    return _file_operation_log_message(basename, new_file, 'Moving processed file')


def mild_warning(msg: str) -> None:
    console.print(indented_bullet(Text(msg, style='mild_warning')))


def warning_text(text: Union[str, Text]) -> Text:
    msg = Text('').append(f"WARNING", style='bright_yellow').append(": ")

    if isinstance(text, Text):
        return msg + text
    else:
        return msg.append(text)


def comma_join(strs: List[str], style: str) -> Text:
    return Text(", ").join([Text(s, style) for s in strs])


def _file_operation_log_message(basename: str, new_file: Path, log_msg: str) -> Text:
    log_msg += ' '
    log_msg = Text(log_msg)

    if Config.dry_run:
        log_msg = NOT + log_msg

    txt = Text(f"➤ ") + log_msg + Text(basename, style='color(221)')
    txt.append(' to ').append(str(new_file), style='cyan')
    return txt
