import pandas as pd
from loguru import logger

from base.base import BaseDataConverter

# FIXME: костыль для выключения предупреждения "replace deprecated"
pd.set_option('future.no_silent_downcasting', True)


class DataConverter(BaseDataConverter):

    @staticmethod
    def _replace_bool(dataframe: pd.DataFrame) -> pd.DataFrame:
        try:
            bool_columns = dataframe.columns[dataframe.isin([True, False]).all()]
            dataframe = dataframe.astype({col: int for col in bool_columns})

            return dataframe
        except AttributeError as e:
            logger.warning(f"_replace_bool - AttributeError: Проверьте, что переданный объект является DataFrame. {e}")
            return None
        except (TypeError, ValueError) as e:
            logger.error(f"_replace_bool - Ошибка типа или значения: {e}")
            return None
        except Exception as e:
            logger.error(f"_replace_bool - Непредвиденная ошибка: {e}")
            return None
    
    @staticmethod
    def _fix_headers(dataframe: pd.DataFrame) -> pd.DataFrame:
        correct_columns = [
            "time", "Closing", "Electrode Force, N FE", "Electrode Force, N ME",
            "Force Control FE", "Force Control ME", "Hold Position ME", "Oncomming",
            "Position Control FE", "Position Control ME", "Relief",
            "Rotor Position, mm FE", "Rotor Position, mm ME",
            "Rotor Speed, mm/s FE", "Rotor Speed, mm/s ME",
            "Squeeze", "Welding", "Welding Current ME", "Welding Voltage ME"
        ]
        try:
            correct_mapping = {name.lower(): name for name in correct_columns}
            new_columns = []
            for col in dataframe.columns:
                fixed_col = correct_mapping.get(col.lower(), col)
                new_columns.append(fixed_col)
            dataframe.columns = new_columns
            # Удаляем повторяющиеся столбцы, оставляя только первое вхождение
            dataframe = dataframe.loc[:, ~dataframe.columns.duplicated()]
            return dataframe
        except AttributeError as e:
            logger.warning(f"_fix_headers - AttributeError: Проверьте, что переданный объект является DataFrame. {e}")
            return None
        except Exception as e:
            logger.error(f"_fix_headers - Непредвиденная ошибка: {e}")
            return None

    def convert_data(self, files: list[str]) -> None:
        try:
            dataframes = [pd.read_csv(file) if file != '' else None for file in files]
            renamed_dataframes = list(map(self._fix_headers, dataframes))
            converted_dataframes = list(map(self._replace_bool, renamed_dataframes))
        except FileNotFoundError as e:
            logger.error(f"convert_data - FileNotFoundError: Файл не найден. {e}")
            converted_dataframes = [None]
        except pd.errors.EmptyDataError as e:
            logger.error(f"convert_data - EmptyDataError: Файл пустой. {e}")
            converted_dataframes = [None]
        except Exception as e:
            logger.error(f"convert_data - Непредвиденная ошибка: {e}")
            converted_dataframes = [None]
        finally:
            self._mediator.notify(self, converted_dataframes)
