#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @File     : pic_echarts
# @Author   : LiuYan
# @Time     : 2021/12/16 19:29

import os

from pyecharts import options as opts
from pyecharts.charts import Pie, Bar, Line, Grid
from pyecharts.faker import Faker
from pyecharts.render import make_snapshot  # 导入输出图片工具
from snapshot_selenium import snapshot  # 使用snapshot-selenium 渲染图片
from pyecharts.globals import CurrentConfig
from pathlib import Path
# import time
from unittest import mock

from base.config.base_config import root_dir
from utils.tools import timeit
import threading


# 解决linux 下图片生成失败问题
def get_chrome_driver():
    from selenium import webdriver
    options = webdriver.ChromeOptions()
    options.add_argument("headless")
    options.add_argument('--no-sandbox')
    options.add_argument('--disable-gpu')
    options.add_argument('--disable-dev-shm-usage')
    return webdriver.Chrome(options=options)



"""
关于: [图片生成的中文字体样式渲染问题]
中文字体全局配置默认为None, 即为读取服务器端已有中文字体样式, 按照优先顺序[源码与定义好的]进行中文渲染。
例如39服务器上有simhei和simsun, 中文字体样式会选用simsun
目前39服务器上仅放置simhei, 后续可根据具体需要放置其他中文字体样式, 并实现在代码中全局或局部控制生成的中文样式
"""

# CurrentConfig.ONLINE_HOST = 'https://cdn.jsdelivr.net/gh/pyecharts/pyecharts-assets@master/assets/'
# define "echarts.min.js"文件存放地址
CurrentConfig.ONLINE_HOST = 'http://39.105.62.235:8000/assets/'
# CurrentConfig.ONLINE_HOST = 'http://192.168.1.149:8000/assets/'
pic_echarts_dir = os.path.join(root_dir, 'generate/echarts')
Path(pic_echarts_dir).mkdir(parents=True, exist_ok=True)

lock = threading.RLock()

@timeit
def pic_echarts_pie(keys: list, values: list, title: str or None, pic_echarts_path: str) -> str:
    # pic_echarts_path = os.path.join(pic_echarts_dir, 'echarts_pie.png')
    # pic_echarts_path = os.path.join(pic_echarts_dir, temp_file_name)
    with lock:
        pie = (
            Pie().add(
                series_name='',
                data_pair=[list(z) for z in zip(keys, values)],
                center=['45%', '50%'],
                is_clockwise=False
            ).set_global_opts(
                title_opts=opts.TitleOpts(title=title),
                legend_opts=opts.LegendOpts(type_='scroll', pos_left='80%', orient='vertical', textstyle_opts=opts.TextStyleOpts(font_size=20))
            ).set_series_opts(
                label_opts=opts.LabelOpts(formatter="{b}: {d}%", font_size=18)
            )
        )
        # print("当前处理的数据集key{}，和value{}".format(keys, values))
    with lock:
        with mock.patch('snapshot_selenium.snapshot.get_chrome_driver', get_chrome_driver):
            make_snapshot(snapshot, pie.render(), pic_echarts_path)
    # make_snapshot(snapshot, pie.render(), pic_echarts_path)
    return pic_echarts_path


@timeit
def pic_echarts_bar(
        keys: list, dict_values: dict, temp_file_name: str, title=None,
        x_name=None, y_name=None,
) -> str:
    pic_echarts_path = os.path.join(pic_echarts_dir, temp_file_name)
    bar = (
        Bar().add_xaxis(
            xaxis_data=keys
        ).set_global_opts(
            title_opts=opts.TitleOpts(title=title),
            xaxis_opts=opts.AxisOpts(name=x_name, axislabel_opts=opts.LabelOpts(rotate=-15)),
            yaxis_opts=opts.AxisOpts(name=y_name),
            legend_opts=opts.LegendOpts(type_='scroll', pos_left='80%', orient='vertical', textstyle_opts=opts.TextStyleOpts(font_size=18))
        )
        # 设置标签字体大小
        .set_series_opts(label_opts=opts.LabelOpts(font_size=20))
    )
    for key in dict_values:
        bar.add_yaxis(series_name=key, y_axis=dict_values[key])

    make_snapshot(snapshot, bar.render(), pic_echarts_path)

    return pic_echarts_path


@timeit
def pic_echarts_line(
        keys: list, dict_values: dict, temp_file_name: str, title=None,
        x_name=None, y_name=None
) -> str:
    pic_echarts_path = os.path.join(pic_echarts_dir, temp_file_name)
    line = (
        Line().add_xaxis(
            xaxis_data=keys
        ).set_global_opts(
            title_opts=opts.TitleOpts(title=title),
            xaxis_opts=opts.AxisOpts(name=x_name, axislabel_opts=opts.LabelOpts(rotate=-15)),
            yaxis_opts=opts.AxisOpts(name=y_name),
            legend_opts=opts.LegendOpts(textstyle_opts=opts.TextStyleOpts(font_size=20))
        )
        # 设置标签字体大小
        .set_series_opts(label_opts=opts.LabelOpts(font_size=20))
    )
    for key in dict_values:
        line.add_yaxis(series_name=key, y_axis=dict_values[key])

    make_snapshot(snapshot, line.render(), pic_echarts_path)

    return pic_echarts_path


@timeit
def pic_echarts_line_test() -> None:
    pic_echarts_path = os.path.join(pic_echarts_dir, 'echarts_line_test.png')
    x_data = ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
    y_data = [820, 932, 901, 934, 1290, 1330, 1320]

    line = (
        Line()
            .add_xaxis(xaxis_data=x_data)
            .add_yaxis(
            series_name='邮件营销',
            stack='总量',
            y_axis=[120, 132, 101, 134, 90, 230, 210],
            label_opts=opts.LabelOpts(is_show=False),
        )
            .add_yaxis(
            series_name='联盟广告',
            stack='总量',
            y_axis=[220, 182, 191, 234, 290, 330, 310],
            label_opts=opts.LabelOpts(is_show=False),
        )
            .add_yaxis(
            series_name='视频广告',
            stack='总量',
            y_axis=[150, 232, 201, 154, 190, 330, 410],
            label_opts=opts.LabelOpts(is_show=False),
        )
            .add_yaxis(
            series_name='直接访问',
            stack='总量',
            y_axis=[320, 332, 301, 334, 390, 330, 320],
            label_opts=opts.LabelOpts(is_show=False),
        )
            .add_yaxis(
            series_name='搜索引擎',
            stack='总量',
            y_axis=[820, 932, 901, 934, 1290, 1330, 1320],
            label_opts=opts.LabelOpts(is_show=False),
        )
            .set_global_opts(
            title_opts=opts.TitleOpts(title='折线图堆叠'),
            tooltip_opts=opts.TooltipOpts(trigger='axis'),
            yaxis_opts=opts.AxisOpts(
                type_='value',
                axistick_opts=opts.AxisTickOpts(is_show=True),
                splitline_opts=opts.SplitLineOpts(is_show=True),
            ),
            xaxis_opts=opts.AxisOpts(type_='category', boundary_gap=False),
        )
    )

    make_snapshot(snapshot, line.render(), pic_echarts_path)


@timeit
def pic_echarts_bar_line(
        temp_file_name: str,
        keys=['2016年报', '2017年报', '2018年报', '2019年报', '2020年报', '2021年报'],
        dict_bar_values={
            '总资产': [1905.11, 1998.17, 2009.65, 2031.37, 1950.35, 1988.65],
            '总负债': [1367.25, 1340.74, 1332.95, 1323.80, 1238.31, 1230.78]
        },
        dict_line_values={
            '负债率': [70.72, 67.10, 66.33, 65.17, 63.49, 61.89]
        },
        colors=['#d14a61', '#5793f3', '#2f4554'],
        title='资产负债表(CNY)',
        x_name='年度', y_name_left='金额/(亿元)', y_name_right='负债率/(%)'
) -> str:
    pic_echarts_path = os.path.join(pic_echarts_dir, temp_file_name)
    bar = (
        Bar().add_xaxis(
            xaxis_data=keys
        ).extend_axis(
            yaxis=opts.AxisOpts(
                name=y_name_right,
                position='right'
            )
        ).set_global_opts(
            xaxis_opts=opts.AxisOpts(name=x_name),
            yaxis_opts=opts.AxisOpts(
                name=y_name_left,
                position='left'
            ),
            title_opts=opts.TitleOpts(title=title),
            tooltip_opts=opts.TooltipOpts(trigger='axis', axis_pointer_type='cross'),
            legend_opts=opts.LegendOpts(textstyle_opts=opts.TextStyleOpts(font_size=20))
        )
        # 设置标签字体大小
        .set_series_opts(label_opts=opts.LabelOpts(font_size=20))
    )
    index = 0
    for bar_key in dict_bar_values:
        bar.add_yaxis(
            series_name=bar_key,
            y_axis=dict_bar_values[bar_key],
            yaxis_index=0, z=0,
            color=colors[index]
        )
        index += 1

    line = (
        Line().add_xaxis(
            xaxis_data=keys
        )
    )
    for line_key in dict_line_values:
        line.add_yaxis(
            series_name=line_key,
            y_axis=dict_line_values[line_key],
            # color=colors[index],
            yaxis_index=1,
            label_opts=opts.LabelOpts(is_show=False)
        )
        index += 1

    bar.overlap(line)
    grid = Grid()
    grid.add(bar, opts.GridOpts(pos_left='5%', pos_right='5%'), is_control_axis_index=True)

    make_snapshot(snapshot, grid.render(), pic_echarts_path)

    return pic_echarts_path


@timeit
def pic_echarts_bar_line_test() -> str:
    pic_echarts_path = os.path.join(pic_echarts_dir, 'echarts_bar_line_test.png')
    x_data = ['{}月'.format(i) for i in range(1, 13)]
    bar = (
        Bar().add_xaxis(
            xaxis_data=x_data
        ).add_yaxis(
            series_name='蒸发量',
            y_axis=[2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3],
            yaxis_index=0, color='#d14a61',
        ).add_yaxis(
            series_name='降水量',
            y_axis=[2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3],
            yaxis_index=1, color='#5793f3',
        ).extend_axis(
            yaxis=opts.AxisOpts(
                name='蒸发量',
                type_='value',
                min_=0,
                max_=250,
                position='right',
                axisline_opts=opts.AxisLineOpts(
                    linestyle_opts=opts.LineStyleOpts(color='#d14a61')
                ),
                axislabel_opts=opts.LabelOpts(formatter='{value} ml'),
            )
        ).extend_axis(
            yaxis=opts.AxisOpts(
                type_='value',
                name='温度',
                min_=0,
                max_=25,
                position="left",
                axisline_opts=opts.AxisLineOpts(
                    linestyle_opts=opts.LineStyleOpts(color='#675bba')
                ),
                axislabel_opts=opts.LabelOpts(formatter='{value} °C'),
                splitline_opts=opts.SplitLineOpts(
                    is_show=True, linestyle_opts=opts.LineStyleOpts(opacity=1)
                ),
            )
        ).set_global_opts(
            yaxis_opts=opts.AxisOpts(
                name='降水量',
                min_=0,
                max_=250,
                position='right',
                offset=80,
                axisline_opts=opts.AxisLineOpts(
                    linestyle_opts=opts.LineStyleOpts(color='#5793f3')
                ),
                axislabel_opts=opts.LabelOpts(formatter='{value} ml'),
            ),
            title_opts=opts.TitleOpts(title='多 Y 轴图示例'),
            tooltip_opts=opts.TooltipOpts(trigger='axis', axis_pointer_type='cross'),
        )
    )

    line = (
        Line().add_xaxis(
            xaxis_data=x_data
        ).add_yaxis(
            '平均温度',
            [2.0, 2.2, 3.3, 4.5, 6.3, 10.2, 20.3, 23.4, 23.0, 16.5, 12.0, 6.2],
            yaxis_index=2,
            color='#675bba',
            label_opts=opts.LabelOpts(is_show=False),
        )
    )

    bar.overlap(line)
    grid = Grid()
    grid.add(bar, opts.GridOpts(pos_left='5%', pos_right='20%'), is_control_axis_index=True)

    make_snapshot(snapshot, grid.render(), pic_echarts_path)

    return pic_echarts_path


if __name__ == '__main__':

    # pic_echarts_pie(keys=Faker.choose(), values=Faker.values(), title='Echarts Pie 标题1')
    # pic_echarts_bar(
    #     keys=Faker.choose(),
    #     dict_values={
    #         '2019': Faker.values(),
    #         '2020': Faker.values(),
    #         '2021': Faker.values()
    #     },
    #     title='Echarts Bar 标题'
    # )
    # pic_echarts_line(
    #     keys=Faker.choose(),
    #     dict_values={
    #         '折线1': Faker.values(),
    #         '折线2': Faker.values()
    #     },
    #     title='Echarts Line 标题',
    #     x_name='X轴名称',
    #     y_name='Y轴名称'
    # )
    # pic_echarts_line_test()
    pic_echarts_bar_line()
