# MediLink_Down.py
import os, shutil
from MediLink_Decoder import process_decoded_file, display_consolidated_records, write_records_to_csv
from MediLink_ConfigLoader import log, load_configuration
from MediLink_DataMgmt import operate_winscp

def handle_files(local_storage_path, downloaded_files):
    """
    Moves downloaded files to the appropriate directory and translates them to CSV format.
    """
    log("Starting to handle downloaded files.")
    
    # Set the local response directory
    local_response_directory = os.path.join(local_storage_path, "responses")
    os.makedirs(local_response_directory, exist_ok=True)
    
    # Supported file extensions
    file_extensions = ['.era', '.277', '.277ibr', '.277ebr', '.dpt', '.ebt', '.ibt', '.txt']
    
    files_moved = []
    
    for file in downloaded_files:
        if any(file.lower().endswith(ext) for ext in file_extensions):  # Case-insensitive match
            source_path = os.path.join(local_storage_path, file)
            destination_path = os.path.join(local_response_directory, file)
            
            try:
                shutil.move(source_path, destination_path)
                log("Moved '{}' to '{}'".format(file, local_response_directory))
                files_moved.append(destination_path)
            except Exception as e:
                log("Error moving file '{}' to '{}': {}".format(file, destination_path, e), level="ERROR")
    
    if not files_moved:
        log("No files were moved. Ensure that files with supported extensions exist in the download directory.", level="WARNING")
    
    # Translate the files
    consolidated_records, translated_files = translate_files(files_moved, local_response_directory)
    
    return consolidated_records, translated_files

def translate_files(files, output_directory):
    """
    Translates given files into CSV format and returns the list of translated files and consolidated records.
    """
    log("Translating files: {}".format(files), level="DEBUG")

    if not files:
        log("No files provided for translation. Exiting translate_files.", level="WARNING")
        return [], []

    translated_files = []
    consolidated_records = []
    
    # Supported file extensions with selector
    file_type_selector = {
        '.era': False,
        '.277': False,
        '.277ibr': False,
        '.277ebr': False,
        '.dpt': False,
        '.ebt': True,  # Only EBT files are processed
        '.ibt': False,
        '.txt': False
    }

    file_counts = {ext: 0 for ext in file_type_selector.keys()}

    for file in files:
        ext = os.path.splitext(file)[1]
        if file_type_selector.get(ext, False):  # Check if the file type is selected
            file_counts[ext] += 1

            try:
                records = process_decoded_file(os.path.join(output_directory, file), output_directory, return_records=True)
                consolidated_records.extend(records)
                csv_file_path = os.path.join(output_directory, os.path.basename(file) + '_decoded.csv')
                translated_files.append(csv_file_path)
                log("Translated file to CSV: {}".format(csv_file_path), level="INFO")
            except ValueError:
                log("Unsupported file type: {}".format(file), level="WARNING")
            except Exception as e:
                log("Error processing file {}: {}".format(file, e), level="ERROR")

    log("Detected and processed file counts by type:")
    for ext, count in file_counts.items():
        log("{}: {} files detected".format(ext, count), level="INFO")

    return consolidated_records, translated_files

def prompt_csv_export(records, output_directory):
    """
    Prompts the user to export consolidated records to a CSV file.
    """
    if records:
        user_input = input("Do you want to export the consolidated records to a CSV file? (y/n): ")
        if user_input.lower() == 'y':
            output_file_path = os.path.join(output_directory, "Consolidated_Records.csv")
            write_records_to_csv(records, output_file_path)
            log("Consolidated CSV file created at: {}".format(output_file_path), level="INFO")
        else:
            log("CSV export skipped by user.", level="INFO")

def main(desired_endpoint=None):
    """
    Main function for running MediLink_Down as a standalone script. 
    Simplified to handle only CLI operations and delegate the actual processing to the high-level function.
    """
    log("Running MediLink_Down.main with desired_endpoint={}".format(desired_endpoint))

    if not desired_endpoint:
        log("No specific endpoint provided. Aborting operation.", level="ERROR")
        return None, None
    
    try:
        config, _ = load_configuration()
        endpoint_config = config['MediLink_Config']['endpoints'].get(desired_endpoint)
        if not endpoint_config or 'remote_directory_down' not in endpoint_config:
            log("Configuration for endpoint '{}' is incomplete or missing 'remote_directory_down'.".format(desired_endpoint), level="ERROR")
            return None, None

        local_storage_path = config['MediLink_Config']['local_storage_path']
        log("Local storage path set to {}".format(local_storage_path))
        
        downloaded_files = operate_winscp("download", None, endpoint_config, local_storage_path, config)
        
        if downloaded_files:
            log("From main(), WinSCP Downloaded the following files: \n{}".format(downloaded_files))
            consolidated_records, translated_files = handle_files(local_storage_path, downloaded_files)
            
            # Convert UnifiedRecord instances to dictionaries before displaying
            dict_consolidated_records = [record.to_dict() for record in consolidated_records]
            display_consolidated_records(dict_consolidated_records)

            # Prompt for CSV export
            prompt_csv_export(consolidated_records, local_storage_path)
            
            return consolidated_records, translated_files
        else:
            log("No files were downloaded for endpoint: {}. Exiting...".format(desired_endpoint), level="WARNING")
            return None, None

    except Exception as e:
        log("An error occurred in MediLink_Down.main: {}".format(e), level="ERROR")
        return None, None

if __name__ == "__main__":
    main()