#!/usr/bin/env python3
"""
bridge_respond.py - AIVA Bridge Response Tool for Claude Code
Posts responses and status updates back to the command queue.
"""

import os
import sys
import argparse
import logging
import datetime
from typing import Optional, Dict, Any
from dataclasses import dataclass

import psycopg2
from psycopg2 import sql
from psycopg2.extras import RealDictCursor


# ============================================================================
# CONFIGURATION
# ============================================================================

from psycopg2.extras import RealDictCursor

from core.secrets_loader import get_postgres_config


# ============================================================================
# CONFIGURATION
# ============================================================================

@dataclass(frozen=True)
class Config:
    """Immutable configuration container."""
    schema: str = "genesis_bridge"



# ============================================================================
# DATABASE MANAGER
# ============================================================================

class ResponseManager:
    """
    Manages database operations for posting responses.
    """
    
    def __init__(self, config: Config):
        self.config = config
        self.logger = self._setup_logging()
    
    def _setup_logging(self) -> logging.Logger:
        """Configure logging."""
        logger = logging.getLogger("bridge_respond")
        logger.setLevel(logging.INFO)
        
        if not logger.handlers:
            handler = logging.StreamHandler(sys.stderr)
            handler.setFormatter(logging.Formatter('%(levelname)s: %(message)s'))
            logger.addHandler(handler)
        
        return logger
    
    @contextmanager
    def get_connection(self):
        """Context manager for database connections."""
        conn = None
        try:
            pg_config = get_postgres_config()
            if not pg_config.is_configured:
                raise psycopg2.Error("PostgreSQL is not configured.")
            conn = psycopg2.connect(pg_config.to_dsn())
            yield conn
        except psycopg2.Error as e:
            self.logger.error(f"Database error: {e}")
            raise
        finally:
            if conn:
                conn.close()
    
    def complete_directive(
        self, 
        directive_id: int, 
        status: str, 
        message: str
    ) -> bool:
        """
        Mark a directive as completed and post response.
        """
        try:
            with self.get_connection() as conn:
                with conn.cursor() as cursor:
                    # Update original directive
                    update_query = sql.SQL("""
                        UPDATE {}.command_queue
                        SET status = %s, 
                            updated_at = NOW(),
                            completion_message = %s,
                            completed_at = NOW()
                        WHERE id = %s
                    """).format(sql.Identifier(self.config.schema))
                    
                    cursor.execute(update_query, [status, message, directive_id])
                    
                    # Insert response record
                    insert_query = sql.SQL("""
                        INSERT INTO {}.command_queue 
                        (direction, status, target, command_type, payload, source_id, priority, created_at)
                        VALUES ('outbound', 'pending', 'aiva', 'response', %s, %s, 5, NOW())
                    """).format(sql.Identifier(self.config.schema))
                    
                    payload = {
                        "original_directive_id": directive_id,
                        "status": status,
                        "message": message,
                        "timestamp": datetime.datetime.now().isoformat()
                    }
                    
                    cursor.execute(insert_query, [psycopg2.extras.Json(payload), directive_id])
                    
                    conn.commit()
                    
                    print(f"✓ Directive {directive_id} marked as '{status}'")
                    print(f"  Message: {message}")
                    return True
                    
        except Exception as e:
            self.logger.error(f"Failed to complete directive {directive_id}: {e}")
            print(f"✗ Error: {e}", file=sys.stderr)
            return False
    
    def post_status_update(
        self, 
        message: str, 
        directive_id: Optional[int] = None,
        completion_percentage: Optional[int] = None
    ) -> bool:
        """
        Post a status update to the queue.
        """
        try:
            with self.get_connection() as conn:
                with conn.cursor() as cursor:
                    query = sql.SQL("""
                        INSERT INTO {}.command_queue 
                        (direction, status, target, command_type, payload, source_id, priority, created_at)
                        VALUES ('outbound', 'pending', 'aiva', 'status_update', %s, %s, 3, NOW())
                    """).format(sql.Identifier(self.config.schema))
                    
                    payload = {
                        "message": message,
                        "completion_percentage": completion_percentage,
                        "timestamp": datetime.datetime.now().isoformat(),
                        "claude_session": os.getenv("CLAUDE_SESSION_ID", "unknown")
                    }
                    
                    cursor.execute(query, [
                        psycopg2.extras.Json(payload), 
                        directive_id
                    ])
                    
                    conn.commit()
                    
                    target_info = f" for directive {directive_id}" if directive_id else ""
                    print(f"✓ Status update posted{target_info}: {message}")
                    return True
                    
        except Exception as e:
            self.logger.error(f"Failed to post status update: {e}")
            print(f"✗ Error: {e}", file=sys.stderr)
            return False


# ============================================================================
# MAIN ENTRY POINT
# ============================================================================

def main():
    parser = argparse.ArgumentParser(
        description="AIVA Bridge Response Tool - Post responses back to command queue"
    )
    
    parser.add_argument(
        "--directive-id", 
        type=int, 
        help="ID of the directive being responded to"
    )
    parser.add_argument(
        "--status", 
        choices=['completed', 'failed', 'in_progress', 'blocked'],
        help="Status to set for the directive"
    )
    parser.add_argument(
        "--message", 
        type=str, 
        help="Response message or completion notes"
    )
    parser.add_argument(
        "--status-update", 
        type=str, 
        help="Post a status update message (does not complete directive)"
    )
    parser.add_argument(
        "--completion-percentage", 
        type=int, 
        help="Completion percentage for status update (0-100)"
    )
    
    args = parser.parse_args()
    
    # Validation
    if args.status_update:
        # Status update mode
        config = Config()
        manager = ResponseManager(config)
        success = manager.post_status_update(
            args.status_update,
            args.directive_id,
            args.completion_percentage
        )
        sys.exit(0 if success else 1)
    
    elif args.directive_id and args.status and args.message:
        # Completion mode
        config = Config()
        manager = ResponseManager(config)
        success = manager.complete_directive(
            args.directive_id,
            args.status,
            args.message
        )
        sys.exit(0 if success else 1)
    
    else:
        parser.print_help()
        print("\nError: Either --status-update or (--directive-id, --status, --message) required", file=sys.stderr)
        sys.exit(1)


if __name__ == "__main__":
    main()