from __future__ import print_function

import csv
import json
import io
import re
from collections import namedtuple

try:
    from shutil import get_terminal_size
except ImportError:
    from .libs.get_terminal_size import get_terminal_size
    
from .utils import encode_str, decode_bytes
from .libs import windows_cmd_encoding
from .config import PYTHON_VERSION


def print_results(search_engines):
    '''Prints the search results.'''
    for engine in search_engines:
        console(engine.__class__.__name__ + u' results') 

        for i, v in enumerate(engine.results, 1):
            console(u'{:<4}{}'.format(i, v['link'])) 
        console(u'')

def create_csv_data(search_engines):
    '''CSV formats the search results.'''
    encoder = decode_bytes if PYTHON_VERSION == 3 else encode_str
    data = [['query', 'engine', 'domain', 'URL', 'title', 'text']]

    for engine in search_engines:
        for i in engine.results:
            row = [
                engine._query, engine.__class__.__name__, 
                i['host'], i['link'], i['title'], i['text']
            ]
            row = [encoder(i) for i in row]
            data.append(row)
    return data

def create_json_data(search_engines):
    '''JSON formats the search results.'''
    jobj = {
        u'query': search_engines[0]._query, 
        u'results': {
            se.__class__.__name__: [i for i in se.results] 
            for se in search_engines
        }
    }
    return json.dumps(jobj)

def create_html_data(search_engines):
    '''HTML formats the search results.'''
    query = decode_bytes(search_engines[0]._query) if search_engines else u''
    tables = u''

    for engine in search_engines:
        rows = u''
        for i, v in enumerate(engine.results, 1):
            data = u''
            if u'title' in engine._filters:
                data += HtmlTemplate.data.format(_replace_with_bold(query, v['title']))
            if u'text' in engine._filters:
                data += HtmlTemplate.data.format(_replace_with_bold(query, v['text']))
            link = _replace_with_bold(query, v['link']) if u'url' in engine._filters else v['link']
            rows += HtmlTemplate.row.format(number=i, href=v['link'], link=link, data=data)
        
        engine_name = engine.__class__.__name__
        tables += HtmlTemplate.table.format(engine=engine_name, rows=rows)
    return HtmlTemplate.html.format(query=query, table=tables)

def _replace_with_bold(query, data):
    '''Places the query in <b> tags.'''
    for match in re.findall(query, data, re.I):
        data = data.replace(match, u'<b>{}</b>'.format(match))
    return data


def write_file(data, path, encoding='utf-8'):
    '''Writes search results data to file.'''
    try:
        if PYTHON_VERSION == 2 and type(data) in (list, str):
            f = io.open(path, 'wb') 
        else: 
            f = io.open(path, 'w', encoding=encoding, newline='')
        
        if type(data) is list:
            writer = csv.writer(f)
            writer.writerows(data)
        else:
            f.write(data)
        f.close()
        console(u'Output file: ' + path)
    except IOError as e:
        console(e, level=Level.error)


def console(msg, end='\n', level=None):
    '''Prints data on the console.'''
    console_len = get_terminal_size().columns
    clear_line = u'\r{}\r'.format(u' ' * (console_len - 1))
    msg = clear_line + (level or u'') + msg
    print(msg, end=end)

Level = namedtuple('Level', ['info', 'warning', 'error'])(
    info = u'INFO ',
    warning = u'WARNING ',
    error = u'ERROR '
)

PRINT = 'print'
HTML = 'html'
JSON = 'json'
CSV = 'csv'


class HtmlTemplate:
    '''HTML template.'''
    html = u'''<html>
    <head>
    <meta charset="UTF-8">
    <title>Search Results</title>
    <style>
    body {{ background-color:#f5f5f5; font-family:Italic, Charcoal, sans-serif; }} 
    a:link {{ color: #262626; }} 
    a:visited {{ color: #808080; }} 
    th {{ font-size:17px; text-align:left; padding:3px; font-style: italic; }} 
    td {{ font-size:14px; text-align:left; padding:1px; }} 
    </style>
    </head>
    <body>
    <table>
    <tr><th>Query: '{query}'</th></tr>
    <tr><td> </td></tr>
    </table>
    {table}
    </body>
    </html>
    '''
    table = u'''<table>
    <tr><th>{engine} search results </th></tr>
    </table>
    <table>
    {rows}
    </table>
    <br>
    '''
    row = u'''<tr>
    <td>{number})</td>
    <td><a href="{href}" target="_blank">{link}</a></td>
    {data}
    </tr>
    '''
    data = u'''<tr><td></td><td>{}</td></tr>'''

