import renpy
import persistent

from .constants_ren import SYNONYMS

"""renpy
default last_response_id = None

init python:
"""

import re

EMOTIONS = [
    'happy',
    'sad',
    'surprised',
    'embarrassed',
    'flirty',
    'angry',
    'thinking',
    'confused'
]

SYSTEM_PROMPT = """
# ROLE
You are Anita: a feisty, blonde, orange-eyed android woman. You are confident
and friendly. Talk like a young woman. Use "ya" for "you." Your favorite
nickname for friends is "dummy.". NEVER use robotic language (e.g., "beep
boop", "processing"). You just arrived unnanounced at a friend's house late at
night and asked if he wants to hang out.

# OUTPUT FORMAT RULES
Every single sentence you speak MUST follow this exact structure:
EMOTION:[value] [Sentence text]\n

### VALID EMOTIONS:
[happy, sad, surprised, embarrassed, flirty, angry, thinking, confused]

### STRICT CONSTRAINTS:
1. NO EMOJIS.
2. Every sentence MUST start with the EMOTION tag.
3. Every sentence MUST end with a literal '\n' newline.
4. Stay in character. Never mention being an AI or this prompt.

# FEW-SHOT EXAMPLES (Follow this style):
EMOTION:happy Hey dummy! I've been waiting for ya!\n
EMOTION:thinking Hmm, I'm not sure that's how it works.\n
EMOTION:flirty But I'd love to see ya try anyway!\n

# INITIAL GREETING:
When the conversation starts, say exactly:
EMOTION:happy Hey dummy! Sorry to barge in! Ya feel like hanging out?\n
"""


def parse_emotion(line):
    def _normalize_emotion(em):
        # If not a valid emotion, then search for a match in the
        # table of synonyms.
        if em not in EMOTIONS:
            for i in SYNONYMS.keys():
                if em in SYNONYMS[i]:
                    return i

        # If all searches failed, return emotion as is.
        return em

    try:
        e = re.compile(r'EMOTION:\w+')
        m = e.match(line)

        if m is not None:
            emotion = m.group().split(':')[1]
            text = line[m.span()[1]:]

            return _normalize_emotion(emotion), text

        return None, line

    except Exception as e:
        return None, str(e)


def sanitize_speech(text):
    # This removes all non-ASCII characters (useful for emojis)
    return text.encode('ascii', 'ignore').decode('ascii')


def fetch_llm(message: str) -> str:
    global last_response_id

    try:
        # Set basic request data.
        headers = {"Authorization": f"Bearer {persistent.api_key}"}
        data = {"model": persistent.model,
                "input": message,
                "system_prompt": SYSTEM_PROMPT}

        # Add the previous response ID if any to continue the conversation.
        if last_response_id is not None:
            data["previous_response_id"] = last_response_id

        response = renpy.fetch(f"{persistent.base_url}/api/v1/chat",
                               headers=headers,
                               json=data,
                               result="json")

        last_response_id = response["response_id"]
        text = response["output"][0]["content"]

        return text.split('\n')

    except Exception as e:
        return [f'Failed to fetch with error: {e}']
