#!/usr/bin/env python3
"""
Normalization Pipeline Examples

This script demonstrates how to use the AtomIngest normalization pipeline
with both simple and complex datasets.
"""

from pathlib import Path
from atomingest.normalization import (
    normalize_csv_file,
    NormalizationConfig,
    NormalizationStepConfig,
    NormalizationPipeline,
)


def simple_example():
    """
    Simple normalization example with basic steps.
    """
    print("=" * 50)
    print("SIMPLE NORMALIZATION EXAMPLE")
    print("=" * 50)

    # Define normalization steps programmatically
    steps = [
        NormalizationStepConfig(step="RemoveBOMStep", config={}, enabled=True),
        NormalizationStepConfig(
            step="TrimWhitespaceStep",
            config={"trim_quotes": True, "collapse_spaces": True},
            enabled=True,
        ),
        NormalizationStepConfig(
            step="NullTokenNormalizationStep",
            config={"null_tokens": ["", "NA", "NULL", "N/A", "-"]},
            enabled=True,
        ),
        NormalizationStepConfig(
            step="ColumnNameNormalizationStep",
            config={
                "case": "lower",
                "replace_spaces": "_",
                "remove_non_alphanumeric": True,
            },
            enabled=True,
        ),
        NormalizationStepConfig(
            step="BasicTypeCleanupStep",
            config={
                "numeric_columns": ["customer_id", "age"],
                "convert_to_number": True,
                "boolean_columns": ["is_active"],
                "true_values": ["true", "yes", "1", "y", "active"],
                "false_values": ["false", "no", "0", "n", "inactive"],
                "date_columns": ["registration_date"],
                "date_formats": ["%Y-%m-%d", "%m/%d/%Y", "%d/%m/%Y"],
                "output_date_format": "%Y-%m-%d",
            },
            enabled=True,
        ),
    ]

    # Process the simple customers CSV
    csv_path = Path(__file__).parent / "simple_customers.csv"

    try:
        rows, report = normalize_csv_file(csv_path, steps=steps, strict=False)

        print(f"Input file: {csv_path}")
        print(f"Rows processed: {report.rows_emitted}")
        print(f"Warnings: {len(report.warnings)}")

        # Display first few normalized rows
        print("\nNormalized data (first 3 rows):")
        for i, row in enumerate(rows[:3]):
            print(f"Row {i+1}: {row}")

        # Display report details
        if report.warnings:
            print("\nWarnings encountered:")
            for warning in report.warnings:
                print(f"  - {warning}")

        print(f"\nReport summary: {report.summary()}")

    except Exception as e:
        print(f"Error processing simple example: {e}")


def complex_example():
    """
    Complex normalization example with advanced features.
    """
    print("\n" + "=" * 50)
    print("COMPLEX NORMALIZATION EXAMPLE")
    print("=" * 50)

    # Create complex configuration from dictionary (simulates YAML loading)
    config_dict = {
        "strict": False,
        "source_type": "csv",
        "source_config": {"delimiter": ",", "encoding": "utf-8"},
        "steps": [
            {
                "step": "RemoveBOMStep",
                "config": {"check_all_lines": False},
                "enabled": True,
            },
            {
                "step": "SkipUntilHeaderStep",
                "config": {
                    "expected_columns": [
                        "Transaction_ID",
                        "Account_Number",
                        "Amount",
                        "Currency",
                        "Date",
                    ],
                    "separator": ",",
                    "max_skip": 20,
                },
                "enabled": True,
            },
            {"step": "DropRepeatedHeaderRowsStep", "config": {}, "enabled": True},
            {
                "step": "DropTrailerLinesStep",
                "config": {
                    "trailer_regex": "^(TOTAL|SUMMARY|END|Record Count:|Total Records:)",
                    "row_count_regex": "Record Count:\\s*(\\d+)",
                    "trailer_position": "end-only",
                    "max_trailer_lines": 10,
                },
                "enabled": True,
            },
            {
                "step": "TrimWhitespaceStep",
                "config": {"trim_quotes": True, "collapse_spaces": True},
                "enabled": True,
            },
            {
                "step": "NullTokenNormalizationStep",
                "config": {
                    "null_tokens": [
                        "",
                        "NA",
                        "NULL",
                        "N/A",
                        "n/a",
                        "nil",
                        "NIL",
                        "-",
                        "--",
                        "###",
                        "NaN",
                        "nan",
                        "NONE",
                        "none",
                        "MISSING",
                        "missing",
                        "UNKNOWN",
                        "unknown",
                    ]
                },
                "enabled": True,
            },
            {
                "step": "ColumnNameNormalizationStep",
                "config": {
                    "alias_map": {
                        "Transaction_ID": "transaction_id",
                        "Account_Number": "account_number",
                        "Amount": "amount",
                        "Currency": "currency_code",
                        "Date": "transaction_date",
                        "Description": "description",
                        "Status": "status",
                        "Reference": "reference_number",
                        "Is_Reversal": "is_reversal",
                    },
                    "case": "lower",
                    "replace_spaces": "_",
                    "remove_non_alphanumeric": True,
                },
                "enabled": True,
            },
            {
                "step": "BasicTypeCleanupStep",
                "config": {
                    "numeric_columns": ["amount"],
                    "convert_to_number": True,
                    "boolean_columns": ["is_reversal"],
                    "true_values": ["true", "yes", "1", "y", "t", "active", "approved"],
                    "false_values": [
                        "false",
                        "no",
                        "0",
                        "n",
                        "f",
                        "inactive",
                        "denied",
                    ],
                    "date_columns": ["transaction_date"],
                    "date_formats": [
                        "%Y-%m-%d",
                        "%m/%d/%Y",
                        "%d/%m/%Y",
                        "%d-%m-%Y",
                        "%Y/%m/%d",
                        "%d-%b-%Y",
                    ],
                    "output_date_format": "%Y-%m-%d",
                },
                "enabled": True,
            },
        ],
    }

    # Create configuration and pipeline
    config = NormalizationConfig.from_dict(config_dict)
    pipeline = NormalizationPipeline(config)

    # Process the complex transactions CSV
    csv_path = Path(__file__).parent / "complex_transactions.csv"

    try:
        row_iterator, report = pipeline.run(csv_path)

        # Consume iterator to get all rows
        rows = list(row_iterator)

        print(f"Input file: {csv_path}")
        print(f"Rows read: {report.rows_read}")
        print(f"Rows emitted: {report.rows_emitted}")
        print(f"Metadata lines skipped: {report.metadata_skipped}")
        print(f"Trailer lines skipped: {report.trailer_skipped}")
        print(f"Duplicate headers removed: {report.duplicate_headers}")
        print(f"Trailer row count: {report.trailer_row_count}")
        print(f"Warnings: {len(report.warnings)}")

        # Display normalized rows
        print("\nNormalized data:")
        for i, row in enumerate(rows):
            print(f"Row {i+1}: {row}")

        # Display report details
        if report.warnings:
            print("\nWarnings encountered:")
            for warning in report.warnings:
                print(f"  - {warning}")

        # Validation summary
        print(f"\nValidation result: {report.validate_row_count(strict=False)}")
        print(f"Report summary: {report.summary()}")

    except Exception as e:
        print(f"Error processing complex example: {e}")
        import traceback

        traceback.print_exc()


def yaml_config_example():
    """
    Example of using YAML configuration (simulated).
    """
    print("\n" + "=" * 50)
    print("YAML CONFIGURATION EXAMPLE")
    print("=" * 50)

    import yaml

    # This would normally be loaded from a YAML file
    yaml_config = """
    normalization:
      strict: false
      source_type: csv
      steps:
        - step: RemoveBOMStep
          config: {}
          enabled: true
        - step: TrimWhitespaceStep
          config:
            trim_quotes: true
            collapse_spaces: true
          enabled: true
        - step: ColumnNameNormalizationStep
          config:
            case: lower
            replace_spaces: "_"
          enabled: true
    """

    try:
        config_data = yaml.safe_load(yaml_config)
        norm_config = NormalizationConfig.from_dict(config_data["normalization"])

        print("Configuration loaded from YAML:")
        print(f"  Strict mode: {norm_config.strict}")
        print(f"  Source type: {getattr(norm_config, 'source_type', 'csv')}")
        print(f"  Number of steps: {len(norm_config.steps)}")

        for i, step in enumerate(norm_config.steps):
            print(f"    Step {i+1}: {step.step} (enabled: {step.enabled})")

    except ImportError:
        print("PyYAML not installed. Install with: pip install PyYAML")
    except Exception as e:
        print(f"Error loading YAML config: {e}")


if __name__ == "__main__":
    """
    Run all normalization examples.
    """
    try:
        simple_example()
        complex_example()
        yaml_config_example()

        print("\n" + "=" * 50)
        print("All examples completed successfully!")
        print("=" * 50)

    except Exception as e:
        print(f"Example failed: {e}")
        import traceback

        traceback.print_exc()
