"""
CLI commands for quality assurance.
"""

from __future__ import annotations

import json
import sys
from pathlib import Path

from pycharter.config import get_database_url
from pycharter.metadata_store import PostgresMetadataStore
from pycharter.quality import QualityCheck, QualityCheckOptions, QualityThresholds


def cmd_quality_check(
    schema_id: str | None,
    contract: str | None,
    data: str,
    database_url: str | None,
    record_violations: bool,
    check_thresholds: bool,
    thresholds_file: str | None,
    sample_size: int | None,
    output: str | None,
) -> int:
    """
    Run quality check command.

    Args:
        schema_id: Schema ID (for store-based validation)
        contract: Contract file path (for contract-based validation)
        data: Data file path or '-' for stdin
        database_url: Database connection string
        record_violations: Whether to record violations
        check_thresholds: Whether to check thresholds
        thresholds_file: Path to thresholds JSON file
        sample_size: Sample size for large datasets
        output: Output file path

    Returns:
        Exit code (0 for success, 1 for failure)
    """
    try:
        # Validate arguments
        if not schema_id and not contract:
            print(
                "❌ Error: Either --schema-id or --contract must be provided",
                file=sys.stderr,
            )
            return 1

        if schema_id and not database_url:
            # Try to get from config
            database_url = get_database_url()
            if not database_url:
                print(
                    "❌ Error: --database-url required when using --schema-id",
                    file=sys.stderr,
                )
                return 1

        # Initialize store if needed
        store = None
        if schema_id:
            store = PostgresMetadataStore(connection_string=database_url)
            store.connect()
            print(f"✓ Connected to database")

        # Load thresholds if provided
        thresholds = None
        if check_thresholds:
            if thresholds_file:
                with open(thresholds_file, "r") as f:
                    thresholds_data = json.load(f)
                    thresholds = QualityThresholds(**thresholds_data)
            else:
                # Use default thresholds
                thresholds = QualityThresholds()

        # Create quality check
        quality_check = QualityCheck(store=store)

        # Build options
        options = QualityCheckOptions(
            record_violations=record_violations,
            calculate_metrics=True,
            check_thresholds=check_thresholds,
            thresholds=thresholds,
            include_field_metrics=True,
            sample_size=sample_size,
        )

        # Prepare data source
        if data == "-":
            # Read from stdin
            data_source = json.load(sys.stdin)
            if not isinstance(data_source, list):
                data_source = [data_source]
        else:
            data_path = Path(data)
            if not data_path.exists():
                print(f"❌ Error: Data file not found: {data}", file=sys.stderr)
                return 1
            data_source = data

        # Run quality check
        print(f"Running quality check...")
        if schema_id:
            print(f"  Schema ID: {schema_id}")
        if contract:
            print(f"  Contract: {contract}")
        print(f"  Data: {data}")

        report = quality_check.run(
            schema_id=schema_id,
            contract=contract,
            data=data_source,
            options=options,
        )

        # Display results
        print("\n" + "=" * 70)
        print("Quality Check Report")
        print("=" * 70)
        print(f"Schema ID: {report.schema_id}")
        print(f"Check Timestamp: {report.check_timestamp}")
        print(f"Record Count: {report.record_count}")
        print(f"Valid Records: {report.valid_count}")
        print(f"Invalid Records: {report.invalid_count}")

        if report.quality_score:
            print(f"\nQuality Score: {report.quality_score.overall_score:.2f}/100")
            print(f"  Accuracy: {report.quality_score.accuracy:.2%}")
            print(f"  Completeness: {report.quality_score.completeness:.2%}")
            print(f"  Violation Rate: {report.quality_score.violation_rate:.2%}")

        if report.threshold_breaches:
            print(f"\n⚠ Threshold Breaches:")
            for breach in report.threshold_breaches:
                print(f"  - {breach}")

        if report.violation_count > 0:
            print(f"\n⚠ Violations Recorded: {report.violation_count}")

        # Save report if output specified
        if output:
            output_path = Path(output)
            with open(output_path, "w") as f:
                json.dump(report.model_dump(), f, indent=2, default=str)
            print(f"\n✓ Report saved to: {output}")

        # Return exit code based on pass/fail
        if report.passed:
            print("\n✓ Quality check passed")
            return 0
        else:
            print("\n❌ Quality check failed")
            return 1

    except Exception as e:
        print(f"❌ Error running quality check: {e}", file=sys.stderr)
        import traceback

        traceback.print_exc()
        return 1
    finally:
        if store:
            store.disconnect()


def cmd_quality_violations(
    schema_id: str | None,
    status: str | None,
    severity: str | None,
    database_url: str | None = None,
    limit: int | None = None,
    output: str | None = None,
) -> int:
    """Query and display quality violations from the database.

    Args:
        schema_id: Filter by schema ID.
        status: Filter by status (open, resolved, ignored).
        severity: Filter by severity (critical, warning, info).
        database_url: Database connection string. Resolved from config
            or ``DATABASE_URL`` env var when *None*.
        limit: Maximum number of violations to return.
        output: Output file path for JSON export.

    Returns:
        Exit code (0 for success, 1 for failure).
    """
    engine = None
    session = None
    try:
        # Resolve database URL
        if not database_url:
            database_url = get_database_url()
        if not database_url:
            print(
                "Error: --database-url is required (or set DATABASE_URL)",
                file=sys.stderr,
            )
            return 1

        from sqlalchemy import create_engine
        from sqlalchemy.orm import Session as SASession

        from pycharter.quality.violations import ViolationTracker

        engine = create_engine(database_url)
        session = SASession(bind=engine)

        tracker = ViolationTracker(db_session=session)
        violations = tracker.get_violations(
            schema_id=schema_id,
            severity=severity,
            status=status,
            limit=limit,
        )

        # Display violations table
        print("\nQuality Violations")
        print("=" * 70)

        if not violations:
            print("No violations found matching the filters.")
            return 0

        for v in violations:
            print(f"\n  ID: {v.id}")
            print(f"  Schema: {v.schema_id}")
            print(f"  Record: {v.record_id}")
            print(f"  Severity: {v.severity}")
            print(f"  Status: {v.status}")
            print(f"  Errors: {len(v.field_violations)}")
            print(f"  Timestamp: {v.timestamp}")
            for fv in v.field_violations:
                print(f"    - {fv.get('field', '?')}: {fv.get('error_message', '?')}")

        # Summary
        summary = tracker.get_violation_summary(schema_id=schema_id)
        print(f"\n{'=' * 70}")
        print(
            f"Total: {summary['total']}  |  "
            f"Open: {summary['open']}  |  "
            f"Resolved: {summary['resolved']}  |  "
            f"Ignored: {summary['ignored']}"
        )
        print(
            f"By severity — "
            f"Critical: {summary['by_severity']['critical']}  |  "
            f"Warning: {summary['by_severity']['warning']}  |  "
            f"Info: {summary['by_severity']['info']}"
        )

        # Export to JSON if requested
        if output:
            output_path = Path(output)
            violations_data = [v.to_dict() for v in violations]
            with open(output_path, "w") as f:
                json.dump(violations_data, f, indent=2, default=str)
            print(f"\nViolations exported to: {output}")

        return 0

    except Exception as e:
        print(f"Error querying violations: {e}", file=sys.stderr)
        import traceback

        traceback.print_exc()
        return 1
    finally:
        if session:
            session.close()
        if engine:
            engine.dispose()
