import React, { useState, useEffect } from 'react';
import { createRoot } from 'react-dom/client';
import html2canvas from 'html2canvas';

const transformerImageDataUri = '/0_WGCl24jT_rWfgZWL.png';

const App = () => {
    // Component definitions for the Transformer architecture
    const components = [
        { id: 'inputs', label: 'Inputs', side: 'encoder' },
        { id: 'input-embedding', label: 'Input Embedding', side: 'encoder' },
        { id: 'positional-encoding', label: 'Positional Encoding', side: 'encoder' },
        { id: 'multi-head-attention', label: 'Multi-Head Attention', side: 'encoder' },
        { id: 'add-norm', label: 'Add & Norm', side: 'encoder' },
        { id: 'feedforward', label: 'Feedforward', side: 'encoder' },
        { id: 'outputs', label: 'Outputs (shifted right)', side: 'decoder' },
        { id: 'output-embedding', label: 'Output Embedding', side: 'decoder' },
        { id: 'decoder-positional-encoding', label: 'Positional Encoding', side: 'decoder' },
        { id: 'masked-multi-head-attention', label: 'Masked Multi-Head Attention', side: 'decoder' },
        { id: 'decoder-add-norm', label: 'Add & Norm', side: 'decoder' },
        { id: 'cross-attention', label: 'Cross Attention', side: 'decoder' },
        { id: 'decoder-feedforward', label: 'Feedforward', side: 'decoder' },
        { id: 'linear', label: 'Linear', side: 'decoder' },
        { id: 'softmax', label: 'Softmax', side: 'decoder' },
        { id: 'output-probabilities', label: 'Output Probabilities', side: 'decoder' },
    ];

    const [notes, setNotes] = useState<{ [key: string]: string }>({});
    const [showToast, setShowToast] = useState(false);
    const [name, setName] = useState('');

    // Load notes from localStorage on initial render
    useEffect(() => {
        try {
            const savedNotes = localStorage.getItem('transformer-notes');
            if (savedNotes) {
                setNotes(JSON.parse(savedNotes));
            }
        } catch (error) {
            console.error("Failed to load notes from localStorage", error);
        }
    }, []);

    const handleNoteChange = (id: string, value: string) => {
        setNotes((prev: { [key: string]: string }) => ({ ...prev, [id]: value }));
    };

    const handleSaveNotes = async () => {
        const appContainer = document.querySelector('.app-container') as HTMLElement;
        if (!appContainer) return;
        try {
            const canvas = await html2canvas(appContainer, { backgroundColor: '#121212' });
            const image = canvas.toDataURL('image/png');
            const link = document.createElement('a');
            link.href = image;
            link.download = 'transformer-notes.png';
            link.click();
        } catch (error) {
            console.error('Failed to capture screenshot', error);
        }
    };

    const encoderComponents = components.filter(c => c.side === 'encoder');
    const decoderComponents = components.filter(c => c.side === 'decoder');

    const renderNoteColumn = (title: string, componentsToRender: { id: string; label: string; side: string }[]) => (
        <div className="notes-column">
            <h2 className="column-title">{title}</h2>
            {componentsToRender.map(comp => (
                <div className="note-block" key={comp.id}>
                    <label className="note-label" htmlFor={comp.id}>{comp.label}</label>
                    <textarea
                        id={comp.id}
                        aria-label={`Notes for ${comp.label}`}
                        value={notes[comp.id] || ''}
                        onChange={(e: React.ChangeEvent<HTMLTextAreaElement>) => handleNoteChange(comp.id, e.target.value)}
                        placeholder={`Explain ${comp.label}...`}
                    />
                </div>
            ))}
        </div>
    );

    return (
        <div className="app-container">
            <header className="header">
                <h1>Interactive Transformer Architecture</h1>
                <p>An interactive diagram of the Transformer model from "Attention Is All You Need". Add your notes in the text boxes to explain each part. Your notes will be saved locally in your browser.</p>
            </header>
            
            <div className="save-button-container" style={{ flexDirection: 'column', alignItems: 'center', gap: '1rem' }}>
                <input
                    type="text"
                    className="name-input"
                    placeholder="Enter your name..."
                    value={name}
                    onChange={e => setName(e.target.value)}
                    style={{ padding: '10px', borderRadius: '6px', border: '1px solid #333', width: '250px', fontSize: '1rem', marginBottom: '0.5rem' }}
                />
                <button className="save-button" onClick={handleSaveNotes}>
                    Save Notes
                </button>
            </div>
            
            <div className="architecture-container">
                {renderNoteColumn('Encoder', encoderComponents)}
                
                <div className="image-column">
                    <img 
                        src={transformerImageDataUri}
                        alt="Transformer Architecture Diagram" 
                        className="architecture-image"
                    />
                </div>

                {renderNoteColumn('Decoder', decoderComponents)}
            </div>

            <div className={`toast ${showToast ? 'show' : ''}`}>
                Notes saved successfully!
            </div>
        </div>
    );
};

const container = document.getElementById('root');
if (container) {
    const root = createRoot(container);
    root.render(<App />);
}
