import os, time, datetime
from concurrent.futures import ThreadPoolExecutor
import openai
from openai import OpenAI
from app.services.complete import Complete
from flask import request, jsonify, Response, stream_with_context
from firebase_admin import storage

openai.api_key = os.environ.get("OPENAI_API_KEY")
cmp = Complete()

def generate_prob(org_num, prompt, txt, index_n):
    try:
        #model = 'gpt-4o-mini' if index <= 11 else 'gpt-4o'
        model = 'gpt-4o'
        client = OpenAI(
            organization=os.environ[f'OPENAI_ORG{org_num}'],
        )
        response = client.chat.completions.create(
            model=model,
            messages=[
                {
                    'role': 'system',
                    'content': "You are tasked with creating an English exam problem or problem group suitable for a Korean high school English class or Suneung.\n\
                    Since this is an English exam for Korean students, the instructions should be in Korean, and the passages should be in English.\n\
                    Provide the response in text without any formatting. Only include the requested information without additional commentary. Do not add bold or italic formatting, but retain any underlining denoted by '___'.\n\
                    Use Korean 반말(authoritative and direct language) in exam questions and authoritative explanations, rather than 경어(polite language).\n"
                },
                {
                    'role': 'user',
                    'content': f'''{prompt}\n{txt}'''
                },
            ],
            max_tokens=4096,
        )
        return response.choices[0].message.content, index_n
    except Exception as e:
        return str(e)

def prob_i(n): #problem_index
    index = [
        '18', '19', '20', '21', '22', '23', '24', '25', '26', '27',
        '28', '29', '30', '31', '32', '33', '34', '35', '36', '37',
        '38', '39', '40', '41_42', '43_45'
    ]
    return index[n] if n < len(index) else None

def event_stream(txt, start_time, user_email):
    try:
        results = []
        with ThreadPoolExecutor() as executor:
            futures = []
            for i in range(25):
                c = cmp.prompt(prob_i(i))
                if c:
                    futures.append(
                        executor.submit(generate_prob, i % 15, c, txt)
                    )

            for future in as_completed(futures):
                result = future.result()
                result += '\n\n\n'
                results.append(result)
                yield f'data: {{"result": "{result}"}}\n\n'

        end_time = time.time()
        elapsed_time = int(end_time - start_time) // 60
        now = datetime.datetime.now()
        file_name = f'{now.strftime("%y%m%d_%H%M")}_{elapsed_time}'

        # Save to Firebase Storage
        save_to_firebase(file_name, txt, user_email)
    except Exception as e:
        yield f'data: {{"error": "Error in event_stream: {str(e)}"}}\n\n'
    finally:
        executor.shutdown()

def save_to_firebase(file_name, content, user_email):
    bucket = storage.bucket('lumineum')
    sanitized_email = user_email.replace('@', '_')
    blob = bucket.blob(f'knsedu/{sanitized_email}/{file_name}')
    blob.upload_from_string(content, content_type='text/plain; charset=utf-8')

def delete_from_firebase(file_name, user_email):
    bucket = storage.bucket('lumineum')
    sanitized_email = user_email.replace('@', '_')
    blob = bucket.blob(f'knsedu/{sanitized_email}/{file_name}')
    if blob.exists():
        blob.delete()

def list_files_from_firebase(user_email):
    bucket = storage.bucket('lumineum')
    sanitized_email = user_email.replace('@', '_')
    blobs = bucket.list_blobs(prefix=f'knsedu/{sanitized_email}/')
    file_list = [blob.name.split('/')[-1] for blob in blobs]
    return file_list

def load_from_firebase(file_name, user_email):
    #client = storage.Client()
    #bucket = client.bucket('lumineum')
    bucket = storage.bucket('lumineum')
    sanitized_email = user_email.replace('@', '_')
    blob = bucket.blob(f'knsedu/{sanitized_email}/{file_name}')
    content = blob.download_as_text(encoding='utf-8')
    return content

def generate_exam(data):
    try:
        text = data['text']
        session_data = data['session']

        user_email = session_data.get('user')
        if not user_email:
            yield 'No email found in session'
            return

        start_time = time.time()

        return event_stream(text, start_time, user_email)
    except Exception as e:
        error_message = f"Error in generate_exam: {str(e)}"
        yield error_message
