# docs/examples/example_tolerance_comparison.py

"""
Example: Metric Reconciliation and Tolerance Comparison

This script demonstrates a key validation feature of BatteryProc:
1.  Loading a CSV file with intentional errors in the file-reported capacity.
2.  Recomputing the capacity summary from the raw data.
3.  Showing how different tolerance settings affect the decision to either
    keep the file's values or replace them with the recomputed ones.
"""

import pandas as pd

from batteryproc.formulas import normalize_inputs, per_cycle_capacity_summary
from batteryproc.metric_reconcile import reconcile_metric_sources


def run_tolerance_comparison_example():
    """
    Shows how metric reconciliation works with different tolerances.
    """
    print("--- Running Metric Reconciliation Example ---")

    # 1. Load data with known discrepancies
    try:
        df = pd.read_csv("docs/examples/sample_tolerance_test.csv")
        print("Loaded sample_tolerance_test.csv successfully.")
    except FileNotFoundError:
        print(
            "Error: sample_tolerance_test.csv not found. Make sure you are running from the repo root."
        )
        return

    # 2. Normalize inputs
    inputs = normalize_inputs(df)
    print("\nInputs normalized.")

    # 3. Create a realistic file-reported summary with non-canonical, instrument-style names
    file_summary = pd.DataFrame(
        {
            "Cycle": [1.0, 2.0],
            "Chg. Cap.(mAh)": [0.90, 0.84],  # Intentionally incorrect
            "DChg. Cap.(mAh)": [0.70, 0.65],  # Intentionally incorrect
        }
    )
    print("\nOriginal File-Reported Summary (with non-canonical names):")
    print(file_summary)

    # 4. Recompute the metrics from raw data to get the ground truth
    recomputed_summary = per_cycle_capacity_summary(inputs)
    print("\nRecomputed Summary (Ground Truth):")
    print(recomputed_summary[["cycle_index", "charge_mAh", "discharge_mAh"]])

    # 5. Define a function to run and display reconciliation
    def test_reconciliation(rtol, atol, prefer_file=True):
        print(f"\n--- Testing with rtol={rtol}, atol={atol}, prefer_file={prefer_file} ---")

        reconciled = reconcile_metric_sources(
            file_cycle=file_summary,
            recomputed_capacity=recomputed_summary,
            recomputed_energy=None,
            prefer_file=prefer_file,
            recompute_all=not prefer_file,
            relative_tolerance=rtol,
            absolute_tolerance=atol,
        )

        print("\nComparison Report (Charge Capacity):")
        if reconciled.comparison_result:
            report = reconciled.comparison_result.per_metric.get("charge_mAh")
            if report is not None:
                print(
                    report[
                        [
                            "cycle_index",
                            "file_value",
                            "recomputed_value",
                            "diff",
                            "within_tolerance",
                        ]
                    ]
                )
        else:
            print("No comparison was performed.")

        print("\nFinal (Reconciled) Summary:")
        # Use the correct, canonical column names
        print(reconciled.capacity_summary[["cycle_index", "charge_mAh", "discharge_mAh"]])
        return reconciled.capacity_summary

    # --- Scenario 1: Loose Tolerances ---
    # With a high tolerance, the incorrect file values are KEPT.
    test_reconciliation(rtol=1.0, atol=1.0)

    # --- Scenario 2: Tight Tolerances ---
    # With tight tolerances, the errors are caught and RECOMPUTED values are used.
    test_reconciliation(rtol=0.01, atol=0.1)

    # --- Scenario 3: Forcing Recomputation ---
    # `prefer_file=False` is equivalent to the `--recompute-all` CLI flag.
    # The recomputed values are ALWAYS used.
    test_reconciliation(rtol=0.05, atol=0.5, prefer_file=False)


if __name__ == "__main__":
    run_tolerance_comparison_example()
