#!/usr/bin/env python3
"""
Diagnostic script to check primary key detection on actual QGIS layers.

Usage:
    python test_pk_detection_live.py

This script will check all layers in the current QGIS project and report:
- Detected primary key for each layer
- Provider type
- Detection method used
- Warnings for problematic configurations
"""

import sys
import logging
from pathlib import Path

# Configure logging
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)

try:
    from qgis.core import QgsProject, QgsVectorLayer, QgsApplication
    from qgis.utils import iface
except ImportError:
    logger.error("Ce script doit être exécuté dans la console Python de QGIS")
    sys.exit(1)


def analyze_layer_primary_key(layer):
    """
    Analyze primary key detection for a single layer.
    
    Args:
        layer: QgsVectorLayer to analyze
        
    Returns:
        dict: Analysis results
    """
    if not layer or not layer.isValid():
        return {"error": "Layer invalide"}
    
    provider = layer.providerType()
    feature_count = layer.featureCount()
    pk_attributes = layer.primaryKeyAttributes()
    
    result = {
        "name": layer.name(),
        "provider": provider,
        "feature_count": feature_count,
        "declared_pk_indices": pk_attributes,
        "declared_pk_fields": [],
        "has_declared_pk": len(pk_attributes) > 0,
        "warnings": [],
        "recommended_pk": None
    }
    
    # Get declared PK field names
    if pk_attributes:
        fields = layer.fields()
        for idx in pk_attributes:
            if idx < fields.count():
                field = fields[idx]
                result["declared_pk_fields"].append({
                    "index": idx,
                    "name": field.name(),
                    "type": field.typeName(),
                    "is_numeric": field.isNumeric()
                })
    
    # Check for 'id' fields
    id_fields = []
    for field in layer.fields():
        if 'id' in field.name().lower():
            id_fields.append({
                "name": field.name(),
                "type": field.typeName(),
                "is_numeric": field.isNumeric()
            })
    
    result["id_fields_found"] = id_fields
    
    # Analyze based on provider
    if provider == 'postgres':
        if not pk_attributes:
            result["warnings"].append(
                "⚠️ Couche PostgreSQL sans PRIMARY KEY déclarée. "
                "FilterMate utilisera 'ctid' avec limitations."
            )
            if id_fields:
                result["warnings"].append(
                    f"💡 Champ(s) avec 'id' trouvé(s): {[f['name'] for f in id_fields]}. "
                    "FilterMate utilisera le premier."
                )
                result["recommended_pk"] = id_fields[0]["name"]
            else:
                result["warnings"].append(
                    "❌ Aucun champ avec 'id' trouvé. "
                    "Recommandation: ajoutez une PRIMARY KEY."
                )
                result["recommended_pk"] = "ctid"
        else:
            result["recommended_pk"] = result["declared_pk_fields"][0]["name"]
            if len(pk_attributes) > 1:
                result["warnings"].append(
                    f"ℹ️ Clé primaire composée ({len(pk_attributes)} champs). "
                    "FilterMate utilisera le premier champ."
                )
    
    elif provider in ['spatialite', 'ogr']:
        if pk_attributes:
            result["recommended_pk"] = result["declared_pk_fields"][0]["name"]
        elif id_fields:
            result["recommended_pk"] = id_fields[0]["name"]
            result["warnings"].append(
                f"ℹ️ Pas de PK déclarée, mais champ '{id_fields[0]['name']}' trouvé"
            )
        else:
            result["warnings"].append(
                "⚠️ Aucune clé primaire ou champ 'id' trouvé"
            )
    
    elif provider == 'memory':
        if not pk_attributes and not id_fields:
            result["warnings"].append(
                "ℹ️ Couche mémoire sans PK. FilterMate créera 'virtual_id'"
            )
            result["recommended_pk"] = "virtual_id"
    
    return result


def print_layer_report(result):
    """Print formatted report for a single layer."""
    print("\n" + "="*80)
    print(f"Couche: {result['name']}")
    print(f"Provider: {result['provider']}")
    print(f"Features: {result['feature_count']}")
    print("-"*80)
    
    if result.get("error"):
        print(f"❌ Erreur: {result['error']}")
        return
    
    if result["has_declared_pk"]:
        print("✅ Clé primaire déclarée:")
        for pk in result["declared_pk_fields"]:
            print(f"   - {pk['name']} (index {pk['index']}, type {pk['type']})")
    else:
        print("❌ Aucune clé primaire déclarée")
    
    if result["id_fields_found"]:
        print("\n🔍 Champs avec 'id' trouvés:")
        for field in result["id_fields_found"]:
            print(f"   - {field['name']} (type {field['type']})")
    
    if result["recommended_pk"]:
        print(f"\n✨ FilterMate utilisera: {result['recommended_pk']}")
    
    if result["warnings"]:
        print("\n⚠️ Avertissements:")
        for warning in result["warnings"]:
            print(f"   {warning}")


def analyze_all_layers():
    """Analyze all layers in current QGIS project."""
    project = QgsProject.instance()
    layers = project.mapLayers().values()
    
    print("\n" + "="*80)
    print("ANALYSE DES CLÉS PRIMAIRES - FilterMate")
    print("="*80)
    print(f"\nProjet: {project.fileName() or 'Sans nom'}")
    print(f"Nombre de couches: {len(list(layers))}")
    
    results_by_provider = {}
    all_results = []
    
    for layer in layers:
        if not isinstance(layer, QgsVectorLayer):
            continue
        
        result = analyze_layer_primary_key(layer)
        all_results.append(result)
        
        provider = result["provider"]
        if provider not in results_by_provider:
            results_by_provider[provider] = []
        results_by_provider[provider].append(result)
        
        print_layer_report(result)
    
    # Summary
    print("\n" + "="*80)
    print("RÉSUMÉ")
    print("="*80)
    
    for provider, results in results_by_provider.items():
        print(f"\n{provider.upper()}:")
        with_pk = sum(1 for r in results if r["has_declared_pk"])
        without_pk = len(results) - with_pk
        print(f"  Avec PK déclarée: {with_pk}")
        print(f"  Sans PK déclarée: {without_pk}")
        
        if provider == 'postgres' and without_pk > 0:
            print(f"  ⚠️ {without_pk} couche(s) PostgreSQL sans PRIMARY KEY!")
            print("     Recommandation: ajoutez des PRIMARY KEY pour performances optimales")
    
    # Count warnings
    total_warnings = sum(len(r["warnings"]) for r in all_results)
    if total_warnings > 0:
        print(f"\n⚠️ Total d'avertissements: {total_warnings}")
    else:
        print("\n✅ Toutes les couches ont une configuration optimale")
    
    return all_results


if __name__ == '__main__':
    try:
        results = analyze_all_layers()
        print("\n✅ Analyse terminée")
    except Exception as e:
        logger.exception("Erreur lors de l'analyse")
        print(f"\n❌ Erreur: {e}")
