# docs/examples/example_cycle_detection.py

"""
Example: Cycle Detection Methods

This script demonstrates how to use the flexible cycle detection engine in
BatteryProc. It shows how to:
1.  Run the default 'auto' detection method.
2.  Force the 'step_type' method for labeled data.
3.  Force the 'current_sign' method for unlabeled or raw data.
4.  Inspect the metadata produced by the detection process.
"""

import pandas as pd

from batteryproc.batteryproc_types import CycleDetectionMethod
from batteryproc.formulas import detect_cycle_boundaries, normalize_inputs


def run_cycle_detection_example():
    """
    Demonstrates various cycle detection methods on sample data.
    """
    print("--- Running Cycle Detection Example ---")

    # 1. Load data with reliable step type labels
    try:
        df = pd.read_excel("docs/examples/sample_cccv.xlsx")
        print("Loaded sample_cccv.xlsx successfully.")
    except FileNotFoundError:
        print("Error: sample_cccv.xlsx not found. Make sure you are running from the repo root.")
        return

    inputs = normalize_inputs(df)
    print("Inputs normalized.")

    # --- Method 1: AUTO (Default) ---
    # The 'auto' method will try the most reliable detection strategies first.
    # In this case, it will find and validate the 'step_type' labels.
    print("\nRunning AUTO cycle detection...")
    auto_cycles = detect_cycle_boundaries(inputs, method=CycleDetectionMethod.AUTO)
    print(f"Detected {auto_cycles.max()} cycles.")
    print("Detection metadata:")
    print(auto_cycles.attrs)

    # --- Method 2: Forcing STEP_TYPE ---
    # This explicitly tells the engine to rely on the 'step_type' column.
    print("\nRunning STEP_TYPE cycle detection...")
    step_type_cycles = detect_cycle_boundaries(inputs, method=CycleDetectionMethod.STEP_TYPE)
    print(f"Detected {step_type_cycles.max()} cycles.")
    print("Detection metadata:")
    print(step_type_cycles.attrs)

    # --- Method 3: Forcing CURRENT_SIGN ---
    # This method is ideal for data without reliable labels. It looks at the
    # sign of the current to identify charge/discharge transitions.
    print("\nRunning CURRENT_SIGN cycle detection...")
    current_sign_cycles = detect_cycle_boundaries(
        inputs,
        method=CycleDetectionMethod.CURRENT_SIGN,
        current_sign_kwargs={"current_threshold": 0.1},  # Use a 0.1A threshold
    )
    print(f"Detected {current_sign_cycles.max()} cycles.")
    print("Detection metadata:")
    print(current_sign_cycles.attrs)

    # Compare the results
    df_results = pd.DataFrame(
        {
            "time_s": inputs.time_s,
            "current_a": inputs.current_a,
            "auto_cycle": auto_cycles,
            "step_type_cycle": step_type_cycles,
            "current_sign_cycle": current_sign_cycles,
        }
    )

    print("\nComparison of Cycle Indices:")
    print(df_results)


if __name__ == "__main__":
    run_cycle_detection_example()
