from typing import Optional, Union, TYPE_CHECKING

import pandas as pd

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

from shimoku.exceptions import DataError

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


async def heatmap_chart(
    self: 'PlotLayer', order: int, x: str, y: str, values: str,
    data: Union[list[dict], pd.DataFrame, str], color_range: Optional[tuple[int, int]] = None,
    x_axis_name: Optional[str] = None, y_axis_name: Optional[str] = None,
    title: Optional[str] = None, padding: Optional[str] = None,
    rows_size: Optional[int] = None, cols_size: Optional[int] = None,
    calculate_color_range: Optional[bool] = False, continuous: Optional[bool] = False,
    option_modifications: Optional[dict] = None, variant: Optional[str] = None
):
    """ Create a heatmap chart """
    color_range = (0, 10) if color_range is None else color_range
    if calculate_color_range:
        aux_data = data
        if isinstance(aux_data, str):
            if aux_data not in self._shared_data:
                log_error(
                    logger,
                    f"Shared data set ({aux_data}) not found in the menu path ({str(self._app)})",
                    DataError
                )
            aux_data = self._shared_data[aux_data]
        if isinstance(aux_data, pd.DataFrame):
            aux_data = aux_data.to_dict('records')
        color_range = (min([row[values] for row in aux_data]), max([row[values] for row in aux_data]))
    common_options = get_common_echart_options()
    series_options = get_common_series_options()
    del common_options['legend']
    del common_options['toolbox']['feature']['magicType']
    common_options['xAxis'][0].update({'type': 'category', 'data': None})
    common_options['yAxis'][0].update({'type': 'category', 'nameGap': 64})
    common_options['visualMap'] = {'calculable': True, 'orient': 'vertical',
                                   'type': 'continuous' if continuous else 'piecewise',
                                   'left': 'right', 'top': 'center', 'show': variant != 'minimal',
                                   'min': color_range[0], 'max': color_range[1]}
    common_options['grid'].update({'top': '5%', 'right': 80, 'bottom': 28, 'left': '5%' if y_axis_name else '1%'})

    series_options.update({
        'type': 'heatmap',
        'itemStyle': {'borderRadius': [0, 0, 0, 0]},
    })
    await self._create_trend_chart(
        data_mapping_to_tuples=await self._choose_data(order, data), axes=[], values=[(x, y, values)],
        echart_options=common_options, series_options=series_options, order=order, title=title, padding=padding,
        rows_size=rows_size, cols_size=cols_size, show_values='all', x_axis_names=x_axis_name, y_axis_names=y_axis_name,
        option_modifications=option_modifications, variant=variant
    )
