from typing import Optional, Union, TYPE_CHECKING

from pandas import DataFrame

from shimoku.plt.utils import (calculate_percentages_from_list, interpret_color)
from shimoku.exceptions import BentoboxError

from shimoku.plt.EChart_definitions.default_echart_options import get_common_echart_options, get_common_series_options

if TYPE_CHECKING:
    from shimoku.plt.plt_layer import PlotLayer

import logging
from shimoku.execution_logger import log_error
logger = logging.getLogger(__name__)


async def shimoku_gauge_chart(
    self: 'PlotLayer', order: int,
    value: Union[int, float], name: str = "",
    color: Optional[Union[str, int]] = 1, title: Optional[str] = None,
    rows_size: Optional[int] = 1, cols_size: Optional[int] = 3,
    padding: Optional[str] = None,
    is_percentage: bool = False,
    option_modifications: Optional[dict] = None,
):
    """ Create a pie chart """

    color = interpret_color(color)

    value_font_size = 24 * max(min(rows_size, int(cols_size / 2)), 1)

    if self._bentobox_data:
        value_font_size = 35 * max(int(min(rows_size / 10,
                                   (cols_size - self._bentobox_data['bentoboxSizeColumns']) / 4)), 1)

    common_options = get_common_echart_options()
    series_options = get_common_series_options()
    del common_options['yAxis']
    del common_options['xAxis']
    del common_options['grid']
    del common_options['toolbox']
    common_options['tooltip']['trigger'] = 'item'
    common_options['grid'] = {
        'left': '5%',
        'right': '5%',
        'top': '5%',
        'bottom': '5%',
        'containLabel': True
    }
    series_options.update({
        'type': 'gauge',
        'startAngle': 180,
        'endAngle': 0,
        'radius': '100%',
        'min': 0,
        'max': 100,
        'pointer': {
            'show': False,
        },
        'progress': {
            'show': True,
            'width': 30 if rows_size > 1 else 25,
            'overlap': False,
            'roundCap': False,
            'clip': False,
            'itemStyle': {
                'borderWidth': 0,
                'borderColor': color,
                'color': color,
            }
        },
        'splitLine': {
            'show': False,
        },
        'axisLine':
            {'lineStyle':
                 {'width': 30 if rows_size > 1 else 25}
             },
        'axisTick': {
            'show': False
        },
        'axisLabel': {
            'show': False,
        },
        'title': {
            'fontSize': 16,
            'fontFamily': 'Rubik',
            'offsetCenter': ['0', '30'],
        },
        'detail': {
            'fontSize': value_font_size,
            'fontFamily': 'Rubik',
            'font': 'inherit',
            'color': '#202A36',
            'borderColor': 'auto',
            'borderWidth': 0,
            'formatter': ('-' if value < 0 else '') + '{value}' + ('%' if is_percentage else ''),
            'valueAnimation': True,
            'offsetCenter': ['0', '-10']
        }
    })
    common_options['series'] = [series_options]

    await self._create_echart(
        fields=[{'name': 'name', 'value': 'value'}], options=common_options, option_modifications=option_modifications,
        data_mapping_to_tuples=await self._choose_data(order, DataFrame([{'name': name, 'value': abs(value)}])),
        order=order, title=title, rows_size=rows_size, cols_size=cols_size, padding=padding)


def shimoku_gauges_group(
        self: 'PlotLayer', gauges_data: Union[DataFrame, list[dict]], order: int,
        rows_size: Optional[int] = None, cols_size: Optional[int] = 12,
        gauges_padding: Optional[str] = '3, 1, 1, 1',
        gauges_rows_size: Optional[int] = 9, gauges_cols_size: Optional[int] = 4,
        calculate_percentages: Optional[bool] = False
):
    if isinstance(gauges_data, DataFrame):
        gauges_data = gauges_data.to_dict(orient="records")

    if calculate_percentages:
        percentages = calculate_percentages_from_list([gauge['value'] for gauge in gauges_data], 0)
        for i in range(len(percentages)):
            gauges_data[i]['value'] = percentages[i]

    if self._bentobox_data:
        log_error(logger, 'The gauges group uses a bentobox, so it cannot be used inside another bentobox. Please'
                          ' pop out of the current bentobox before using this function.', BentoboxError)

    self.set_bentobox(cols_size, rows_size)
    for gauge in gauges_data:
        order += 1
        self.shimoku_gauge(
            value=gauge['value'], order=order, name=gauge.get('name'),
            padding=gauge['padding'] if gauge.get('padding') else gauges_padding,
            color=gauge['color'] if gauge.get('color') else 1,
            rows_size=gauge['rows_size'] if gauge.get('rows_size') else gauges_rows_size,
            cols_size=gauge['cols_size'] if gauge.get('cols_size') else gauges_cols_size,
            is_percentage=gauge['is_percentage'] if gauge.get('is_percentage') else True,
        )

    self.pop_out_of_bentobox()
    return order + 1
