#!/usr/bin/env python3

import time
import logging
import json
from config import *
from prompts import *
from api_client import call_llama_api_with_reprompt, call_llama_api
from file_manager import *
from verification import *
from solver_execution import *
from utils import *

def generate_alternating_optimization_problem_with_verification(client, model, db, table_info):
    """Generate optimization problem using alternating optimization with file storage, verification, solver execution, triple expert data generation, and enhanced analysis with incremental intelligent verification"""
    db_id = db['db_id']
    logging.info(f"    Starting alternating optimization iterative process (max {MAX_ALTERNATING_ITERATIONS} iterations)...")
    
    # Track iteration history with structure
    iteration_history = []
    debug_history = []
    verification_history = []
    
    # Iteration 0: Initial OR Expert Analysis
    logging.info(f"    Iteration 0: Initial OR Expert Analysis...")
    initial_prompt, _ = create_initial_or_expert_prompt(db)
    initial_response = call_llama_api_with_reprompt(
        client, model, initial_prompt, f"OR Expert Iteration 0 - {db_id}",
        "OR Expert Analysis", db_id, 0
    )
    
    debug_history.append({
        'iteration': 0,
        'type': 'or_expert',
        'prompt': initial_prompt,
        'response': json.dumps(initial_response, indent=2) if isinstance(initial_response, dict) else str(initial_response)
    })
    
    current_or_analysis = initial_response
    
    iteration_history.append({
        "iteration": 0,
        "type": "or_expert",
        "analysis": current_or_analysis
    })
    
    time.sleep(1)
    
    # Alternating Iterations: OR Expert <-> Data Engineer with File Storage
    for iteration in range(1, MAX_ALTERNATING_ITERATIONS + 1):
        logging.info(f"    Iteration {iteration}: Data Engineer Implementation...")
        
        # Load current state for data engineer context
        state_info, current_schema_sql, current_data_sql, current_data_dictionary, current_business_configuration_logic = load_current_state(OUTPUT_BASE_DIR, db_id)
        
        # Data Engineer implements current OR analysis
        data_engineer_prompt = create_data_engineer_prompt(
            json.dumps(current_or_analysis, indent=2), 
            db_id, 
            iteration,
            current_schema_sql,
            current_data_dictionary,
            current_business_configuration_logic
        )
        
        data_engineer_response = call_llama_api_with_reprompt(
            client, model, data_engineer_prompt, 
            f"Data Engineer Iteration {iteration} - {db_id}",
            "Data Engineer Implementation", db_id, iteration
        )
        
        debug_history.append({
            'iteration': iteration,
            'type': 'data_engineer',
            'prompt': data_engineer_prompt,
            'response': json.dumps(data_engineer_response, indent=2) if isinstance(data_engineer_response, dict) else str(data_engineer_response)
        })
        
        current_implementation = data_engineer_response
        
        # Generate SQL files and state information (placeholder data)
        schema_sql, data_sql, business_configuration_logic = generate_sql_files_from_implementation(current_implementation, current_schema_sql)
        state_info = create_state_info(current_or_analysis, current_implementation, iteration)
        summary_text = create_summary_text(current_or_analysis, current_implementation, iteration)
        data_dictionary = current_implementation.get("data_dictionary", {})
        
        # Setup iteration directory and save state (with placeholder data)
        iteration_dir = setup_iteration_directory(OUTPUT_BASE_DIR, db_id, iteration)
        save_iteration_state(iteration_dir, schema_sql, data_sql, state_info, summary_text, data_dictionary, business_configuration_logic)
        
        iteration_history.append({
            "iteration": iteration,
            "type": "data_engineer",
            "implementation": current_implementation,
            "state_saved": True
        })
        
        time.sleep(1)
        
        # Check if we should continue iterating
        if iteration >= MAX_ALTERNATING_ITERATIONS:
            logging.info(f"    Reached maximum iterations ({MAX_ALTERNATING_ITERATIONS})")
            break
        
        logging.info(f"    Iteration {iteration}: OR Expert Refinement...")
        
        # Load current state for OR expert
        state_info, schema_sql, data_sql, data_dictionary, business_configuration_logic = load_current_state(OUTPUT_BASE_DIR, db_id)
        
        # OR Expert analyzes current implementation and refines
        iterative_or_prompt = create_iterative_or_expert_prompt(
            db_id, 
            state_info,
            schema_sql,
            data_dictionary,
            business_configuration_logic,
            iteration
        )
        
        iterative_or_response = call_llama_api_with_reprompt(
            client, model, iterative_or_prompt,
            f"OR Expert Iteration {iteration} - {db_id}",
            "OR Expert Refinement", db_id, iteration
        )
        
        debug_history.append({
            'iteration': iteration,
            'type': 'or_expert_refinement',
            'prompt': iterative_or_prompt,
            'response': json.dumps(iterative_or_response, indent=2) if isinstance(iterative_or_response, dict) else str(iterative_or_response)
        })
        
        refined_or_analysis = iterative_or_response
        
        iteration_history.append({
            "iteration": iteration,
            "type": "or_expert_refinement", 
            "analysis": refined_or_analysis
        })
        
        # Simple convergence check
        current_or_analysis = refined_or_analysis
        if simple_convergence_check(iteration, current_or_analysis):
            logging.info(f"    Convergence reached at iteration {iteration}")
            break
        
        time.sleep(1)
    
    # Triple Expert Data Generation
    logging.info(f"    Triple Expert: Generating realistic data...")
    
    # Load final state
    final_state_info, final_schema_sql, _, final_data_dictionary, final_business_configuration_logic = load_current_state(OUTPUT_BASE_DIR, db_id)
    
    # Triple expert generates realistic data
    triple_expert_prompt = create_triple_expert_prompt(
        current_or_analysis,
        current_implementation,
        final_schema_sql,
        final_data_dictionary,
        final_business_configuration_logic,
        db_id
    )
    
    triple_expert_response = call_llama_api_with_reprompt(
        client, model, triple_expert_prompt,
        f"Triple Expert Data Generation - {db_id}",
        "Triple Expert Data Generation", db_id, "final"
    )
    
    debug_history.append({
        'iteration': 'final',
        'type': 'triple_expert',
        'prompt': triple_expert_prompt,
        'response': json.dumps(triple_expert_response, indent=2) if isinstance(triple_expert_response, dict) else str(triple_expert_response)
    })
    
    triple_expert_result = triple_expert_response
    
    # Generate final SQL files with realistic data
    final_iteration = len([h for h in iteration_history if h.get("type") == "data_engineer"])
    final_schema_sql_updated, final_data_sql, updated_business_configuration = generate_sql_files_from_triple_expert(
        triple_expert_result, final_schema_sql, final_business_configuration_logic, final_iteration
    )
    
    # Update final iteration with realistic data
    final_iteration_dir = setup_iteration_directory(OUTPUT_BASE_DIR, db_id, final_iteration)
    save_iteration_state(
        final_iteration_dir, 
        final_schema_sql_updated, 
        final_data_sql, 
        final_state_info, 
        create_summary_text(current_or_analysis, current_implementation, final_iteration) + f"\nTriple Expert Data: {triple_expert_result.get('data_generation_approach', 'Realistic data generated')}", 
        final_data_dictionary,
        updated_business_configuration
    )
    
    time.sleep(1)
    
    # Extract expected mathematical formulation from converged alternating optimization
    expected_alternating_formulation = extract_mathematical_formulation_from_alternating(
        current_or_analysis, current_implementation
    )
    
    logging.info(f"    Expected mathematical formulation extracted from alternating optimization convergence")
    
    # Step 3: Problem Description (Sections 1-3)
    logging.info(f"    Generating problem description (sections 1-3)...")
    
    problem_desc_prompt = create_problem_description_prompt(
        current_or_analysis,
        current_implementation,
        final_schema_sql_updated,
        final_data_sql,
        final_data_dictionary,
        updated_business_configuration,
        expected_alternating_formulation,
        db_id
    )
    
    # Use call_llama_api for markdown output
    problem_description = call_llama_api(
        client, model, problem_desc_prompt,
        f"Problem Description - {db_id}"
    )
    
    debug_history.append({
        'iteration': 'final',
        'type': 'problem_description',
        'prompt': problem_desc_prompt,
        'response': problem_description
    })
    
    time.sleep(1)
    
    # Step 4: Mathematical Solution with INCREMENTAL INTELLIGENT Verification
    logging.info(f"    Generating mathematical solution (section 4) with incremental intelligent verification...")
    
    # Prepare original seed problem for diagnosis
    original_seed_problem = {
        "final_or_analysis": current_or_analysis,
        "final_implementation": current_implementation,
        "schema_sql": final_schema_sql_updated,
        "data_sql": final_data_sql,
        "data_dictionary": final_data_dictionary,
        "business_configuration": updated_business_configuration
    }
    
    # FIXED: Start with empty mathematical solution and let the verification function generate it
    final_problem_description, final_mathematical_solution, final_verification_result, final_consistency_score, passes_verification = verify_with_targeted_incremental_regeneration(
        client, model, original_seed_problem, problem_description, "", expected_alternating_formulation, db_id
    )
    
    # Track verification attempts
    verification_history.append({
        "attempt": 1,
        "consistency_score": final_consistency_score,
        "passes_verification": passes_verification,
        "verification_result": final_verification_result,
        "method": "incremental_intelligent_targeted_regeneration"
    })
    
    # Step 5: Generate and Execute Solver Codes with Templates and Retry Logic
    logging.info(f"    Generating and executing solver codes with templates and retry logic...")
    
    solver_results, solver_codes = generate_and_execute_solver_codes_with_templates(
        client, model, final_problem_description, final_mathematical_solution, db_id
    )
    
    # Add solver results to debug history
    debug_history.append({
        'iteration': 'final',
        'type': 'solver_execution',
        'prompt': 'Generated solver codes with templates and executed them with retry logic',
        'response': json.dumps(solver_results, indent=2)
    })
    
    # Step 6: OR Expert Analysis of Solver Results
    logging.info(f"    OR Expert analyzing solver results...")
    
    solver_analysis_prompt = create_solver_results_analysis_prompt(
        final_mathematical_solution, solver_results, solver_codes, db_id
    )
    
    solver_analysis_response = call_llama_api_with_reprompt(
        client, model, solver_analysis_prompt,
        f"Solver Results Analysis - {db_id}",
        "Solver Results Analysis", db_id, "final"
    )
    
    debug_history.append({
        'iteration': 'final',
        'type': 'solver_analysis',
        'prompt': solver_analysis_prompt,
        'response': json.dumps(solver_analysis_response, indent=2) if isinstance(solver_analysis_response, dict) else str(solver_analysis_response)
    })
    
    solver_analysis_result = solver_analysis_response
    
    time.sleep(1)
    
    # Step 7: Format Complete Documentation with Enhanced Analysis
    logging.info(f"    Formatting complete documentation with enhanced analysis...")
    
    # Create enhanced solver sections markdown with analysis
    enhanced_solver_sections = format_enhanced_solver_results_for_markdown(
        solver_results, solver_codes, solver_analysis_result
    )
    
    # Combine all sections
    complete_documentation = final_problem_description + "\n\n" + final_mathematical_solution + "\n\n" + enhanced_solver_sections
    
    # Also create updated mathematical solution with enhanced solver sections
    mathematical_solution_with_enhanced_solvers = final_mathematical_solution + "\n\n" + enhanced_solver_sections
    
    return (complete_documentation, final_problem_description, mathematical_solution_with_enhanced_solvers,
            current_or_analysis, current_implementation, 
            iteration_history, debug_history, verification_history, 
            expected_alternating_formulation, final_verification_result, final_consistency_score,
            solver_results, solver_codes, triple_expert_result, solver_analysis_result)