"""
HubSpot ETL Load Module.

This module handles the loading phase of the HubSpot ETL pipeline.
It takes the transformed data and loads it into the target system, typically the
Nemo database or data warehouse.

The loading process typically includes:
1. Data validation before insertion
2. Connection management to target systems
3. Batch processing for efficient data loading
4. Error handling and rollback capabilities
5. Data integrity checks post-loading
6. Performance optimization for large datasets
7. Comprehensive logging throughout the process

Classes:
    HubSpotLoad: Main class handling HubSpot data loading.
"""

from prefect import get_run_logger
from nemo_library_etl.adapter._utils.enums import ETLAdapter, ETLStep
from nemo_library_etl.adapter._utils.file_handler import ETLFileHandler
from nemo_library_etl.adapter.hubspot.config_models import PipelineHubSpot
from nemo_library import NemoLibrary

from nemo_library_etl.adapter.hubspot.enums import HubSpotLoadStep


class HubSpotLoad:
    """
    Handles loading of transformed HubSpot data into target system.
    
    This class manages the loading phase of the HubSpot ETL pipeline,
    providing methods to insert transformed data into the target system with
    proper error handling, validation, and performance optimization.
    
    The loader:
    - Uses NemoLibrary for core functionality and configuration
    - Integrates with Prefect logging for pipeline visibility
    - Manages database connections and transactions
    - Provides batch processing capabilities
    - Handles data validation before insertion
    - Ensures data integrity and consistency
    - Optimizes performance for large datasets
    
    Attributes:
        nl (NemoLibrary): Core Nemo library instance for system integration.
        config: Configuration object from the Nemo library.
        logger: Prefect logger for pipeline execution tracking.
        cfg (PipelineHubSpot): Pipeline configuration with loading settings.
    """
    
    def __init__(self, cfg:PipelineHubSpot):
        """
        Initialize the HubSpotLoad instance.
        
        Sets up the loader with the necessary library instances, configuration,
        and logging capabilities for the loading process.
        
        Args:
            cfg (PipelineHubSpot): Pipeline configuration object containing
                                                          loading settings and target system configuration.
        """
        self.nl = NemoLibrary()
        self.config = self.nl.config
        self.logger = get_run_logger()
        self.cfg = cfg

        super().__init__()

    def load(self) -> None:
        """
        Execute the main loading process for HubSpot data.
        
        This method orchestrates the complete loading process by:
        1. Connecting to the target system (database, data warehouse, etc.)
        2. Loading transformed data from the previous ETL phase
        3. Validating data before insertion
        4. Performing batch inserts for optimal performance
        5. Handling errors and implementing rollback mechanisms
        6. Verifying data integrity post-insertion
        7. Updating metadata and audit tables
        8. Cleaning up temporary resources
        
        The method provides detailed logging for monitoring and debugging purposes
        and ensures transaction safety through proper error handling.
        
        Note:
            The actual loading logic needs to be implemented based on
            the target system requirements and data models.
        """
        self.logger.info("Loading all HubSpot objects")

        # load objects
        self.load_forecast_call()

    def load_forecast_call(self) -> None:
        """
        Load forecast call data into the target system.
        """
        # Load transformed deals data
        filehandler = ETLFileHandler()
        deals = filehandler.readJSONL(
            adapter=ETLAdapter.HUBSPOT,
            step=ETLStep.TRANSFORM,
            entity=HubSpotLoadStep.DEALS,
        )

        # dump the header
        header = [
            deal for deal in deals if deal.get("dealname").startswith("(FORECAST)")
        ]
        filehandler.writeJSONL(
            adapter=ETLAdapter.HUBSPOT,
            step=ETLStep.LOAD,
            entity=HubSpotLoadStep.DEALS_FORECAST_HEADER,
            data=header,
        )

        # dump the deals itself
        forecast_deals = [
            deal
            for deal in deals
            if not deal.get("dealname", "").startswith("(FORECAST)")
            and deal.get("closedate")
            and deal.get("amount")
            and float(deal.get("amount")) > 0
            and not deal.get("dealstage") in ["Unqualified lead", "closed and lost"]
        ]
        filehandler.writeJSONL(
            adapter=ETLAdapter.HUBSPOT,
            step=ETLStep.LOAD,
            entity=HubSpotLoadStep.DEALS_FORECAST_DEALS,
            data=forecast_deals,
        )
                
        