import os
import inspect
import csv
import sys
from pathlib import Path
from PySide6.QtGui import QShortcut, QKeySequence

def window_shortcut(original_class):
    """类装饰器：为对话框自动添加快捷键支持"""
    class WindowWrapper(original_class):
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            # 添加Ctrl+W快捷键
            shortcut = QShortcut(QKeySequence("Ctrl+W"), self)
            shortcut.activated.connect(self.close)
    
    return WindowWrapper
def getcurpath():
    """Get the path of the current Python file"""
    # Get the caller's stack information
    caller_frame = inspect.stack()[1]
    caller_file = caller_frame.filename
    # Get the absolute path of the caller file's directory
    caller_directory_path = os.path.dirname(os.path.abspath(caller_file))
    return caller_directory_path

def get_current_py_name():
    """Get the name of the current Python file"""
    return os.path.basename(__file__)

def load_data(file_path=None):
    data = None
    try:
        # Try to read data file with different delimiters
        delimiters = [None, ',', '\t']  # None means any whitespace
        for delimiter in delimiters:
            try:
                data = np.loadtxt(file_path, delimiter=delimiter)
                # Check if we have at least two columns
                if data.ndim == 2 and data.shape[1] >= 2:
                    break
                else:
                    data = None
            except:
                continue
    except Exception as e:
        print(e)
    return data     


def is_file_exist(path):
    # Check if the path exists
    if os.path.exists(path):
        # If it exists, further check if it's a file
        if os.path.isfile(path):
            return True
        else:
            return False
    else:
        return False
    

def readTxt(file):
    x = []
    y = []
    with open(file, 'r', newline='') as file:
        # Use csv.reader to read the file, specifying comma as the delimiter
        reader = csv.reader(file)
        for row in reader:
            # Ensure each row has two values
            if len(row) == 2:
                try:
                    # Convert strings to floats and add to x and y lists
                    x.append(float(row[0]))
                    y.append(float(row[1]))
                except ValueError:
                    print(f"Unable to convert '{row}' to numerical value, skipping this row.")
            else:
                print(f"Incorrect row format: '{row}', skipping this row.")
    return x,y          


import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import gaussian_kde

def data_distribution(file, ax=None, data=None, fig=None):
    if data is None:
        _, data = readTxt(file)
    # Calculate statistics
    stats = {
        'max': np.max(data),
        'min': np.min(data),
        'mean': np.mean(data),
        'median': np.median(data),
        'variance': np.var(data)
    }
      # Create a figure or use the provided ax
    if ax is None:
        fig, ax1 = plt.subplots(figsize=(10, 6))
    else:
        ax1 = ax
    # --- Plot histogram ---
    NUM = 20
    bin_width = (np.max(data) - np.min(data))/NUM
    bins = np.arange(np.min(data), np.max(data) + bin_width, bin_width)
    
    # Plot the histogram
    n, bins, patches = ax1.hist(data, bins, 
                               width=bin_width,
                               color='skyblue',
                               edgecolor='white',
                               alpha=0.7,
                               label=get_label(stats))
    
    # --- Plot KDE curve ---
    ax2 = ax1.twinx()
    kde = gaussian_kde(data)
    x_grid = np.linspace(np.min(data)-1, np.max(data)+1, 500)
    y_kde = kde(x_grid)
    ax2.plot(x_grid, y_kde, 'r-', linewidth=2)
    
    # --- Beautify the plot ---
    ax1.set_title(find_file_name(file) + ': kernel fit of the data', pad=20)
    ax1.set_xlabel('Value')
    ax1.set_ylabel('Frequency (Histogram)', color='skyblue')
    ax2.set_ylabel('Density (KDE)', color='red')
    
    ax1.tick_params(axis='y', colors='skyblue')
    ax2.tick_params(axis='y', colors='red')
    ax1.grid(axis='y', alpha=0.3)
    
    # Set axis range
    ax1.set_xlim(min(data)-bin_width, max(data)+bin_width)
    
    # Combine legends
    lines1, labels1 = ax1.get_legend_handles_labels()
    lines2, labels2 = ax2.get_legend_handles_labels()
    ax1.legend(lines1 + lines2, labels1 + labels2, loc='upper right')
    # Display control
    if ax is None:
        plt.tight_layout()
        plt.show()
    elif fig is not None:
        fig.tight_layout()
        if hasattr(fig, 'canvas'):
            fig.canvas.draw()
    # Return the ax object for further operations
    return ax1

def find_file_name(file_path = ''):
    # Get the file name with extension
    file_name_with_ext = Path(file_path).name
    # Get the file name without extension
    file_name = Path(file_path).stem
    return file_name

def get_label(stats):
    return  f"Max: {stats['max']}, Min: {stats['min']}, Mean: {stats['mean']}, Median: {stats['median']}, Variance: {stats['variance']}"


# Example usage (replace with your own data)
if __name__ == "__main__":
    # Generate simulated data (normal distribution, parameters close to your example data)
    np.random.seed(42)
    data = np.random.normal(loc=4.67, scale=0.1, size=100)
    
    # Analyze and plot
    fig, stats = data_distribution(file='Example-SvalbardPETM-logFe.txt')
     
    # Print statistics
    print("Statistics:")
    for name, value in stats.items():
        print(f"{name}: {value:.4f}")
    
    plt.show()