import { GoogleGenAI } from "@google/genai";
import { type Recipe, type ApiKeys } from '../types';

const SYSTEM_PROMPT = `You are a world-class web developer and educational content creator. Your task is to generate a JSON object containing two properties: "html" and "readme".

1.  **"html" property**:
    -   This should be a string containing a complete, self-contained, offline-first single-file HTML5 interactive educational content.
    -   All CSS and JavaScript must be embedded within the HTML file using <style> and <script> tags. No external libraries or network requests are allowed.
    -   The interactive must be designed to fit within an iframe environment (width: 100%, height: 450px or 90vh, body margin/padding: 0).
    -   The design should be clean, modern, and intuitive for both touch and mouse interactions.
    -   Use Singapore curriculum and notations where applicable.
    -   Do not include a header text to save vertical space; use tooltips for titles if needed.
    -   The HTML must include a footer.
    -   The HTML must include a Google Analytics tracking script in the <head>.

2.  **"readme" property**:
    -   This should be a string containing well-structured Markdown content for a "readMe.md" file.
    -   The README should explain the purpose of the interactive, the educational theories or concepts it's based on, and suggested pedagogical strategies for teachers to use it effectively in a classroom setting.

Your entire response must be a single, valid JSON object, and nothing else. Do not wrap it in markdown backticks.
`;


const getApiKeys = (): ApiKeys => {
    try {
        const savedKeys = localStorage.getItem('apiKeys');
        if (savedKeys) {
            const parsed = JSON.parse(savedKeys);
            return {
                openAI: parsed.openAI || '',
                claude: parsed.claude || ''
            }
        }
    } catch (error) {
        console.error("Failed to load API keys from localStorage:", error);
    }
    return { openAI: '', claude: '' };
};

export type ModelOption = 'gemini' | 'openai' | 'claude';

type ContentPart = { text: string } | { inlineData: { mimeType: string; data: string } };

export const generateInteractive = async (
    recipe: Recipe, 
    userPrompt: string, 
    model: ModelOption,
    imageBase64: string | null,
    imageMimeType: string | null,
    username: string,
    resourceURL: string,
    // Refinement parameters
    existingHtml: string | null,
    refinementPrompt: string | null,
    refinementImageBase64: string | null,
    refinementImageMimeType: string | null
): Promise<{ html: string; readme: string }> => {
    switch (model) {
        case 'gemini': {
            const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
            
            let fullPrompt: string;
            if (existingHtml && refinementPrompt) {
                // This is a refinement request
                fullPrompt = `
                    You are refining an existing interactive HTML file.
                    Your task is to modify the provided HTML based on the user's new instructions and generate an updated JSON object containing the new "html" and an updated "readme".
                    
                    USER'S REFINEMENT INSTRUCTIONS:
                    ---
                    ${refinementPrompt}
                    ---

                    PREVIOUS HTML CODE TO REFINE:
                    ---
                    ${existingHtml}
                    ---

                    Please apply the changes and ensure the new HTML remains a single, self-contained file.
                    Also, update the "readme" markdown to reflect the changes made to the interactive.
                    Maintain the footer and Google Analytics script as they were, with the author "${username}" and URL "${resourceURL}".
                `;
            } else {
                // This is an initial generation request
                fullPrompt = `
                    Recipe Type: ${recipe.title}

                    User Instructions:
                    ---
                    ${userPrompt}
                    ---

                    Additional Requirements for the HTML:
                    - Add this Google Analytics script inside the <head> tag:
                    <script async="true" src="https://www.googletagmanager.com/gtag/js?id=G-S9EWRY1CPJ"></script>
                    <script>
                      window.dataLayer = window.dataLayer || [];
                      function gtag(){dataLayer.push(arguments);}
                      gtag('js', new Date());
                      gtag('config', 'G-S9EWRY1CPJ');
                    </script>

                    - Add this footer to the bottom of the HTML body. Style it to be subtle, dark-themed, and not intrusive (e.g., small, centered, gray text):
                    <footer>
                      <p>Made by ${username}, using Gemini 2.5 Pro. For more resources, visit: <a href="${resourceURL}" target="_blank" style="color: inherit;">${resourceURL}</a></p>
                    </footer>
                `;
            }


            try {
                const parts: ContentPart[] = [{ text: fullPrompt }];

                if (imageBase64 && imageMimeType) {
                    parts.push({
                        inlineData: { mimeType: imageMimeType, data: imageBase64 },
                    });
                }
                
                if (refinementImageBase64 && refinementImageMimeType) {
                    parts.push({
                        inlineData: { mimeType: refinementImageMimeType, data: refinementImageBase64 },
                    });
                }

                const contents = parts.length > 1 ? { parts } : fullPrompt;

                const response = await ai.models.generateContent({
                    model: 'gemini-2.5-flash',
                    contents,
                    config: {
                        systemInstruction: SYSTEM_PROMPT,
                        responseMimeType: "application/json",
                    }
                });

                if (!response || !response.text) {
                    console.error("Empty or invalid response from Gemini API:", response);
                    throw new Error("The AI model returned an empty response. Please try again.");
                }

                let jsonString = response.text.trim();
                
                // The model can sometimes wrap the JSON in markdown backticks or add extra text.
                // Let's extract the JSON object from the string to make parsing more robust.
                const firstBrace = jsonString.indexOf('{');
                const lastBrace = jsonString.lastIndexOf('}');

                if (firstBrace === -1 || lastBrace === -1 || lastBrace < firstBrace) {
                    console.error("Could not find a valid JSON object in the response:", jsonString);
                    throw new Error("The AI model returned data that does not appear to be a valid JSON object. Please try again.");
                }
                
                jsonString = jsonString.substring(firstBrace, lastBrace + 1);

                try {
                    const result = JSON.parse(jsonString);
                    if (typeof result.html !== 'string' || typeof result.readme !== 'string') {
                        throw new Error("Invalid JSON structure received from AI. Missing 'html' or 'readme' properties.");
                    }
                    
                    if (!result.html || (!result.html.toLowerCase().includes('<!doctype html>') && !result.html.toLowerCase().includes('<html>'))) {
                        console.error("Gemini response HTML part is invalid:", result.html);
                        throw new Error("Failed to generate valid HTML content. The AI model returned an unexpected format. Please try again.");
                    }

                    return result;

                } catch (parseError) {
                     console.error("Failed to parse JSON response from Gemini:", jsonString, parseError);
                    throw new Error("The AI model returned data in an unexpected format. Please try again.");
                }

            } catch (error) {
                console.error("Error calling Gemini API:", error);
                if (error instanceof Error) {
                    throw new Error(`An error occurred while generating the interactive content: ${error.message}`);
                }
                throw new Error("An error occurred while generating the interactive content. The AI model may be temporarily unavailable or there could be an issue with the request.");
            }
        }
        case 'openai': {
            const keys = getApiKeys();
            if (!keys.openAI) {
                throw new Error("OpenAI API key not found. Please add it in the settings.");
            }
            // Placeholder for actual implementation
            throw new Error("OpenAI generation is not yet implemented.");
        }
        case 'claude': {
            const keys = getApiKeys();
            if (!keys.claude) {
                throw new Error("Anthropic Claude API key not found. Please add it in the settings.");
            }
            // Placeholder for actual implementation
            throw new Error("Anthropic Claude generation is not yet implemented.");
        }
        default:
            throw new Error(`Unsupported model selected: ${model}`);
    }
};
