#!/usr/bin/env python3
"""Check two identified faces and analyze why their pose modes are wrong"""

import sys
import os
import json

# Add project root to path
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from backend.db.models import Face, Person, Photo
from backend.db.session import get_database_url
from src.utils.pose_detection import PoseDetector

def check_two_faces(face_id1: int = None, face_id2: int = None):
    """Check two identified faces and analyze their pose modes"""
    db_url = get_database_url()
    print(f"Connecting to database: {db_url}")
    
    engine = create_engine(db_url)
    Session = sessionmaker(bind=engine)
    session = Session()
    
    try:
        # Get all identified faces
        query = (
            session.query(Face, Person, Photo)
            .join(Person, Face.person_id == Person.id)
            .join(Photo, Face.photo_id == Photo.id)
            .filter(Face.person_id.isnot(None))
            .order_by(Face.id)
        )
        
        if face_id1:
            query = query.filter(Face.id == face_id1)
        elif face_id2:
            query = query.filter(Face.id == face_id2)
        
        faces = query.limit(2).all()
        
        if len(faces) < 2:
            print(f"Found {len(faces)} identified face(s). Need 2 faces to compare.")
            if len(faces) == 0:
                print("No identified faces found.")
                return
            print("\nShowing available identified faces:")
            all_faces = (
                session.query(Face, Person, Photo)
                .join(Person, Face.person_id == Person.id)
                .join(Photo, Face.photo_id == Photo.id)
                .filter(Face.person_id.isnot(None))
                .order_by(Face.id)
                .limit(10)
                .all()
            )
            for face, person, photo in all_faces:
                print(f"  Face ID: {face.id}, Person: {person.first_name} {person.last_name}, Photo: {photo.filename}, Pose: {face.pose_mode}")
            return
        
        print(f"\n{'='*80}")
        print("ANALYZING TWO IDENTIFIED FACES")
        print(f"{'='*80}\n")
        
        for idx, (face, person, photo) in enumerate(faces, 1):
            person_name = f"{person.first_name} {person.last_name}"
            
            print(f"{'='*80}")
            print(f"FACE {idx}: ID {face.id}")
            print(f"{'='*80}")
            print(f"Person: {person_name} (ID: {face.person_id})")
            print(f"Photo: {photo.filename}")
            print(f"Current Pose Mode: {face.pose_mode}")
            print(f"Yaw: {face.yaw_angle:.2f}°" if face.yaw_angle is not None else "Yaw: None")
            print(f"Pitch: {face.pitch_angle:.2f}°" if face.pitch_angle is not None else "Pitch: None")
            print(f"Roll: {face.roll_angle:.2f}°" if face.roll_angle is not None else "Roll: None")
            print(f"Face Width: {face.face_width if hasattr(face, 'face_width') else 'N/A'}")
            print(f"Confidence: {face.face_confidence:.3f}")
            print(f"Quality: {face.quality_score:.3f}")
            print(f"Location: {face.location}")
            
            # Parse landmarks if available
            landmarks = None
            if face.landmarks:
                try:
                    landmarks = json.loads(face.landmarks)
                    print(f"\nLandmarks:")
                    for key, value in landmarks.items():
                        print(f"  {key}: {value}")
                except json.JSONDecodeError:
                    print(f"\nLandmarks: (invalid JSON)")
            
            # Recalculate pose mode using current logic
            print(f"\n{'─'*80}")
            print("RECALCULATING POSE MODE:")
            print(f"{'─'*80}")
            
            # Calculate face width from landmarks if available
            face_width = None
            if landmarks:
                face_width = PoseDetector.calculate_face_width_from_landmarks(landmarks)
                print(f"Calculated face_width from landmarks: {face_width}")
            
            # Recalculate pose mode
            recalculated_pose = PoseDetector.classify_pose_mode(
                face.yaw_angle,
                face.pitch_angle,
                face.roll_angle,
                face_width,
                landmarks
            )
            
            print(f"Recalculated Pose Mode: {recalculated_pose}")
            
            if recalculated_pose != face.pose_mode:
                print(f"⚠️  MISMATCH! Current: '{face.pose_mode}' vs Recalculated: '{recalculated_pose}'")
                
                # Analyze why
                print(f"\nAnalysis:")
                if face.yaw_angle is None:
                    print(f"  - Yaw is None")
                    if landmarks:
                        left_eye = landmarks.get('left_eye')
                        right_eye = landmarks.get('right_eye')
                        nose = landmarks.get('nose')
                        missing = []
                        if not left_eye:
                            missing.append('left_eye')
                        if not right_eye:
                            missing.append('right_eye')
                        if not nose:
                            missing.append('nose')
                        if missing:
                            print(f"  - Missing landmarks: {', '.join(missing)}")
                            print(f"  - Should be classified as profile (missing landmarks)")
                        else:
                            print(f"  - All landmarks present")
                            if face_width:
                                print(f"  - Face width: {face_width}px")
                                if face_width < 25.0:
                                    print(f"  - Face width < 25px, should be profile")
                                else:
                                    print(f"  - Face width >= 25px, should be frontal")
                    else:
                        print(f"  - No landmarks available")
                else:
                    abs_yaw = abs(face.yaw_angle)
                    print(f"  - Yaw angle: {face.yaw_angle:.2f}° (abs: {abs_yaw:.2f}°)")
                    if abs_yaw >= 30.0:
                        expected = "profile_left" if face.yaw_angle < 0 else "profile_right"
                        print(f"  - |yaw| >= 30°, should be '{expected}'")
                    else:
                        print(f"  - |yaw| < 30°, should be 'frontal'")
            else:
                print(f"✓ Pose mode matches recalculated value")
            
            print()
    
    finally:
        session.close()

if __name__ == "__main__":
    face_id1 = None
    face_id2 = None
    
    if len(sys.argv) > 1:
        try:
            face_id1 = int(sys.argv[1])
        except ValueError:
            print(f"Invalid face ID: {sys.argv[1]}")
            sys.exit(1)
    
    if len(sys.argv) > 2:
        try:
            face_id2 = int(sys.argv[2])
        except ValueError:
            print(f"Invalid face ID: {sys.argv[2]}")
            sys.exit(1)
    
    try:
        check_two_faces(face_id1, face_id2)
    except Exception as e:
        print(f"❌ Error: {e}")
        import traceback
        traceback.print_exc()
        sys.exit(1)

