# encoding: utf-8
import time
from cStringIO import StringIO
from datetime import datetime

from old_helper import convert_from_utf_to_localtime
from utils import (
    report_default_header,
    DATE_TIME_FMT,
    center,
    add_key_value_line,
    empty_line,
    add_table_line,
    get_store_id,
    single_line_separator
)


class OpenedTablesReport(object):
    def __init__(self, table_repository, order_repository, pos_id, operator_name_retriever):
        self.table_repository = table_repository
        self.order_repository = order_repository
        self.pos_id = pos_id
        self.operator_name_retriever = operator_name_retriever
        self.store_id = get_store_id()

        self.columns_height = [18, 20]
        self.character_to_add = [".:", " ", " "]
        self.command = "Comanda"

    def generate_opened_tables_report(self, pos_id):
        report = StringIO()
        title = "Relatorio Mesas Abertas"
        current_datetime = time.strftime(DATE_TIME_FMT)
        report.write(report_default_header(title, int(pos_id), None, None, current_datetime, self.store_id))
        self._opened_tables_report_body(report)

        return report.getvalue()

    def _opened_tables_report_body(self, report):
        tables = self.table_repository.get_opened_tables()
        orders = []
        [orders.extend(x.orders) for x in tables.values() if x.orders != [None]]
        orders_amount = self.order_repository.get_orders_amount(orders)

        sectors_details = {}
        for table in sorted(tables.items(), key=lambda x: x[1].name):
            table_id = table[0]
            current_table = table[1]
            is_tab = "TAB" in table_id

            table_context = "Comanda " if is_tab else "Mesa "
            date = datetime.strptime(current_table.opened_date, "%Y-%m-%d %H:%M:%S")
            date = convert_from_utf_to_localtime(date)
            table_name = current_table.name
            table_detail_header = table_context + str(table_name) + " - " + datetime.strftime(date, "%d/%m/%Y %H:%M:%S")

            table_amount = self._get_table_amount(current_table, orders_amount)
            seats = current_table.seats
            columns = ["Total [Assentos]", 'R$ {:>8.2f}'.format(table_amount) + " [" + seats + "]"]

            operator_id = current_table.operator
            operator_name = self.operator_name_retriever.get_operator_name(operator_id)
            table_info = dict(header=table_detail_header, operator=operator_name, columns=columns)

            sector = self._get_sector_name(current_table, is_tab)
            if sector in sectors_details:
                sectors_details[sector].append(table_info)
            else:
                sectors_details[sector] = [table_info]

        sectors_keys = [s for s in sectors_details.keys() if s != self.command]
        sectors_keys.sort()
        if self.command in sectors_details.keys():
            sectors_keys.append(self.command)

        for sector in sectors_keys:
            report.write(center(sector.upper()))
            report.write(empty_line())
            for table_info in sectors_details[sector]:
                report.write(center(table_info["header"]))
                report.write(add_key_value_line("Operador........: ", table_info["operator"]))
                report.write(add_table_line(
                    table_info["columns"],
                    self.columns_height,
                    character_to_add=self.character_to_add)
                )
                report.write(empty_line())

            report.write(single_line_separator())

    @staticmethod
    def _get_sector_name(current_table, is_tab):
        sector = current_table.sector
        if sector:
            return sector

        if is_tab:
            return 'COMANDAS'

        return 'SEM SETOR'

    @staticmethod
    def _get_table_amount(current_table, orders_amount):
        table_amount = 0
        for order_id in current_table.orders:
            if order_id is None or order_id not in orders_amount:
                continue

            table_amount += orders_amount[order_id]["amount"]
            if current_table.status == 'TOTALED':
                table_amount += orders_amount[order_id]["tip"]

        return table_amount
