from typing import TYPE_CHECKING
import asyncio
from copy import deepcopy
from shimoku.api.utils import change_data_set_name_with_report, revert_uuids_from_dict
from shimoku.code_gen.business_code_gen.apps_code_gen.data_sets_code_gen.code_gen_from_data_sets import (
    code_gen_read_csv_from_data_set,
    get_linked_data_set_info,
)
from shimoku.code_gen.utils_code_gen import code_gen_from_list

if TYPE_CHECKING:
    from shimoku.api.resources.report import Report
    from shimoku.code_gen.business_code_gen.apps_code_gen.code_gen_from_apps import (
        AppCodeGen,
    )


# Todo needs to have the correct names for the columns
async def code_gen_from_annotated_echart(
    self: "AppCodeGen", report: "Report", properties: dict
) -> list[str]:
    """Generate code for an echarts report.
    :param report: report to generate code from
    :param report_params: parameters of the report
    :param properties: properties of the report
    :return: list of code lines"""
    echart_options = deepcopy(properties["option"])
    rds_ids_in_order = revert_uuids_from_dict(echart_options)
    data_set_ids, _ = await get_linked_data_set_info(self, report, rds_ids_in_order)
    data_sets = await asyncio.gather(
        *[self._app.get_data_set(ds_id) for ds_id in data_set_ids]
    )
    if data_sets[0]["columns"]:
        rev_data_set_columns = [
            {v: k for k, v in data_set["columns"].items()} for data_set in data_sets
        ]
    else:
        rev_data_set_columns = [
            {"dateField1": "dateField1", "intField1": "intField1"} for _ in data_sets
        ]
    data_set_names = [
        change_data_set_name_with_report(data_set, report) for data_set in data_sets
    ]
    data_args = await asyncio.gather(
        *[
            code_gen_read_csv_from_data_set(data_set, name)
            for data_set, name in zip(data_sets, data_set_names)
        ]
    )
    data_args = [data_arg for data_arg in data_args if data_arg is not None]
    slider_properties = properties.get("slider") or {}
    marks = slider_properties.pop("marks") if "marks" in slider_properties else None

    slider_params = []
    if slider_properties:
        slider_params.append(f"    slider_config={slider_properties},")
    if marks:
        slider_params.append(
            f'    slider_marks={[(mark["label"], mark["value"]) for mark in marks]},'
        )
    y_code_lines = code_gen_from_list(
        [rev_data_set_columns[i]["intField1"] for i in range(len(data_args))], 4
    )
    return [
        "shimoku_client.plt.annotated_chart(",
        f'    data=[{", ".join(data_args)}],',
        f'    x="{rev_data_set_columns[0]["dateField1"]}",',
        f"    y={y_code_lines[0][4:]}",
        *y_code_lines[1:],
        *slider_params,
        *self.code_gen_report_params(report.cascade_to_dict()),
        ")",
    ]
