import json
import pandas as pd
import requests
from loguru import logger
from scripts.constants.app_configuration import KairosDb


class KairosQuery:
    def __init__(self, start_timestamp, end_timestamp, tag_dict):
        self.start_timestamp = start_timestamp
        self.end_timestamp = end_timestamp
        self.kairos_host = KairosDb.uri
        self.kairos_url = "{kairos_host}/api/v1/datapoints/query".format(kairos_host=self.kairos_host)
        self.tag_dict = tag_dict

    def kairos_query(self):
        try:
            return {
                "metrics": [
                    {
                        "tags": {
                            "c3": list(self.tag_dict.keys())
                        },
                        "name": KairosDb.metric_name,
                        "group_by": [
                            {
                                "name": "tag",
                                "tags": ["c3"]
                            }
                        ],
                        "aggregators": [
                            {
                            "name": KairosDb.aggregator,
                            "sampling": {
                                "value": KairosDb.aggregator_value,
                                "unit": KairosDb.aggregator_unit
                            },
                                "align_sampling": True,
                                "align_start_time": True
                            }
                        ]
                    }
                ],
                "plugins": [],
                "cache_time": 0,
                "time_zone": "Asia/Calcutta",
                "start_absolute": self.start_timestamp,
                "end_absolute": self.end_timestamp,
            }
        except Exception as e:
            logger.exception(f"Exception - {e}")

    def get_data(self, data_query):
        try:
            logger.info("Data for the parameters being pulled from Kairos Database")
            response = requests.post(self.kairos_url, data=json.dumps(data_query))
            response_data = response.json()
            output_data = response_data["queries"]
            logger.debug("Data pull complete")
            df_final = pd.DataFrame()
            for i in range(len(output_data)):
                grouped_output_data = output_data[i]["results"]
                for each_grouped_data in grouped_output_data:
                    value = (each_grouped_data["values"])
                    tag_id = each_grouped_data["group_by"][0]["group"]["c3"]
                    try:
                        logger.debug("Renamed {} to {} in Data".format(tag_id, self.tag_dict[tag_id]))
                        column_name = self.tag_dict[tag_id]
                    except KeyError as e:
                        logger.exception(f'Exception - {e}')
                        logger.debug("Column Renaming Logic not found for {}".format(tag_id))
                        column_name = tag_id
                    df_column_data = pd.DataFrame(data=value, columns=["timestamp", column_name])
                    if df_final.empty:
                        df_final = df_column_data
                    else:
                        df_final = df_final.merge(df_column_data, how="outer", left_on="timestamp",
                                                  right_on="timestamp")
            df_final['datetime'] = pd.to_datetime(df_final['timestamp'], unit="ms").dt.tz_localize('UTC').\
                dt.tz_convert('Asia/Kolkata')
            logger.debug("Final number of columns : {}".format(str(len(list(df_final.columns)))))
            return df_final
        except Exception as e:
            logger.exception(f"Exception occurred - {e}", exc_info=True)

    def kairos_data_import(self):
        try:
            logger.debug("Fetching live data")
            query_live = self.kairos_query()
            logger.info(f"query_live = {query_live}")
            df = self.get_data(data_query=query_live)
            return df
        except Exception as e:
            logger.exception(f"Exception - {e}")


