# -*- coding: UTF-8 -*-
import os
import platform
import pandas as pd
import matplotlib

from src.common.path import ordered_list_json_dir
from src.common.json import load_json, dump_json
from src.bar_chart_race.chart import bar_chart_race
from dataclasses import dataclass


@dataclass
class InputMeta:
    '''
    type: 指定类型，如果是 "json_str" 表示一个JSON文件夹，如果是"csv"表示一个csv文件
    JSON 文件夹:
        约定每个文件的文件名是月份，每个JSON文件是一个数组，数组元素是标签统计信息
        name_field: 指定标签名字的字段名
        count_field: 指定标签月份统计信息的字段名
    CSV 文件
        month_field: 指定月份字段
        name_field: 指定标签名字的字段名
        count_field: 指定标签月份统计信息的字段名
    '''
    type: str
    path: str
    month_field: str
    name_field: str
    count_field: str


@dataclass
class OutputMeta:
    '''
    输出配置
    path: 输出路径
    title: 标题
    x_label: X轴名字
    y_label: Y轴名字
    month_count: 绘制月份，用来调试，使用较少的月份快速查看输出效果
    '''
    path: str
    title: str
    x_label: str
    y_label: str
    month_count: int


class Top:
    '''
    # TopN 竞赛动图
    '''

    def __init__(self, input: InputMeta, output: OutputMeta):
        self.input_type = input.type
        self.input = input.path
        self.month_field = input.month_field
        self.name_field = input.name_field
        self.count_field = input.count_field

        self.output = output.path
        self.title = output.title
        self.x_label = output.x_label
        self.y_label = output.y_label
        self.month_count = output.month_count

    def build(self):
        self.__load_dataframe()
        # self.__exit()
        self.__config_font()
        self.__build_race()

    def __load_dataframe(self):
        if self.input_type == 'json_dir':
            self.__load_dataframe_from_json()
        elif self.input_type == 'csv':
            self.__load_dataframe_from_csv()
        else:
            raise Exception(
                "un suport input type, only support json_dir or csv")

    def __load_dataframe_from_json(self):
        tag_files = ordered_list_json_dir(self.input)
        tag_array = []
        month_count = 0
        for tag_file in tag_files:
            tags = load_json(tag_file)
            tag_month = os.path.basename(tag_file)[0:10]
            print(tag_month)
            for tag in tags:
                tag_array.append([
                    tag_month,
                    tag[self.name_field],
                    tag[self.count_field]
                ])
            month_count += 1
            if self.month_count is not None:
                if month_count == self.month_count:
                    break

        df = pd.DataFrame(tag_array, columns=[
            'month',
            self.name_field,
            self.count_field]
        )

        self.df = df.pivot_table(
            index='month',
            columns=self.name_field,
            values=self.count_field,
            fill_value=0
        )
        print(self.df.head())

    def __load_dataframe_from_csv(self):
        df = pd.read_csv(
            self.input,
            encoding='utf_8_sig',
            index_col=[0],
            lineterminator="\n"
        )

        max_rows = df.shape[0]
        if self.month_count is not None:
            max_rows = min(max_rows, self.month_count)
        df = df[0:max_rows]

        self.df = df.pivot_table(
            index=self.month_field,
            columns=self.name_field,
            values=self.count_field,
            fill_value=0
        )

        print(self.df.head())

    def __config_font(self):
        # matplotlib.rc("font", family='FZFangSong-Z02', weight='bold')
        if(platform.system() == 'Linux'):
            matplotlib.font_manager.findfont('WenQuanYi Micro Hei')
            matplotlib.rc("font", family='WenQuanYi Micro Hei')
        else:
            matplotlib.rc("font", family='FZFangSong-Z02')

    def __build_race(self):
        bar_chart_race(
            df=self.df,
            filename=self.output,
            n_bars=10,
            title=self.title,
            title_size=24,
            logo=self.x_label,
            y_label=self.y_label,
            # filter_column_colors=True,
            figsize=(8, 8),
            bar_size=0.7,
            bar_label_size=14,
            tick_label_size=14,
        )

    def __exit(self):
        import sys
        sys.exit()
