from typing import Dict, Union, List
import pandas as pd
from app.config import logger


class BaseConverter:
    def __init__(self, content: Union[str, bytes]):
        self.content = content
        # Placeholder for data not ready for conversion to a DataFrame format
        self.datadict = None
        self.df = None

    def read_file(self) -> None:
        """Read the file content into a DataFrame."""
        raise NotImplementedError(
            "Subclasses must implement add_metadata method")

    def add_metadata(self) -> None:
        """Add metadata columns to the DataFrame."""
        raise NotImplementedError(
            "Subclasses must implement add_metadata method")

    def convert_columns(self) -> None:
        """Convert specific columns in the DataFrame."""
        raise NotImplementedError(
            "Subclasses must implement convert_columns method")

    def rename_columns(self) -> None:
        """Rename columns in the DataFrame."""
        raise NotImplementedError(
            "Subclasses must implement rename_columns method")

    def clean_data(self) -> None:
        """Clean and preprocess the DataFrame."""
        raise NotImplementedError(
            "Subclasses must implement rename_columns method")

    def convert(self) -> List[Dict]:
        """Convert the content to the standardized format."""
        try:
            self.read_file()
            self.add_metadata()
            self.convert_columns()
            self.rename_columns()
            self.clean_data()
            result = self.df.to_dict(orient="records")

            logger.info(
                f"Conversion completed successfully with {len(result)} records")
            return result

        except pd.errors.EmptyDataError as e:
            logger.error(f"File is empty or malformed: {str(e)}")
            raise ValueError(f"File is empty or malformed: {str(e)}")
        except KeyError as e:
            logger.error(f"Missing expected column: {str(e)}")
            raise ValueError(f"Missing expected column: {str(e)}")
        except Exception as e:
            logger.exception(f"Unexpected error during conversion: {str(e)}")
            raise ValueError(f"Unexpected error during conversion: {str(e)}")
