"""Detailed structure validation for all SQLAlchemy models."""
import sys
import os

# Set UTF-8 encoding for Windows console
if os.name == 'nt':
    import io
    sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace')

import api.models
from sqlalchemy.orm import RelationshipProperty
from sqlalchemy.schema import ForeignKeyConstraint, CheckConstraint, Index


def get_table_models():
    """Get all table model classes (excluding base classes)."""
    base_classes = {'Base', 'TimestampMixin', 'UUIDMixin'}
    all_classes = [attr for attr in dir(api.models) if not attr.startswith('_') and attr[0].isupper()]
    return sorted([m for m in all_classes if m not in base_classes])


def analyze_model(model_name):
    """Analyze a model's structure in detail."""
    model_cls = getattr(api.models, model_name)

    result = {
        'name': model_name,
        'table': model_cls.__tablename__,
        'has_uuid_mixin': False,
        'has_timestamp_mixin': False,
        'foreign_keys': [],
        'relationships': [],
        'indexes': [],
        'check_constraints': [],
        'columns': []
    }

    # Check mixins
    for base in model_cls.__mro__:
        if base.__name__ == 'UUIDMixin':
            result['has_uuid_mixin'] = True
        if base.__name__ == 'TimestampMixin':
            result['has_timestamp_mixin'] = True

    # Get table object
    if hasattr(model_cls, '__table__'):
        table = model_cls.__table__

        # Analyze columns
        for col in table.columns:
            col_info = {
                'name': col.name,
                'type': str(col.type),
                'nullable': col.nullable,
                'primary_key': col.primary_key
            }
            result['columns'].append(col_info)

        # Analyze foreign keys
        for fk in table.foreign_keys:
            result['foreign_keys'].append({
                'parent_column': fk.parent.name,
                'target': str(fk.target_fullname)
            })

        # Analyze indexes
        if hasattr(table, 'indexes'):
            for idx in table.indexes:
                result['indexes'].append({
                    'name': idx.name,
                    'columns': [col.name for col in idx.columns]
                })

        # Analyze check constraints
        for constraint in table.constraints:
            if isinstance(constraint, CheckConstraint):
                result['check_constraints'].append({
                    'sqltext': str(constraint.sqltext)
                })

    # Analyze relationships
    for attr_name in dir(model_cls):
        try:
            attr = getattr(model_cls, attr_name)
            if hasattr(attr, 'property') and isinstance(attr.property, RelationshipProperty):
                rel = attr.property
                result['relationships'].append({
                    'name': attr_name,
                    'target': rel.mapper.class_.__name__,
                    'uselist': rel.uselist
                })
        except (AttributeError, TypeError):
            continue

    return result


def print_model_summary(result):
    """Print a formatted summary of model structure."""
    print(f"\n{'='*70}")
    print(f"Model: {result['name']} (table: {result['table']})")
    print(f"{'='*70}")

    # Mixins
    mixins = []
    if result['has_uuid_mixin']:
        mixins.append('UUIDMixin')
    if result['has_timestamp_mixin']:
        mixins.append('TimestampMixin')
    if mixins:
        print(f"Mixins: {', '.join(mixins)}")

    # Columns
    print(f"\nColumns ({len(result['columns'])}):")
    for col in result['columns'][:10]:  # Limit to first 10 for readability
        pk = " [PK]" if col['primary_key'] else ""
        nullable = "NULL" if col['nullable'] else "NOT NULL"
        print(f"  - {col['name']}: {col['type']} {nullable}{pk}")
    if len(result['columns']) > 10:
        print(f"  ... and {len(result['columns']) - 10} more columns")

    # Foreign Keys
    if result['foreign_keys']:
        print(f"\nForeign Keys ({len(result['foreign_keys'])}):")
        for fk in result['foreign_keys']:
            print(f"  - {fk['parent_column']} -> {fk['target']}")

    # Relationships
    if result['relationships']:
        print(f"\nRelationships ({len(result['relationships'])}):")
        for rel in result['relationships']:
            rel_type = "many" if rel['uselist'] else "one"
            print(f"  - {rel['name']} -> {rel['target']} ({rel_type})")

    # Indexes
    if result['indexes']:
        print(f"\nIndexes ({len(result['indexes'])}):")
        for idx in result['indexes']:
            cols = ', '.join(idx['columns'])
            print(f"  - {idx['name']}: ({cols})")

    # Check Constraints
    if result['check_constraints']:
        print(f"\nCheck Constraints ({len(result['check_constraints'])}):")
        for check in result['check_constraints']:
            print(f"  - {check['sqltext']}")


def main():
    print("="*70)
    print("ClaudeTools - Detailed Model Structure Analysis")
    print("="*70)

    models = get_table_models()
    print(f"\nAnalyzing {len(models)} table models...\n")

    all_results = []
    for model_name in models:
        try:
            result = analyze_model(model_name)
            all_results.append(result)
        except Exception as e:
            print(f"[ERROR] Error analyzing {model_name}: {e}")
            import traceback
            traceback.print_exc()

    # Print summary statistics
    print("\n" + "="*70)
    print("SUMMARY STATISTICS")
    print("="*70)

    total_models = len(all_results)
    models_with_uuid = sum(1 for r in all_results if r['has_uuid_mixin'])
    models_with_timestamp = sum(1 for r in all_results if r['has_timestamp_mixin'])
    models_with_fk = sum(1 for r in all_results if r['foreign_keys'])
    models_with_rel = sum(1 for r in all_results if r['relationships'])
    models_with_idx = sum(1 for r in all_results if r['indexes'])
    models_with_checks = sum(1 for r in all_results if r['check_constraints'])

    total_fk = sum(len(r['foreign_keys']) for r in all_results)
    total_rel = sum(len(r['relationships']) for r in all_results)
    total_idx = sum(len(r['indexes']) for r in all_results)
    total_checks = sum(len(r['check_constraints']) for r in all_results)

    print(f"\nTotal Models: {total_models}")
    print(f"  - With UUIDMixin: {models_with_uuid}")
    print(f"  - With TimestampMixin: {models_with_timestamp}")
    print(f"  - With Foreign Keys: {models_with_fk} (total: {total_fk})")
    print(f"  - With Relationships: {models_with_rel} (total: {total_rel})")
    print(f"  - With Indexes: {models_with_idx} (total: {total_idx})")
    print(f"  - With CHECK Constraints: {models_with_checks} (total: {total_checks})")

    # Print detailed info for each model
    print("\n" + "="*70)
    print("DETAILED MODEL INFORMATION")
    print("="*70)

    for result in all_results:
        print_model_summary(result)

    print("\n" + "="*70)
    print("[SUCCESS] Analysis complete!")
    print("="*70)


if __name__ == "__main__":
    main()
