from flask import Flask, request, jsonify
from flask_cors import CORS
from werkzeug.utils import secure_filename
import os
from datetime import datetime
import json
from openai import OpenAI
from dotenv import load_dotenv

# Load environment variables from .env file
load_dotenv(os.path.join(os.path.dirname(__file__), '.env'))
# load_dotenv(os.path.join(os.path.dirname(__file__), '..', '.env'))

app = Flask(__name__)

# Enable CORS for all routes
CORS(app, resources={r"/api/*": {"origins": "*"}})

# Initialize OpenAI client
openai_api_key = os.environ.get("OPENAI_API_KEY")
if openai_api_key:
    openai_client = OpenAI(api_key=openai_api_key)
else:
    openai_client = None

# Configuration
UPLOAD_FOLDER = os.path.join(os.path.dirname(__file__), 'uploads')
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif', 'webp'}
MAX_FILE_SIZE = 5 * 1024 * 1024  # 5MB

# Create upload folder if it doesn't exist
os.makedirs(UPLOAD_FOLDER, exist_ok=True)

app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['MAX_CONTENT_LENGTH'] = MAX_FILE_SIZE

def allowed_file(filename):
    """Check if file extension is allowed"""
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

def get_game_suggestions_from_openai(submission_data, picture_url):
    """Get game suggestions from OpenAI based on gathering data"""
    if not openai_client:
        return None
    
    try:
        # Prepare the prompt with user data
        prompt = f'''**TASK:** Act as an expert Game Suggestion Engine. Based on the user's provided context and constraints, generate **exactly 3 unique game recommendations**.

                For each game, you must output the following specific, structured information:
                1.  **Game Title** (Must be engaging)
                2.  **Suitability Justification** (Explain how it matches the culture, goal, and age range.)
                3.  **Required Props/Setup** (List only the materials needed from the 'Properties Available' section or basic items.)
                4.  **Instructions/Gameplay Summary** (Brief, step-by-step summary of how to play.)

                ---
                ### **USER CONTEXT**

                **A. Gathering & Culture**
                -   **Gathering Type:** {submission_data.get('gatheringType', 'N/A')}
                -   **No. of Participants:** {submission_data.get('participants', 'N/A')}
                -   **Age Range:** {submission_data.get('ageRange', 'N/A')}
                -   **Gender Mix:** {submission_data.get('gender', 'N/A')}
                -   **Cultural/Regional Context:** {submission_data.get('culturalContext', 'N/A')}

                **B. Logistics & Constraints**
                -   **Goal/Desired Mood:** {submission_data.get('mood', 'N/A')}
                -   **Time Constraint:** {submission_data.get('timeConstraint', 'N/A')}
                -   **Properties Available:** {submission_data.get('objects', 'N/A')}
                -   **Budget/Material Preference:** Basic household items and minimal props

                **C. Location**
                -   **Location Description:** Medium-sized living room with flexible seating
                -   **Visual Context:** {picture_url}

                ---
                ### **OUTPUT FORMAT**

                Please ensure the final response is easy to read.
                Generate poster-style WhatsApp version.
                Please ensure the final response follows this exact structure for all 3 suggestions:

                **1. [Game Title #1]**
                * **Justification:** [Explanation]
                * **Props:** [List of props]
                * **Instructions:** [Summary of gameplay]

                **2. [Game Title #2]**
                * **Justification:** [Explanation]
                * **Props:** [List of props]
                * **Instructions:** [Summary of gameplay]

                **3. [Game Title #3]**
                * **Justification:** [Explanation]
                * **Props:** [List of props]
                * **Instructions:** [Summary of gameplay]'''
        
        # Call OpenAI API
        response = openai_client.chat.completions.create(
            model="gpt-4o",
            messages=[
                {
                    "role": "system",
                    "content": "You are an expert Game Suggestion Engine. Generate game recommendations based on gathering context and constraints."
                },
                {
                    "role": "user",
                    "content": prompt
                }
            ],
            temperature=0.7,
            max_tokens=2000
        )
        
        return response.choices[0].message.content
    
    except Exception as e:
        print(f"Error calling OpenAI API: {e}")
        return None

def validate_gathering_data(data):
    """Validate form data"""
    errors = {}
    
    # Validate Gathering Type
    gathering_types = [
        'Family', 'Childhood Friends', 'Kitty Parties', 'Religious',
        'Neighborhood', 'Co-workers', 'Classmates', 'Professional Associations',
        'Conventions'
    ]
    
    if not data.get('gatheringType'):
        errors['gatheringType'] = 'Gathering Type is required'
    elif data.get('gatheringType') not in gathering_types:
        errors['gatheringType'] = 'Invalid Gathering Type'
    
    # Validate No. Of Participants
    try:
        participants = int(data.get('participants', 0))
        if participants <= 0:
            errors['participants'] = 'No. Of Participants must be a positive integer'
    except (ValueError, TypeError):
        errors['participants'] = 'No. Of Participants must be a valid integer'
    
    # Validate Gender
    genders = ['Male', 'Female', 'Both']
    if not data.get('gender'):
        errors['gender'] = 'Gender is required'
    elif data.get('gender') not in genders:
        errors['gender'] = 'Invalid Gender value'
    
    # Validate Age Range
    age_ranges = ['18-25', '26-35', '36-45', '46-55', '56-65', '65+', '66+']
    if not data.get('ageRange'):
        errors['ageRange'] = 'Age Range is required'
    elif data.get('ageRange') not in age_ranges:
        errors['ageRange'] = 'Invalid Age Range'
    
    # Validate Cultural Context
    cultural_contexts = [
        'American Indian', 'Asian', 'African American', 'Latin American', 
        'Middle Eastern', 'Pacific Islander', 'White', 'Indian', 'Western',
        'European', 'African', 'Mixed', 'Others'
    ]
    if not data.get('culturalContext'):
        errors['culturalContext'] = 'Cultural / Regional Context is required'
    elif data.get('culturalContext') not in cultural_contexts:
        errors['culturalContext'] = 'Invalid Cultural / Regional Context'
        # errors['d'] = data.get('culturalContext')
    
    # Picture is validated separately (file upload)
    
    # Objects we've is optional, so no validation needed
    
    return errors

@app.route("/info")
def info():
    return {
        "python_version": platform.python_version(),
        "flask_version": flask.__version__,
        "os": platform.system()
    }

# Optional: root test
@app.route("/")
def home():
    return "GameGenie API is running"

@app.route('/api/gathering', methods=['POST'])
def submit_gathering():
    """Handle gathering form submission"""
    try:
        # Check if picture file is present
        if 'picture' not in request.files:
            return jsonify({
                'success': False,
                'message': 'Picture file is required',
                'errors': {'picture': 'Picture file is required'}
            }), 400
        
        file = request.files['picture']
        
        if file.filename == '':
            return jsonify({
                'success': False,
                'message': 'No file selected',
                'errors': {'picture': 'No file selected'}
            }), 400
        
        if not allowed_file(file.filename):
            return jsonify({
                'success': False,
                'message': 'Invalid file type. Only images are allowed',
                'errors': {'picture': 'Only image files are allowed (JPG, PNG, GIF, WebP)'}
            }), 400
        
        if file.content_length > MAX_FILE_SIZE:
            return jsonify({
                'success': False,
                'message': 'File size exceeds maximum limit',
                'errors': {'picture': 'File size must be less than 5MB'}
            }), 400
        
        # Validate form data
        data = request.form.to_dict()
        errors = validate_gathering_data(data)
        
        if errors:
            return jsonify({
                'success': False,
                'message': 'Validation failed',
                'errors': errors
            }), 400
        
        # Save uploaded file
        filename = secure_filename(file.filename)
        timestamp = datetime.now().strftime('%Y%m%d_%H%M%S_')
        filename = timestamp + filename
        filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename)
        file.save(filepath)
        
        # Prepare response data
        submission_data = {
            'gatheringType': data.get('gatheringType'),
            'participants': int(data.get('participants')),
            'gender': data.get('gender'),
            'ageRange': data.get('ageRange'),
            'culturalContext': data.get('culturalContext'),
            'picture': filename,
            'pictureUrl': f'/api/uploads/{filename}',
            'objects': data.get('objects', ''),
            'submittedAt': datetime.now().isoformat()
        }
        
        # Get game suggestions from OpenAI
        print("Fetching game suggestions from OpenAI...")
        game_suggestions = get_game_suggestions_from_openai(
            submission_data,
            f'http://localhost/uploads/{filename}'
        )
        
        
        temp_file = os.path.join(os.path.dirname(__file__), 'temp.txt')
        try:
            with open(temp_file, 'w') as f:
                json.dump(game_suggestions, f, indent=4)
        except IOError as e:
            print(f"Warning: Could not save submission to file: {e}")

        print(game_suggestions)
        
        if game_suggestions:
            submission_data['gameSuggestions'] = game_suggestions
        else:
            submission_data['gameSuggestions'] = None
        
        # Save submission to a JSON file for record keeping
        submissions_file = os.path.join(os.path.dirname(__file__), 'submissions.json')
        submissions = []
        
        if os.path.exists(submissions_file):
            try:
                with open(submissions_file, 'r') as f:
                    submissions = json.load(f)
            except (json.JSONDecodeError, IOError):
                submissions = []
        
        submissions.append(submission_data)
        
        try:
            with open(submissions_file, 'w') as f:
                json.dump(submissions, f, indent=4)
        except IOError as e:
            print(f"Warning: Could not save submission to file: {e}")
        
        return jsonify({
            'success': True,
            'message': 'Data submitted successfully',
            'data': submission_data,
            'kld': 'deepak'
        }), 200
    
    except Exception as e:
        return jsonify({
            'success': False,
            'message': 'An error occurred while processing your request',
            'error': str(e)
        }), 500

@app.route('/api/submissions', methods=['GET'])
def get_submissions():
    """Get all submissions"""
    try:
        submissions_file = os.path.join(os.path.dirname(__file__), 'submissions.json')
        
        if not os.path.exists(submissions_file):
            return jsonify({
                'success': True,
                'data': [],
                'message': 'No submissions yet'
            }), 200
        
        with open(submissions_file, 'r') as f:
            submissions = json.load(f)
        
        return jsonify({
            'success': True,
            'data': submissions,
            'total': len(submissions)
        }), 200
    
    except Exception as e:
        return jsonify({
            'success': False,
            'message': 'An error occurred while retrieving submissions',
            'error': str(e)
        }), 500

@app.route('/api/uploads/<filename>', methods=['GET'])
def download_file(filename):
    """Serve uploaded files"""
    try:
        filepath = os.path.join(app.config['UPLOAD_FOLDER'], secure_filename(filename))
        if os.path.exists(filepath):
            from flask import send_file
            return send_file(filepath)
        else:
            return jsonify({
                'success': False,
                'message': 'File not found'
            }), 404
    except Exception as e:
        return jsonify({
            'success': False,
            'message': 'An error occurred while retrieving the file',
            'error': str(e)
        }), 500

@app.route('/api/health', methods=['GET'])
def health_check():
    """Health check endpoint"""
    return jsonify({
        'success': True,
        'message': 'API is running',
        'status': 'healthy'
    }), 200

if __name__ == '__main__':
    app.run(debug=True, host='localhost', port=3000)
