#!/usr/bin/env python3
"""
Simple API server for Criteria Manager UI
Allows automated updates without manual code editing
"""
from flask import Flask, request, jsonify
from flask_cors import CORS
import subprocess
import json
import os
import uuid
import time
from datetime import datetime

app = Flask(__name__)
CORS(app)  # Allow requests from criteria_manager.html

# Store active jobs in memory
active_jobs = {}

@app.route('/api/update-weights', methods=['POST'])
def update_weights():
    """Update criteria weights in Python files"""
    try:
        config = request.json

        # Save config to temp file
        config_file = '/tmp/criteria_config.json'
        with open(config_file, 'w') as f:
            json.dump(config, f)

        # Run update script
        result = subprocess.run(
            ['python3', 'update_criteria_weights.py', config_file],
            capture_output=True,
            text=True,
            cwd=os.path.dirname(__file__)
        )

        response = json.loads(result.stdout) if result.stdout else {'success': False, 'message': 'No output'}

        return jsonify(response)

    except Exception as e:
        return jsonify({'success': False, 'message': str(e)}), 500


@app.route('/api/update-api-key', methods=['POST'])
def update_api_key():
    """Update OpenAI API key in .env file"""
    try:
        data = request.json
        api_key = data.get('api_key', '').strip()

        if not api_key:
            return jsonify({'success': False, 'message': 'API key is required'}), 400

        # Update .env file
        env_path = os.path.join(os.path.dirname(__file__), '.env')

        # Read existing .env or create new
        env_lines = []
        if os.path.exists(env_path):
            with open(env_path, 'r') as f:
                env_lines = f.readlines()

        # Update or add OPENAI_API_KEY
        key_found = False
        new_lines = []
        for line in env_lines:
            if line.startswith('OPENAI_API_KEY='):
                new_lines.append(f'OPENAI_API_KEY={api_key}\n')
                key_found = True
            else:
                new_lines.append(line)

        if not key_found:
            new_lines.append(f'OPENAI_API_KEY={api_key}\n')

        # Write back
        with open(env_path, 'w') as f:
            f.writelines(new_lines)

        return jsonify({
            'success': True,
            'message': 'API key updated successfully in .env file'
        })

    except Exception as e:
        return jsonify({'success': False, 'message': str(e)}), 500


@app.route('/api/run-evaluation', methods=['POST'])
def run_evaluation():
    """Run custom criteria evaluation"""
    try:
        data = request.json
        criteria_type = data.get('type', 'custom')  # 'custom' or 'gpt'

        if criteria_type == 'custom':
            # Run custom criteria evaluation
            process = subprocess.Popen(
                ['python3', 'custom_criteria.py'],
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                cwd=os.path.dirname(__file__)
            )
            # Don't wait - return immediately
            return jsonify({
                'success': True,
                'message': 'Custom criteria evaluation started in background',
                'note': 'This will take 3-5 minutes. Check terminal for progress.'
            })

        elif criteria_type == 'gpt':
            # Run GPT analysis
            process = subprocess.Popen(
                ['python3', 'analyze_from_urls.py'],
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                cwd=os.path.dirname(__file__)
            )
            return jsonify({
                'success': True,
                'message': 'GPT analysis started in background',
                'note': 'This will cost ~$3-5 and take 5-10 minutes. Check terminal for progress.'
            })

        else:
            return jsonify({'success': False, 'message': 'Invalid evaluation type'}), 400

    except Exception as e:
        return jsonify({'success': False, 'message': str(e)}), 500


@app.route('/api/get-api-key', methods=['GET'])
def get_api_key():
    """Get masked API key for display"""
    try:
        env_path = os.path.join(os.path.dirname(__file__), '.env')

        if not os.path.exists(env_path):
            return jsonify({'success': True, 'has_key': False, 'key': ''})

        with open(env_path, 'r') as f:
            for line in f:
                if line.startswith('OPENAI_API_KEY='):
                    key = line.split('=', 1)[1].strip()
                    if key:
                        # Mask the key (show first 7 and last 4 chars)
                        masked = f"{key[:7]}...{key[-4:]}" if len(key) > 15 else "sk-..."
                        return jsonify({'success': True, 'has_key': True, 'key': masked})

        return jsonify({'success': True, 'has_key': False, 'key': ''})

    except Exception as e:
        return jsonify({'success': False, 'message': str(e)}), 500


@app.route('/api/update-prompt', methods=['POST'])
def update_prompt():
    """Update GPT criteria prompt in prompt.txt file"""
    try:
        data = request.json
        prompt_content = data.get('prompt', '').strip()

        if not prompt_content:
            return jsonify({'success': False, 'message': 'Prompt content is required'}), 400

        # Update prompt.txt file
        prompt_path = os.path.join(os.path.dirname(__file__), 'prompt.txt')

        # Create backup of existing prompt
        if os.path.exists(prompt_path):
            backup_path = prompt_path + '.backup'
            with open(prompt_path, 'r', encoding='utf-8') as f:
                backup_content = f.read()
            with open(backup_path, 'w', encoding='utf-8') as f:
                f.write(backup_content)

        # Write new prompt
        with open(prompt_path, 'w', encoding='utf-8') as f:
            f.write(prompt_content)

        return jsonify({
            'success': True,
            'message': 'GPT criteria prompt updated successfully in prompt.txt',
            'backup_created': True
        })

    except Exception as e:
        return jsonify({'success': False, 'message': str(e)}), 500


@app.route('/api/scrape-favorites', methods=['POST'])
def scrape_favorites():
    """Trigger favorites scraping"""
    try:
        data = request.json
        full_pipeline = data.get('full_pipeline', True)  # Run full pipeline by default

        # Generate unique job ID
        job_id = str(uuid.uuid4())[:8]

        script = 'auto_scrape_favorites.py'
        command = 'now' if full_pipeline else 'scrape-only'

        # Create progress file
        progress_file = f'/tmp/farmmatch_progress_{job_id}.json'
        initial_progress = {
            'job_id': job_id,
            'status': 'running',
            'progress': 0,
            'current_step': 'Starting...',
            'total_steps': 8 if full_pipeline else 1,  # Updated to 8 steps
            'started_at': datetime.now().isoformat(),
            'full_pipeline': full_pipeline
        }
        with open(progress_file, 'w') as f:
            json.dump(initial_progress, f)

        # Create log file for this job
        log_file = f'/tmp/farmmatch_job_{job_id}.log'
        log_handle = open(log_file, 'w')

        # Run in background with logging
        process = subprocess.Popen(
            ['python3', script, command],
            stdout=log_handle,
            stderr=subprocess.STDOUT,  # Redirect stderr to stdout for combined log
            cwd=os.path.dirname(__file__),
            env={**os.environ, 'FARMMATCH_JOB_ID': job_id}
        )

        # Store job info
        active_jobs[job_id] = {
            'process': process,
            'type': 'scrape',
            'full_pipeline': full_pipeline,
            'started_at': datetime.now().isoformat(),
            'log_file': log_file
        }

        return jsonify({
            'success': True,
            'job_id': job_id,
            'message': 'Favorites scraping started in background',
            'full_pipeline': full_pipeline,
            'estimated_time': '20-30 minutes' if full_pipeline else '5-10 minutes',
            'log_file': log_file
        })

    except Exception as e:
        return jsonify({'success': False, 'message': str(e)}), 500


@app.route('/api/check-availability', methods=['POST'])
def check_availability():
    """Trigger availability check"""
    try:
        # Generate unique job ID
        job_id = str(uuid.uuid4())[:8]

        # Create progress file
        progress_file = f'/tmp/farmmatch_progress_{job_id}.json'
        initial_progress = {
            'job_id': job_id,
            'status': 'running',
            'progress': 0,
            'current_step': 'Starting availability check...',
            'total_steps': 1,
            'started_at': datetime.now().isoformat()
        }
        with open(progress_file, 'w') as f:
            json.dump(initial_progress, f)

        # Create log file for this job
        log_file = f'/tmp/farmmatch_job_{job_id}.log'
        log_handle = open(log_file, 'w')

        # Run availability check in background with logging
        process = subprocess.Popen(
            ['python3', 'check_availability.py'],
            stdout=log_handle,
            stderr=subprocess.STDOUT,  # Redirect stderr to stdout for combined log
            cwd=os.path.dirname(__file__),
            env={**os.environ, 'FARMMATCH_JOB_ID': job_id}
        )

        # Store job info
        active_jobs[job_id] = {
            'process': process,
            'type': 'availability',
            'started_at': datetime.now().isoformat(),
            'log_file': log_file
        }

        return jsonify({
            'success': True,
            'job_id': job_id,
            'message': 'Availability check started in background',
            'estimated_time': '5-10 minutes'
        })

    except Exception as e:
        return jsonify({'success': False, 'message': str(e)}), 500


@app.route('/api/unfavorite-property', methods=['POST'])
def unfavorite_property():
    """Unfavorite a property on Properstar"""
    try:
        data = request.json
        property_url = data.get('url')

        if not property_url:
            return jsonify({'success': False, 'message': 'No URL provided'}), 400

        # Generate unique job ID
        job_id = str(uuid.uuid4())[:8]

        # Create log file for this job
        log_file = f'/tmp/farmmatch_unfavorite_{job_id}.log'
        log_handle = open(log_file, 'w')

        # Run unfavorite script in background with logging
        process = subprocess.Popen(
            ['python3', 'unfavorite_property.py', property_url],
            stdout=log_handle,
            stderr=subprocess.STDOUT,  # Redirect stderr to stdout for combined log
            cwd=os.path.dirname(__file__)
        )

        # Store job info
        active_jobs[job_id] = {
            'process': process,
            'type': 'unfavorite',
            'property_url': property_url,
            'started_at': datetime.now().isoformat(),
            'log_file': log_file
        }

        return jsonify({
            'success': True,
            'job_id': job_id,
            'message': 'Unfavoriting property...',
            'property_url': property_url,
            'log_file': log_file
        })

    except Exception as e:
        return jsonify({'success': False, 'message': str(e)}), 500


@app.route('/api/job-status/<job_id>', methods=['GET'])
def job_status(job_id):
    """Get status of a running job"""
    try:
        progress_file = f'/tmp/farmmatch_progress_{job_id}.json'

        # Check if progress file exists
        if not os.path.exists(progress_file):
            # Check if job is in active_jobs
            if job_id in active_jobs:
                job_info = active_jobs[job_id]
                process = job_info['process']

                # Check if process is still running
                if process.poll() is None:
                    return jsonify({
                        'success': True,
                        'status': 'running',
                        'progress': 0,
                        'current_step': 'Initializing...',
                        'message': 'Job is starting'
                    })
                else:
                    # Process finished but no progress file - likely error
                    return jsonify({
                        'success': False,
                        'status': 'failed',
                        'message': 'Job failed to start or crashed'
                    })
            else:
                return jsonify({
                    'success': False,
                    'message': 'Job not found'
                }), 404

        # Read progress file
        with open(progress_file, 'r') as f:
            progress = json.load(f)

        return jsonify({
            'success': True,
            **progress
        })

    except Exception as e:
        return jsonify({'success': False, 'message': str(e)}), 500


@app.route('/api/run-analysis', methods=['POST'])
def run_analysis():
    """Run GPT analysis on unanalyzed properties (Analyze Only button)"""
    try:
        # Generate unique job ID
        job_id = str(uuid.uuid4())[:8]

        # Create progress file
        progress_file = f'/tmp/farmmatch_progress_{job_id}.json'
        initial_progress = {
            'job_id': job_id,
            'status': 'running',
            'progress': 0,
            'current_step': 'Starting GPT analysis...',
            'total_steps': 1,
            'started_at': datetime.now().isoformat()
        }
        with open(progress_file, 'w') as f:
            json.dump(initial_progress, f)

        # Create log file for this job
        log_file = f'/tmp/farmmatch_job_{job_id}.log'
        log_handle = open(log_file, 'w')

        # Run analyze_from_urls_optimized.py in background with logging
        # Always use optimized prompt (30% token savings) with caching enabled
        process = subprocess.Popen(
            ['python3', 'analyze_from_urls_optimized.py'],
            stdout=log_handle,
            stderr=subprocess.STDOUT,  # Redirect stderr to stdout for combined log
            cwd=os.path.dirname(__file__),
            env={**os.environ, 'FARMMATCH_JOB_ID': job_id, 'USE_CACHE': 'y', 'USE_OPTIMIZED_PROMPT': 'y'}
        )

        # Store job info
        active_jobs[job_id] = {
            'process': process,
            'type': 'analysis',
            'started_at': datetime.now().isoformat(),
            'log_file': log_file
        }

        return jsonify({
            'success': True,
            'job_id': job_id,
            'message': 'GPT analysis started in background',
            'estimated_time': '2-5 minutes',
            'estimated_cost': '$0.02-0.05'
        })

    except Exception as e:
        return jsonify({'success': False, 'message': str(e)}), 500


@app.route('/api/validate-session', methods=['GET'])
def validate_session_endpoint():
    """Validate if Properstar login session is still valid"""
    try:
        result = subprocess.run(
            ['python3', 'check_session_simple.py'],
            capture_output=True,
            text=True,
            cwd=os.path.dirname(__file__),
            timeout=60
        )

        # Parse JSON output from the script
        output_lines = result.stdout.strip().split('\n')
        json_output = None

        # Find the JSON output (after "JSON Output:")
        for i, line in enumerate(output_lines):
            if 'JSON Output:' in line and i + 1 < len(output_lines):
                try:
                    json_text = '\n'.join(output_lines[i+1:])
                    json_output = json.loads(json_text)
                    break
                except:
                    pass

        if not json_output:
            # Fallback: try to find JSON in output
            for line in output_lines:
                if line.strip().startswith('{'):
                    try:
                        json_output = json.loads(line)
                        break
                    except:
                        pass

        if not json_output:
            json_output = {
                'valid': False,
                'error': 'Could not parse validation result',
                'raw_output': result.stdout
            }

        return jsonify({
            'success': True,
            'session': json_output
        })

    except subprocess.TimeoutExpired:
        return jsonify({
            'success': False,
            'message': 'Session validation timed out'
        }), 500
    except Exception as e:
        return jsonify({
            'success': False,
            'message': str(e)
        }), 500


@app.route('/api/invalidate-session', methods=['POST'])
def invalidate_session_endpoint():
    """Invalidate current session (delete auth.json)"""
    try:
        result = subprocess.run(
            ['python3', 'check_session_simple.py', 'invalidate'],
            capture_output=True,
            text=True,
            cwd=os.path.dirname(__file__),
            timeout=10
        )

        output = json.loads(result.stdout) if result.stdout else {}

        return jsonify({
            'success': output.get('success', False),
            'message': output.get('message', 'Session invalidated'),
            'backup_file': output.get('backup_file')
        })

    except Exception as e:
        return jsonify({
            'success': False,
            'message': str(e)
        }), 500


@app.route('/api/run-structured-analysis', methods=['POST'])
def run_structured_analysis():
    """Run GPT analysis with structured outputs (high quality, guaranteed valid JSON)"""
    try:
        job_id = str(uuid.uuid4())[:8]

        # Create log file
        log_file = f'/tmp/farmmatch_job_{job_id}.log'

        # Set environment variable for progress tracking
        env = os.environ.copy()
        env['FARMMATCH_JOB_ID'] = job_id

        # Run structured analysis
        process = subprocess.Popen(
            ['python3', 'analyze_with_structured_output.py'],
            stdout=open(log_file, 'w'),
            stderr=subprocess.STDOUT,
            cwd=os.path.dirname(__file__),
            env=env
        )

        active_jobs[job_id] = {
            'process': process,
            'started_at': datetime.now().isoformat(),
            'log_file': log_file,
            'type': 'structured_analysis'
        }

        return jsonify({
            'success': True,
            'job_id': job_id,
            'message': 'Structured analysis started',
            'features': [
                '100% valid JSON (guaranteed)',
                'Detailed reasoning for each score',
                '60-70% cost savings vs legacy',
                'Farming-specific features'
            ],
            'estimated_time': '5-15 minutes'
        })

    except Exception as e:
        return jsonify({'success': False, 'message': str(e)}), 500


@app.route('/api/batch-create', methods=['POST'])
def batch_create():
    """Create batch API input for overnight processing (50% cost savings)"""
    try:
        job_id = str(uuid.uuid4())[:8]
        log_file = f'/tmp/farmmatch_job_{job_id}.log'

        process = subprocess.Popen(
            ['python3', 'batch_gpt_analysis.py', 'create'],
            stdout=open(log_file, 'w'),
            stderr=subprocess.STDOUT,
            cwd=os.path.dirname(__file__)
        )

        active_jobs[job_id] = {
            'process': process,
            'started_at': datetime.now().isoformat(),
            'log_file': log_file,
            'type': 'batch_create'
        }

        return jsonify({
            'success': True,
            'job_id': job_id,
            'message': 'Creating batch input file...',
            'next_step': 'Use /api/batch-submit after this completes',
            'estimated_time': '5-10 minutes'
        })

    except Exception as e:
        return jsonify({'success': False, 'message': str(e)}), 500


@app.route('/api/batch-submit', methods=['POST'])
def batch_submit():
    """Submit batch to OpenAI for overnight processing"""
    try:
        result = subprocess.run(
            ['python3', 'batch_gpt_analysis.py', 'submit'],
            capture_output=True,
            text=True,
            cwd=os.path.dirname(__file__),
            timeout=120
        )

        if result.returncode == 0:
            return jsonify({
                'success': True,
                'message': 'Batch submitted to OpenAI',
                'next_step': 'Check status with /api/batch-status',
                'processing_time': '1-24 hours',
                'cost_savings': '50% vs real-time API'
            })
        else:
            return jsonify({
                'success': False,
                'message': f'Batch submission failed: {result.stderr}'
            }), 500

    except Exception as e:
        return jsonify({'success': False, 'message': str(e)}), 500


@app.route('/api/batch-status', methods=['GET'])
def batch_status():
    """Check batch processing status"""
    try:
        result = subprocess.run(
            ['python3', 'batch_gpt_analysis.py', 'status'],
            capture_output=True,
            text=True,
            cwd=os.path.dirname(__file__),
            timeout=30
        )

        # Parse output to extract status
        output = result.stdout

        return jsonify({
            'success': True,
            'raw_output': output,
            'next_step': 'If completed, use /api/batch-retrieve'
        })

    except Exception as e:
        return jsonify({'success': False, 'message': str(e)}), 500


@app.route('/api/batch-retrieve', methods=['POST'])
def batch_retrieve():
    """Retrieve completed batch results"""
    try:
        job_id = str(uuid.uuid4())[:8]
        log_file = f'/tmp/farmmatch_job_{job_id}.log'

        process = subprocess.Popen(
            ['python3', 'batch_gpt_analysis.py', 'retrieve'],
            stdout=open(log_file, 'w'),
            stderr=subprocess.STDOUT,
            cwd=os.path.dirname(__file__)
        )

        active_jobs[job_id] = {
            'process': process,
            'started_at': datetime.now().isoformat(),
            'log_file': log_file,
            'type': 'batch_retrieve'
        }

        return jsonify({
            'success': True,
            'job_id': job_id,
            'message': 'Retrieving batch results...',
            'next_step': 'Run parse_criteria.py to combine scores'
        })

    except Exception as e:
        return jsonify({'success': False, 'message': str(e)}), 500


@app.route('/api/system-status', methods=['GET'])
def system_status():
    """Get system health status"""
    try:
        # Check if enriched_data.json exists and get last modified time
        data_file = os.path.join(os.path.dirname(__file__), 'enriched_data.json')
        data_freshness = None
        data_age_hours = None

        if os.path.exists(data_file):
            last_modified = os.path.getmtime(data_file)
            data_age_seconds = time.time() - last_modified
            data_age_hours = data_age_seconds / 3600
            data_freshness = datetime.fromtimestamp(last_modified).isoformat()

        # Check auth.json (login session)
        auth_file = os.path.join(os.path.dirname(__file__), 'auth.json')
        auth_status = {
            'logged_in': False,
            'session_age_days': None,
            'session_created': None
        }

        if os.path.exists(auth_file):
            auth_modified = os.path.getmtime(auth_file)
            auth_age_seconds = time.time() - auth_modified
            auth_age_days = auth_age_seconds / 86400  # Convert to days
            auth_status = {
                'logged_in': True,
                'session_age_days': auth_age_days,
                'session_created': datetime.fromtimestamp(auth_modified).isoformat()
            }

        # Count active jobs
        running_jobs = len([j for j in active_jobs.values() if j['process'].poll() is None])

        # Check for new quality features
        quality_features = {
            'structured_extraction': os.path.exists(os.path.join(os.path.dirname(__file__), 'extract_property_facts.py')),
            'structured_outputs': os.path.exists(os.path.join(os.path.dirname(__file__), 'analyze_with_structured_output.py')),
            'batch_api': os.path.exists(os.path.join(os.path.dirname(__file__), 'batch_gpt_analysis.py')),
            'csv_sync': os.path.exists(os.path.join(os.path.dirname(__file__), 'sync_csv_to_enriched.py'))
        }

        return jsonify({
            'success': True,
            'api_server': 'running',
            'data_freshness': data_freshness,
            'data_age_hours': data_age_hours,
            'active_jobs': running_jobs,
            'auth_status': auth_status,
            'quality_features': quality_features,
            'features_enabled': all(quality_features.values()),
            'timestamp': datetime.now().isoformat()
        })

    except Exception as e:
        return jsonify({'success': False, 'message': str(e)}), 500


if __name__ == '__main__':
    print("🚀 Starting Criteria API Server...")
    print("   URL: http://localhost:5002")
    print("   Endpoints:")
    print("     POST /api/update-weights - Update criteria weights")
    print("     POST /api/update-api-key - Update OpenAI API key")
    print("     POST /api/run-evaluation - Run evaluation")
    print("     GET  /api/get-api-key - Get masked API key")
    print("     POST /api/scrape-favorites - Scrape favorites from Properstar")
    print("     POST /api/check-availability - Check property availability")
    print("     POST /api/run-analysis - Run GPT analysis on unanalyzed properties")
    print("     GET  /api/job-status/<job_id> - Get job progress")
    print("     GET  /api/system-status - Get system health")
    print()
    print("   🔐 Session Management:")
    print("     GET  /api/validate-session - Check if Properstar session is valid")
    print("     POST /api/invalidate-session - Force session refresh (removes auth.json)")
    print()
    print("   🌟 Quality Analysis Endpoints:")
    print("     POST /api/run-structured-analysis - High-quality structured output analysis")
    print("     POST /api/batch-create - Create batch input (50% cost savings)")
    print("     POST /api/batch-submit - Submit batch to OpenAI")
    print("     GET  /api/batch-status - Check batch processing status")
    print("     POST /api/batch-retrieve - Retrieve completed batch results")
    print()
    app.run(host='0.0.0.0', port=5002, debug=False)
