#!/usr/bin/env python3
"""
Test du feedback détaillé sur échec de matching.
"""

from geniusia2.core.enhanced_workflow_matcher import EnhancedWorkflowMatcher, MatchDifference
from geniusia2.core.multimodal_embedding_manager import MultiModalEmbeddingManager
from geniusia2.core.ui_element_models import (
    UIElement, UIElementType, VisualData, TextData, 
    ElementProperties, ElementContext, EnrichedScreenState,
    WindowInfo, RawData, PerceptionData
)
from geniusia2.core.logger import Logger
import numpy as np
from dataclasses import dataclass
from typing import List, Optional
from datetime import datetime

print('Test du feedback détaillé sur échec de matching')
print('='*60)

# Créer les composants
logger = Logger(log_dir='test_logs')
mm_manager = MultiModalEmbeddingManager(logger=logger, data_dir='test_data')
matcher = EnhancedWorkflowMatcher(mm_manager, logger=logger)

# Définir les structures de workflow
@dataclass
class WorkflowStep:
    step_id: int
    action_type: str
    target_description: str
    position: tuple
    window: str
    embedding: Optional[np.ndarray] = None

@dataclass
class Workflow:
    workflow_id: str
    name: str
    steps: List[WorkflowStep]
    repetitions: int
    confidence: float

# Scénario 1: Match parfait (pas de feedback)
print('\n1. Test Match Parfait (pas de feedback):')
print('-' * 60)

button = UIElement(
    element_id='btn_001',
    type=UIElementType.BUTTON,
    role='primary_action',
    bbox=(100, 200, 80, 30),
    label='Submit',
    visual=VisualData('test.png', 'test', 'test.npy'),
    text=TextData('Submit', 'submit', 'test', 'test.npy'),
    properties=ElementProperties(is_clickable=True),
    context=ElementContext('TestApp', 'Test Window'),
    confidence=0.95
)

screen_state = EnrichedScreenState(
    screen_state_id='screen_001',
    timestamp=datetime.now(),
    session_id='session_001',
    window=WindowInfo('TestApp', 'Test Window', True),
    raw=RawData('test.png'),
    perception=PerceptionData(['Extracted text']),
    ui_elements=[button],
    state_embedding=None,
    context=None
)

step1 = WorkflowStep(1, 'click', 'submit button', (140, 215), 'test', np.random.rand(512))
workflow_perfect = Workflow('wf_perfect', 'Perfect Match', [step1], 5, 0.95)

# Simuler un embedding parfait
current_embedding = np.random.rand(512)

match_perfect = matcher._compute_workflow_match(
    screen_state, current_embedding, workflow_perfect
)

print(f'✓ Score composite: {match_perfect.composite_score:.3f}')
print(f'✓ Confiance: {match_perfect.confidence:.3f}')
print(f'✓ Différences: {len(match_perfect.differences) if match_perfect.differences else 0}')
if match_perfect.differences:
    print(f'⚠ Feedback inattendu pour un match parfait!')
else:
    print(f'✓ Pas de feedback (comme attendu pour un bon match)')

# Scénario 2: Match partiel avec éléments manquants
print('\n2. Test Match Partiel (éléments manquants):')
print('-' * 60)

# Workflow avec 3 steps mais seulement 1 élément détecté
step1 = WorkflowStep(1, 'type', 'username field', (150, 162), 'test')
step2 = WorkflowStep(2, 'type', 'password field', (150, 200), 'test')
step3 = WorkflowStep(3, 'click', 'submit button', (140, 250), 'test')
workflow_partial = Workflow('wf_partial', 'Partial Match', [step1, step2, step3], 5, 0.8)

# Seulement 1 élément détecté
screen_state_partial = EnrichedScreenState(
    screen_state_id='screen_002',
    timestamp=datetime.now(),
    session_id='session_001',
    window=WindowInfo('TestApp', 'Test Window', True),
    raw=RawData('test.png'),
    perception=PerceptionData(['Extracted text']),
    ui_elements=[button],  # Seulement 1 élément au lieu de 3
    state_embedding=None,
    context=None
)

match_partial = matcher._compute_workflow_match(
    screen_state_partial, current_embedding, workflow_partial
)

print(f'✓ Score composite: {match_partial.composite_score:.3f}')
print(f'✓ Confiance: {match_partial.confidence:.3f}')
print(f'✓ Différences détectées: {len(match_partial.differences) if match_partial.differences else 0}')

if match_partial.differences:
    print(f'\n📋 Feedback détaillé:')
    for i, diff in enumerate(match_partial.differences, 1):
        print(f'\n  {i}. [{diff.severity.upper()}] {diff.difference_type}')
        print(f'     Description: {diff.description}')
        if diff.expected:
            print(f'     Attendu: {diff.expected}')
        if diff.actual:
            print(f'     Actuel: {diff.actual}')
        if diff.suggestion:
            print(f'     💡 Suggestion: {diff.suggestion}')

# Scénario 3: Test du résumé de feedback
print('\n3. Test Résumé de Feedback:')
print('-' * 60)

if match_partial.differences:
    summary = match_partial.get_feedback_summary()
    print(summary)

# Scénario 4: Match avec faible confiance
print('\n4. Test Match avec Faible Confiance:')
print('-' * 60)

button_low_conf = UIElement(
    element_id='btn_002',
    type=UIElementType.BUTTON,
    role='primary_action',
    bbox=(100, 200, 80, 30),
    label='Maybe Submit',
    visual=VisualData('test.png', 'test', 'test.npy'),
    text=TextData('Maybe Submit', 'maybe submit', 'test', 'test.npy'),
    properties=ElementProperties(is_clickable=True),
    context=ElementContext('TestApp', 'Test Window'),
    confidence=0.35  # Faible confiance
)

screen_state_low_conf = EnrichedScreenState(
    screen_state_id='screen_003',
    timestamp=datetime.now(),
    session_id='session_001',
    window=WindowInfo('TestApp', 'Test Window', True),
    raw=RawData('test.png'),
    perception=PerceptionData(['Extracted text']),
    ui_elements=[button_low_conf],
    state_embedding=None,
    context=None
)

match_low_conf = matcher._compute_workflow_match(
    screen_state_low_conf, current_embedding, workflow_perfect
)

print(f'✓ Score composite: {match_low_conf.composite_score:.3f}')
print(f'✓ Confiance: {match_low_conf.confidence:.3f}')
print(f'✓ Différences détectées: {len(match_low_conf.differences) if match_low_conf.differences else 0}')

if match_low_conf.differences:
    print(f'\n📋 Résumé:')
    print(match_low_conf.get_feedback_summary())

# Test de la conversion en dictionnaire
print('\n5. Test Sérialisation JSON:')
print('-' * 60)

match_dict = match_partial.to_dict()
print(f'✓ Workflow ID: {match_dict["workflow_id"]}')
print(f'✓ Score composite: {match_dict["composite_score"]:.3f}')
print(f'✓ Différences incluses: {"differences" in match_dict}')
if "differences" in match_dict:
    print(f'✓ Nombre de différences: {len(match_dict["differences"])}')
    print(f'✓ Première différence: {match_dict["differences"][0]["type"]}')

print('\n' + '='*60)
print('✅ Tous les tests de feedback détaillé réussis!')
print('='*60)

# Nettoyage
import shutil
from pathlib import Path
if Path('test_data').exists():
    shutil.rmtree('test_data')
if Path('test_logs').exists():
    shutil.rmtree('test_logs')
