# -*- coding: utf-8 -*-
"""
Выводим графики.
"""
from PIL import Image, ImageDraw
import os
from stocks3.export.templater import Templater
from stocks3.core.factories import templaters
from stocks3.share.mds import upload
from stocks3.share.db import WithDB
from stocks3.share import messages


def circle(draw, center, radius, fill):
    draw.ellipse((center[0] - radius + 1, center[1] - radius + 1, center[0] + radius - 1, center[1] + radius - 1),
                 fill=fill, outline=None)


class SearchAppPngMdsTemplater(Templater, WithDB):
    base_graph_width = 92
    base_graph_height = 32
    base_line_width = 2
    base_point_spacer = 2
    base_point_radius = 3
    base_width_padding = 3
    base_height_padding = 3
    base_scale_factor = 4
    scale_factors = [1, 1.5, 2, 3, 4]
    line_color = '#acb6bd'
    point_red_color = '#f44336'
    point_green_color = '#6dae43'

    def __init__(self, tree, node, exporter, calculator):
        self.records_count = 0
        Templater.__init__(self, tree, node, exporter, calculator)
        WithDB.__init__(self)

    def makeConfig(self):
        Templater.makeConfig(self)
        self.records_count = self.readInt("", "records-count")
        os.makedirs(self.output_directory, exist_ok=True)

    def draw_image(self, prices, scale_factor):
        line_width = self.base_line_width * scale_factor
        point_radius = self.base_point_radius * scale_factor
        point_spacer_radius = self.base_point_spacer * scale_factor + point_radius
        graph_width = self.base_graph_width * scale_factor
        graph_height = self.base_graph_height * scale_factor
        width_padding = self.base_width_padding * scale_factor
        height_padding = self.base_height_padding * scale_factor

        image = Image.new("RGBA", (graph_width, graph_height), (172, 182, 189, 0))
        draw = ImageDraw.Draw(image)
        price_max, price_min = max(prices), min(prices)
        height_factor = (graph_height - height_padding * 2) / ((price_max - price_min) if price_max - price_min else 1)
        width_factor = (graph_width - width_padding * 2) / (len(prices) - 1)

        points = []
        for i in range(0, len(prices)):
            points.append([i * width_factor + width_padding,
                           graph_height - ((prices[i] - price_min) * height_factor + height_padding)])
            circle(draw, points[i], line_width / 2, self.line_color)

        for i in range(1, len(prices)):
            p1 = points[i - 1]
            p2 = points[i]
            draw.line(p1 + p2, fill=self.line_color, width=line_width)

        last_point = points[-1:][0]
        circle(draw, last_point, point_spacer_radius, (172, 182, 189, 0))

        if prices[-2:][1] - prices[-2:][0] >= 0:
            circle(draw, last_point, point_radius, self.point_green_color)
        else:
            circle(draw, last_point, point_radius, self.point_red_color)

        del draw
        return image

    def push(self, quote, data):
        for region, prices in data.items():
            if len(prices) < 5:
                continue
            base_filename = self.get_output_file_name(quote, region)

            if self.check_if_need_update_file(base_filename, prices):
                filename = os.path.join(self.output_directory, base_filename)
                y = [[], []]
                dual = False
                for price in sorted(prices, key=lambda p1: p1.date)[-self.records_count:]:
                    y[0] += [price.buy.value]
                    if price.is_dual_price:
                        dual = True
                        y[1] += [price.sell.value]
                if not dual:
                    y = y[:1]

                graph = self.draw_image(y[0], 8)

                # базовое изображение для аватарницы
                scaled_graph = graph.resize(
                    (int(self.base_graph_width * self.base_scale_factor),
                     int(self.base_graph_height * self.base_scale_factor)),
                    resample=Image.ANTIALIAS)
                if not os.path.exists(os.path.dirname(filename)):
                    os.mkdir(os.path.dirname(filename))
                scaled_graph.save(filename, "PNG")
                uploaded_list = upload(filename)
                if isinstance(uploaded_list, list) and isinstance(uploaded_list[0], (list, tuple)):
                    base_url = dict(uploaded_list)['1'][:-1]     # Отрезаем последний символ, чтобы получить базовый урл
                    self.db.save_export_additions(
                        quote.quote_id,
                        region,
                        {'search_app_graph_base_url': base_url}
                    )
                else:
                    messages.error("error in upload to mds: {0}, quote_id: {1}, region: {2}"
                                   .format(uploaded_list, quote.quote_id, region))
                    os.remove(filename)
            else:
                messages.info("skip generate file: {0}".format(base_filename))


templaters.register("stocks3.templaters.sa_png_mds", SearchAppPngMdsTemplater)
