"""
Module: pricing.py
Description: This module provides a pricing optimization functionality
             based on market data.  It uses a simple optimization
             algorithm and incorporates error handling, logging,
             and type hints.
"""

import logging
import json
from typing import Dict, Union, Optional
import os
import pandas as pd  # Using pandas for more robust data handling

# Initialize logging
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s'
)

# Default configuration file path (relative to the script's location)
DEFAULT_CONFIG_PATH = "/mnt/e/genesis-system/core/revenue/config/pricing_config.json"

class PricingOptimizer:
    """
    A class that optimizes pricing based on market data.
    """

    def __init__(self, config_path: str = DEFAULT_CONFIG_PATH) -> None:
        """
        Initializes the PricingOptimizer with a configuration file.

        Args:
            config_path (str): Path to the configuration file (JSON).
                                Defaults to DEFAULT_CONFIG_PATH.
        """
        self.config = self._load_config(config_path)
        self.market_data: Optional[pd.DataFrame] = None # Store market data

    def _load_config(self, config_path: str) -> Dict:
        """
        Loads the configuration from a JSON file.

        Args:
            config_path (str): Path to the configuration file.

        Returns:
            Dict: A dictionary containing the configuration.

        Raises:
            FileNotFoundError: If the configuration file is not found.
            json.JSONDecodeError: If the configuration file is invalid JSON.
        """
        try:
            with open(config_path, 'r') as f:
                config = json.load(f)
                logging.info(f"Configuration loaded from {config_path}")
                return config
        except FileNotFoundError:
            logging.error(f"Configuration file not found: {config_path}")
            raise FileNotFoundError(f"Configuration file not found: {config_path}")
        except json.JSONDecodeError as e:
            logging.error(f"Invalid JSON in configuration file: {config_path} - {e}")
            raise json.JSONDecodeError(f"Invalid JSON in configuration file: {config_path}", e.doc, e.pos)


    def load_market_data(self, data_path: str, file_type: str = 'csv') -> None:
        """
        Loads market data from a CSV or JSON file into a pandas DataFrame.

        Args:
            data_path (str): Path to the market data file.
            file_type (str, optional): The file type ('csv' or 'json'). Defaults to 'csv'.

        Raises:
            FileNotFoundError: If the data file is not found.
            ValueError: If the file type is not supported.
        """
        try:
            if file_type == 'csv':
                self.market_data = pd.read_csv(data_path)
            elif file_type == 'json':
                self.market_data = pd.read_json(data_path)
            else:
                raise ValueError(f"Unsupported file type: {file_type}")

            logging.info(f"Market data loaded from {data_path} (type: {file_type})")

        except FileNotFoundError:
            logging.error(f"Market data file not found: {data_path}")
            raise FileNotFoundError(f"Market data file not found: {data_path}")
        except Exception as e:
            logging.error(f"Error loading market data from {data_path}: {e}")
            raise

    def optimize_price(self, base_price: float) -> float:
        """
        Optimizes the price based on loaded market data and configured parameters.

        Args:
            base_price (float): The initial base price.

        Returns:
            float: The optimized price.  Returns the base price if market data is missing.
        """
        if self.market_data is None:
            logging.warning("Market data not loaded.  Returning base price.")
            return base_price

        # Placeholder optimization logic.  Replace with actual algorithm.
        # This example adjusts the price based on average demand.
        try:
            demand_column = self.config.get("demand_column", "demand") # Get demand column from config. Default to "demand"
            demand_data = self.market_data[demand_column]
            average_demand = demand_data.mean()

            sensitivity = self.config.get("price_sensitivity", 0.05) # Get price sensitivity from config. Default to 0.05
            optimized_price = base_price * (1 + sensitivity * (average_demand - self.config.get("target_demand", 100)))  #Assume target demand is 100 if not set.

            min_price = self.config.get("min_price", 0.0) #Get min price from config, default to 0
            max_price = self.config.get("max_price", 1000.0) #Get max price from config, default to 1000

            optimized_price = max(min_price, min(optimized_price, max_price)) #Clamp within bounds.


            logging.info(f"Optimized price from {base_price} to {optimized_price} (avg demand: {average_demand})")
            return optimized_price

        except KeyError as e:
            logging.error(f"Column not found in market data: {e}")
            return base_price
        except Exception as e:
            logging.error(f"Error optimizing price: {e}")
            return base_price


    def get_current_market_summary(self) -> Union[Dict, str]:
        """
        Returns a summary of the current market data, if available.

        Returns:
            Union[Dict, str]: A dictionary containing market summary statistics,
                              or a message indicating that data is not loaded.
        """
        if self.market_data is None:
            return "Market data not loaded."

        try:
            summary = self.market_data.describe().to_dict()
            return summary
        except Exception as e:
            logging.error(f"Error generating market summary: {e}")
            return f"Error generating market summary: {e}"

# Example usage (for testing/demonstration purposes)
if __name__ == '__main__':
    # Create a dummy market data file
    dummy_data = {
        'date': ['2023-01-01', '2023-01-02', '2023-01-03'],
        'demand': [90, 110, 100],
        'price': [20, 22, 21]
    }
    dummy_df = pd.DataFrame(dummy_data)
    dummy_csv_path = "/tmp/dummy_market_data.csv"  # Changed to /tmp since we don't have write access
    dummy_df.to_csv(dummy_csv_path, index=False)

    # Create a dummy configuration file
    dummy_config = {
        "demand_column": "demand",
        "price_sensitivity": 0.05,
        "target_demand": 100,
        "min_price": 10,
        "max_price": 30
    }

    dummy_config_path = "/tmp/dummy_pricing_config.json"
    with open(dummy_config_path, 'w') as f:
        json.dump(dummy_config, f)


    try:
        optimizer = PricingOptimizer(config_path=dummy_config_path)
        optimizer.load_market_data(data_path=dummy_csv_path)
        initial_price = 20.0
        optimized_price = optimizer.optimize_price(initial_price)
        print(f"Initial Price: {initial_price}, Optimized Price: {optimized_price}")

        market_summary = optimizer.get_current_market_summary()
        print("Market Summary:")
        print(market_summary)

    except Exception as e:
        print(f"An error occurred: {e}")
    finally:
        # Clean up dummy files (important!)
        if os.path.exists(dummy_csv_path):
            os.remove(dummy_csv_path)
        if os.path.exists(dummy_config_path):
            os.remove(dummy_config_path)