solve any problems with this app and make it better: <html><head><base href="https://example.com"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Enhanced Comic Strip Creator</title><style>
/* WebSim specific enhancements */
body {
  font-family: system-ui, -apple-system, sans-serif;
  background: #FAF9F6;
  line-height: 1.6;
}

/* Update root colors with comic-inspired palette */
:root {
  --websim-primary: #FF4B4B;  /* Dynamic red for action */
  --websim-secondary: #4B4BFF; /* Bold blue for contrast */
  --websim-success: #37DC94; /* Vibrant green like comic highlights */
  --websim-danger: #FF6B6B; /* Softer red for warnings */
  --websim-warning: #FFD93D; /* Comic yellow for alerts */
  --websim-info: #6B9BFF; /* Soft blue for information */
  
  /* Add comic-specific colors */
  --comic-ink: #2D3436; /* Dark gray for text */
  --comic-paper: #FAF9F6; /* Off-white background */
  --comic-accent: #FF6B6B; /* Vibrant accent color */
}

.websim-container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 2rem;
}

.websim-header {
  text-align: center;
  margin-bottom: 3rem;
}

.websim-title {
  font-size: 2.5rem;
  color: var(--comic-ink);
  font-family: 'Comic Sans MS', cursive;
  text-transform: uppercase;
  letter-spacing: 2px;
  text-shadow: 2px 2px var(--comic-accent);
  margin-bottom: 1rem;
}

.websim-description {
  color: #5f6368;
  font-size: 1.2rem;
}

/* Enhanced UI Components */
.websim-panel {
  background: white;
  border-radius: 12px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
  padding: 2rem;
  margin-bottom: 2rem;
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.websim-panel:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0,0,0,0.15);
}

/* Comic-Themed Button Styling */
.websim-button {
  background: var(--websim-primary);
  color: white;
  border: 3px solid var(--comic-ink);
  box-shadow: 4px 4px var(--comic-ink);
  padding: 0.8rem 1.6rem;
  border-radius: 24px;
  font-size: 1rem;
  cursor: pointer;
  transition: all 0.3s ease;
  transform: translate(-2px, -2px);
}

.websim-button:hover {
  background: #1557b0;
  transform: translate(0, 0);
  box-shadow: 2px 2px var(--comic-ink);
}

.websim-button.danger {
  background: #FF6B6B;
}

.websim-button.danger:hover {
  background: #c82333;
}

/* Input Styling */
.websim-input {
  width: 100%;
  padding: 0.8rem;
  border: 2px solid #e0e0e0;
  border-radius: 8px;
  font-size: 1rem;
  transition: border-color 0.3s ease;
}

.websim-input:focus {
  border-color: var(--websim-primary);
  outline: none;
}

/* Animation Classes */
.fade-in {
  animation: fadeIn 0.5s ease-out;
}

@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Responsive Design */
@media (max-width: 768px) {
  .websim-container {
    padding: 1rem;
  }
  
  .websim-title {
    font-size: 2rem;
  }
}

/* Toast Notifications */
.websim-toast {
  position: fixed;
  bottom: 20px;
  right: 20px;
  padding: 1rem 2rem;
  background: #333;
  color: white;
  border-radius: 8px;
  animation: slideIn 0.3s ease-out;
  z-index: 1000;
}

@keyframes slideIn {
  from {
    transform: translateX(100%);
    opacity: 0;
  }
  to {
    transform: translateX(0);
    opacity: 1;
  }
}

/* Loading States */
.websim-loading {
  display: inline-block;
  width: 20px;
  height: 20px;
  border: 2px solid #f3f3f3;
  border-top: 2px solid var(--websim-primary);
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

/* Progress Indicators */
.websim-progress {
  width: 100%;
  height: 4px;
  background: #e0e0e0;
  border-radius: 2px;
  overflow: hidden;
}

.websim-progress-bar {
  height: 100%;
  background: var(--websim-primary);
  width: 0%;
  transition: width 0.3s ease;
}

/* Modal Styles */
.websim-modal {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0,0,0,0.5);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1000;
}

.websim-modal-content {
  background: white;
  padding: 2rem;
  border-radius: 12px;
  max-width: 500px;
  width: 90%;
}

/* Grid System */
.websim-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 1rem;
}

/* Card Components */
.websim-card {
  border: 3px solid var(--comic-ink);
  background: white;
  padding: 1rem;
  box-shadow: 8px 8px 0 rgba(0,0,0,0.1);
  position: relative;
}

.websim-card::before {
  content: '';
  position: absolute;
  top: -8px;
  left: -8px;
  right: -8px;
  bottom: -8px;
  border: 2px dashed var(--comic-accent);
  z-index: -1;
  opacity: 0.5;
}

/* Style options enhancement */
.style-option {
  cursor: pointer;
  transition: transform 0.3s ease;
}

.style-option:hover {
  transform: scale(1.05);
}

.style-option.selected {
  border-color: var(--websim-primary);
  background: var(--comic-paper);
}

/* Message Box Styles */
.message {
  position: fixed;
  top: 20px;
  right: 20px;
  padding: 1rem 2rem;
  border-radius: 8px;
  z-index: 1001;
  opacity: 0.9;
}

.message.success {
  background-color: var(--websim-success);
  color: white;
}

.message.error {
  background-color: var(--websim-danger);
  color: white;
}

/* Comic Strip Preview Styles */
.comic-panel {
  margin-bottom: 2rem;
  text-align: center;
}

.comic-panel img {
  max-width: 100%;
  height: auto;
  border: 2px solid var(--comic-ink);
  border-radius: 8px;
}

.dialogue {
  font-size: 1.1rem;
  margin-top: 0.5rem;
  color: var(--comic-ink);
}
</style>
</head><body>
<div class="websim-container">
  <div class="websim-header">
    <h1 class="websim-title">Comic Strip Creator Simulation</h1>
    <p class="websim-description">Create and customize your own comic strips with AI assistance</p>
  </div>

  <div id="app" class="websim-content">
    <!-- Style Selection -->
    <div class="websim-panel fade-in">
      <h2>Choose Your Style</h2>
      <div class="websim-grid style-options">
        <div class="websim-card style-option" data-style="manga">
          <h3>Manga Style</h3>
          <svg width="100" height="100" viewBox="0 0 100 100">
            <rect x="10" y="10" width="80" height="80" fill="#fff" stroke="#000" stroke-width="2"/>
            <circle cx="50" cy="40" r="20" fill="none" stroke="#000" stroke-width="2"/>
            <path d="M 30,70 Q 50,80 70,70" fill="none" stroke="#000" stroke-width="2"/>
          </svg>
        </div>
        
        <div class="websim-card style-option" data-style="american">
          <h3>American Comic</h3>
          <svg width="100" height="100" viewBox="0 0 100 100">
            <rect x="10" y="10" width="80" height="80" fill="#fff" stroke="#000" stroke-width="3"/>
            <circle cx="50" cy="40" r="15" fill="#000"/>
            <path d="M 25,65 L 75,65" stroke="#000" stroke-width="3"/>
          </svg>
        </div>
        
        <div class="websim-card style-option" data-style="european">
          <h3>European BD</h3>
          <svg width="100" height="100" viewBox="0 0 100 100">
            <rect x="10" y="10" width="80" height="80" fill="#fff" stroke="#000" stroke-width="1"/>
            <ellipse cx="50" cy="40" rx="25" ry="20" fill="none" stroke="#000"/>
            <path d="M 30,75 Q 50,85 70,75" fill="none" stroke="#000"/>
          </svg>
        </div>
      </div>
    </div>

    <!-- Input Section -->
    <div class="websim-panel fade-in">
      <h2>Story Details</h2>
      <input type="text" class="websim-input" id="storyTitle" placeholder="The Adventures of Pixel Pete">
      <textarea class="websim-input" id="storyDescription" rows="4" placeholder="A brave hero ventures into the unknown to save the kingdom."></textarea>
    </div>

    <!-- Character Creation -->
    <div class="websim-panel fade-in">
      <h2>Character Creation</h2>
      <div class="websim-grid">
        <div class="websim-card">
          <h3>Protagonist</h3>
          <input type="text" class="websim-input" id="protagonistName" placeholder="Arthur">
          <textarea class="websim-input" id="protagonistDescription" placeholder="A courageous knight with a strong sense of justice."></textarea>
          <input type="text" class="websim-input" id="protagonistPersonality" placeholder="Brave, Loyal, Determined">
          <input type="text" class="websim-input" id="protagonistSeed" placeholder="123456" readonly>
        </div>
        <div class="websim-card">
          <h3>Antagonist</h3>
          <input type="text" class="websim-input" id="antagonistName" placeholder="Morgana">
          <textarea class="websim-input" id="antagonistDescription" placeholder="A cunning sorceress seeking to overthrow the kingdom."></textarea>
          <input type="text" class="websim-input" id="antagonistPersonality" placeholder="Manipulative, Ambitious, Ruthless">
          <input type="text" class="websim-input" id="antagonistSeed" placeholder="654321" readonly>
        </div>
      </div>
      <button class="websim-button" id="saveCharacterProfiles">Save Character Profiles</button>
    </div>

    <!-- Text Assistant Input Section -->
    <div class="websim-panel fade-in">
      <h2>Text Assistant</h2>
      <textarea class="websim-input" id="textAssistant" rows="4" placeholder="Include elements of mystery and suspense."></textarea>
      <button class="websim-button" onclick="comicCreator.refineStoryline()">Refine Storyline</button>
    </div>

    <!-- Panel Creator -->
    <div class="websim-panel fade-in">
      <h2>Panel Creator</h2>
      <div id="panelsContainer"></div>
      <button class="websim-button add-panel-btn">Add New Panel</button>
      <button class="websim-button" onclick="comicCreator.generateComicStrip()">Generate Comic Strip</button>
    </div>

    <!-- Preview Section -->
    <div class="websim-panel fade-in preview-section" style="display: none;">
      <h2>Preview</h2>
      <div id="comicStrip"></div>
    </div>

    <!-- Export Options -->
    <div class="websim-panel fade-in">
      <h2>Export Options</h2>
      <div class="websim-grid">
        <button class="websim-button" id="exportPdfBtn">Export as PDF</button>
        <button class="websim-button" id="exportImageBtn">Export as Image</button>
        <button class="websim-button" id="shareFacebookBtn">Share on Facebook</button>
        <button class="websim-button" id="shareTwitterBtn">Share on Twitter</button>
      </div>
    </div>
  </div>
</div>

<!-- Loading Overlay -->
<div id="loadingOverlay" class="websim-modal" style="display: none;">
  <div class="websim-loading"></div>
</div>

<!-- Toast Container -->
<div id="toastContainer"></div>

<!-- Message Box -->
<div id="messageBox" class="message" style="display: none;"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.2.7/pdfmake.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.2.7/vfs_fonts.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js"></script>
<script>
// ImageCache Class: Handles image caching to optimize performance
class ImageCache {
  constructor() {
    this.cache = new Map();
  }

  async getImage(url) {
    if (this.cache.has(url)) {
      return this.cache.get(url);
    }

    try {
      const imageData = await this.loadImage(url);
      this.cache.set(url, imageData);
      return imageData;
    } catch (error) {
      throw new Error(`Failed to load image: ${error.message}`);
    }
  }

  async loadImage(url) {
    return new Promise((resolve, reject) => {
      const img = new Image();
      img.crossOrigin = 'anonymous';
      img.onload = () => {
        resolve({
          dataUrl: img.src,
          width: img.width,
          height: img.height,
          element: img
        });
      };
      img.onerror = () => reject(new Error('Image load failed'));
      img.src = url;
    });
  }

  clear() {
    this.cache.clear();
  }
}

// PollinationsAPI Class: Handles interaction with the Pollinations API, including retries and rate limiting
class PollinationsAPI {
  static retryDelay = 1000; // ms
  static maxRetries = 5;
  static requestQueue = [];
  static isProcessingQueue = false;
  static rateLimitDelay = 1000; // 1 second

  static async fetchWithRetry(url, options = {}, retries = this.maxRetries) {
    try {
      const response = await fetch(url, options);
      if (response.status === 429) {
        throw new Error('RATE_LIMIT');
      }
      if (!response.ok) {
        throw new Error('FETCH_ERROR');
      }
      return response;
    } catch (error) {
      if (retries === 0) throw error;
      if (error.message === 'RATE_LIMIT') {
        await new Promise(res => setTimeout(res, this.rateLimitDelay));
      } else {
        await new Promise(res => setTimeout(res, this.retryDelay * (this.maxRetries - retries + 1)));
      }
      return this.fetchWithRetry(url, options, retries - 1);
    }
  }

  static async queueRequest(requestFn) {
    return new Promise((resolve, reject) => {
      this.requestQueue.push({ requestFn, resolve, reject });
      if (!this.isProcessingQueue) this.processQueue();
    });
  }

  static async processQueue() {
    if (this.requestQueue.length === 0) {
      this.isProcessingQueue = false;
      return;
    }
    this.isProcessingQueue = true;
    const { requestFn, resolve, reject } = this.requestQueue.shift();
    try {
      const result = await requestFn();
      resolve(result);
    } catch (error) {
      reject(error);
    }
    await new Promise(res => setTimeout(res, this.rateLimitDelay));
    this.processQueue();
  }

  // Generates text using Pollinations AI
  static async generateText(prompt) {
    return this.queueRequest(async () => {
      try {
        const url = `https://text.pollinations.ai/${encodeURIComponent(prompt)}`;
        const response = await this.fetchWithRetry(url);
        return response.text();
      } catch (error) {
        if (error.message === 'RATE_LIMIT') {
          throw new Error('Rate limit exceeded. Please try again later.');
        }
        throw new Error('Failed to generate text.');
      }
    });
  }

  // Generates image using Pollinations AI with support for seeds
  static async generateImage(prompt, settings = {}) {
    return this.queueRequest(async () => {
      const baseUrl = 'https://image.pollinations.ai/prompt/';
      const params = new URLSearchParams({
        width: settings.width || 512, // Adjusted for typical comic panel size
        height: settings.height || 512,
        seed: settings.seed || Math.floor(Math.random() * 1000000),
        nologo: 'true',
        model: settings.model || 'flux', // Default model
        private: 'true',
        t: Date.now()
      });

      const encodedPrompt = encodeURIComponent(prompt);
      const url = `${baseUrl}${encodedPrompt}?${params}`;

      try {
        const response = await this.fetchWithRetry(url);
        if (!response.url) {
          throw new Error('Image URL not found in response.');
        }
        return response.url;
      } catch (error) {
        if (error.message === 'RATE_LIMIT') {
          throw new Error('Rate limit exceeded. Please try again later.');
        }
        throw new Error('Failed to generate image.');
      }
    });
  }
}

// PersonalizedComicStripCreator Class: Core application logic
class PersonalizedComicStripCreator {
  constructor() {
    // Initialize properties
    this.currentPage = 0;
    this.pages = [];
    this.isGenerating = false;
    this.imageCache = new ImageCache();

    // Bind UI elements
    this.storyTitleInput = document.getElementById('storyTitle');
    
    // Updated Reference
    this.dialogueInput = document.getElementById('storyDescription');
    
    this.textAssistantInput = document.getElementById('textAssistant');
    
    // Character profiles
    this.protagonistNameInput = document.getElementById('protagonistName');
    this.protagonistDescriptionInput = document.getElementById('protagonistDescription');
    this.protagonistPersonalityInput = document.getElementById('protagonistPersonality');
    
    this.antagonistNameInput = document.getElementById('antagonistName');
    this.antagonistDescriptionInput = document.getElementById('antagonistDescription');
    this.antagonistPersonalityInput = document.getElementById('antagonistPersonality');
    
    // Seed inputs
    this.protagonistSeedInput = document.getElementById('protagonistSeed');
    this.antagonistSeedInput = document.getElementById('antagonistSeed');

    // Panel Container
    this.panelsContainer = document.getElementById('panelsContainer');

    // Export buttons
    this.exportPdfBtn = document.getElementById('exportPdfBtn');
    this.exportImageBtn = document.getElementById('exportImageBtn');
    this.shareFacebookBtn = document.getElementById('shareFacebookBtn');
    this.shareTwitterBtn = document.getElementById('shareTwitterBtn');
    
    // Comic Strip Preview
    this.comicStrip = document.getElementById('comicStrip');
    this.previewSection = document.querySelector('.preview-section');
    
    // Message Box
    this.messageBox = document.getElementById('messageBox');

    // Bind Events
    this.bindEvents();
    
    // Initialize Comic Panels
    this.panelCount = 0;
  }

  // Function to bind event listeners
  bindEvents() {
    document.getElementById('saveCharacterProfiles').addEventListener('click', () => this.saveCharacterProfiles());
    document.querySelector('.add-panel-btn').addEventListener('click', () => this.addPanel());
    this.exportPdfBtn.addEventListener('click', () => this.exportAsPDF());
    this.exportImageBtn.addEventListener('click', () => this.exportAsImage());
    this.shareFacebookBtn.addEventListener('click', () => this.shareOnSocial('facebook'));
    this.shareTwitterBtn.addEventListener('click', () => this.shareOnSocial('twitter'));
    
    // Ensure that the refineStoryline method is correctly bound
    document.querySelector('button[onclick="comicCreator.refineStoryline()"]').addEventListener('click', () => this.refineStoryline());
  }

  // Function to save character profiles from UI inputs
  saveCharacterProfiles() {
    // Update protagonist profile
    this.characters = {
      protagonist: {
        name: this.protagonistNameInput.value.trim(),
        description: this.protagonistDescriptionInput.value.trim(),
        personality: this.protagonistPersonalityInput.value.trim(),
        seed: this.characters?.protagonist?.seed || null
      },
      antagonist: {
        name: this.antagonistNameInput.value.trim(),
        description: this.antagonistDescriptionInput.value.trim(),
        personality: this.antagonistPersonalityInput.value.trim(),
        seed: this.characters?.antagonist?.seed || null
      }
      // Add more characters as needed
    };
    
    // Assign seeds if not already assigned
    for (const [key, character] of Object.entries(this.characters)) {
      if (!character.seed) {
        character.seed = this.generateSeed(character.name);
        this.updateSeedUI(key);
      }
    }

    this.showMessage('Character profiles saved successfully!', 'success');
  }

  // Function to assign a unique seed based on character name
  generateSeed(identifier) {
    let hash = 0;
    for (let i = 0; i < identifier.length; i++) {
      hash = identifier.charCodeAt(i) + ((hash << 5) - hash);
    }
    return Math.abs(hash);
  }

  // Function to update seed inputs in the UI
  updateSeedUI(characterKey) {
    const seedInput = document.getElementById(`${characterKey}Seed`);
    if (seedInput && this.characters[characterKey]) {
      seedInput.value = this.characters[characterKey].seed.toString();
    }
  }

  // Function to add a new panel
  addPanel() {
    this.panelCount++;
    const panelDiv = document.createElement('div');
    panelDiv.classList.add('panel');
    panelDiv.innerHTML = `
      <div class="panel-number">${this.panelCount}</div>
      
      <label for="dialoguePanel${this.panelCount}">Dialogue for Panel ${this.panelCount}:</label>
      <textarea id="dialoguePanel${this.panelCount}" rows="3" placeholder="We must journey to the Dark Forest."></textarea>
      
      <label for="scenarioPanel${this.panelCount}">Scenario for Panel ${this.panelCount}:</label>
      <textarea id="scenarioPanel${this.panelCount}" rows="3" placeholder="The heroes arrive at the edge of the Dark Forest, shrouded in mist."></textarea>
      
      <button class="remove-panel-btn">Remove Panel</button>
    `;
    
    // Add event listener to remove panel
    panelDiv.querySelector('.remove-panel-btn').addEventListener('click', () => this.removePanel(panelDiv));
    
    this.panelsContainer.appendChild(panelDiv);
  }

  // Function to remove a panel
  removePanel(panelDiv) {
    panelDiv.remove();
    
    // Update panel numbers
    this.panelCount--;
    const panels = this.panelsContainer.querySelectorAll('.panel');
    panels.forEach((panel, index) => {
      panel.querySelector('.panel-number').textContent = index + 1;
    });
  }

  // Function to generate and refine storyline with AI
  async refineStoryline() {
    const initialDialogue = this.dialogueInput.value.trim(); // Updated reference
    const aiAssistantText = this.textAssistantInput.value.trim();

    if (!initialDialogue) {
      this.showMessage('Please enter some dialogues or plot points.', 'error');
      return;
    }

    let prompt = `Refine and expand the following storyline for a comic strip:\n\n${initialDialogue}`;
    if (aiAssistantText) {
      prompt += `\n\nAdditional instructions: ${aiAssistantText}`;
    }

    try {
      const refinedStory = await PollinationsAPI.generateText(prompt);
      this.dialogueInput.value = refinedStory.trim(); // Updated reference
      this.showMessage('Storyline refined successfully!', 'success');
    } catch (error) {
      this.showMessage(error.message, 'error');
    }
  }

  // Function to assemble the comic strip in the preview section
  async assembleComicStrip() {
    if (this.pages.length === 0) {
      this.showMessage('Please generate the comic strip first.', 'error');
      return;
    }
    
    this.comicStrip.innerHTML = '';
    
    for (const page of this.pages) {
      const panelDiv = document.createElement('div');
      panelDiv.classList.add('comic-panel');
      
      const img = document.createElement('img');
      img.src = page.imageUrl;
      img.alt = "Comic Panel Illustration";
      
      const dialogueP = document.createElement('p');
      dialogueP.classList.add('dialogue');
      dialogueP.textContent = page.dialogue;
      
      panelDiv.appendChild(img);
      panelDiv.appendChild(dialogueP);
      
      this.comicStrip.appendChild(panelDiv);
    }
    
    this.previewSection.style.display = 'block';
  }

  // Function to generate the comic strip by calling AI APIs
  async generateComicStrip() {
    if (this.isGenerating) return;

    this.isGenerating = true;
    this.showMessage('Generating comic strip...', 'success');

    try {
      // Clear previous panels
      this.pages = [];
    
      // Iterate through each panel input
      const panels = this.panelsContainer.querySelectorAll('.panel');
      for (let i = 0; i < panels.length; i++) {
        const panel = panels[i];
        const dialogue = panel.querySelector('textarea[id^="dialoguePanel"]').value.trim();
        const scenario = panel.querySelector('textarea[id^="scenarioPanel"]').value.trim();
    
        if (!dialogue || !scenario) {
          this.showMessage(`Please fill in all fields for Panel ${i + 1}.`, 'error');
          this.isGenerating = false;
          return;
        }
    
        // Generate scene description with Pollinations AI
        const sceneDescription = await PollinationsAPI.generateText(`
          Create a detailed and stylistic description for a comic panel illustration.
          Characters:
            Protagonist: ${this.characters.protagonist.description} Personality: ${this.characters.protagonist.personality}
            Antagonist: ${this.characters.antagonist.description} Personality: ${this.characters.antagonist.personality}
          Scenario: ${scenario}
          Dialogue: "${dialogue}"
          Theme: ${this.storyTitleInput.value.trim() || 'General'}
          Consider:
            - Character continuity
            - Expressive emotions
            - Dynamic angles
            - Background details
            - Panel composition
        `);
    
        // Build image prompt
        const imagePrompt = `
          ${sceneDescription}
          --seed=${this.characters.protagonist.seed} --seed=${this.characters.antagonist.seed}
        `;
    
        // Generate image
        const imageUrl = await PollinationsAPI.generateImage(imagePrompt, { 
          width: 512, 
          height: 512,
          seed: this.characters.protagonist.seed // Using protagonist's seed for consistency
        });
    
        // Add panel to pages
        this.pages.push({
          dialogue: dialogue,
          scenario: scenario,
          imageUrl: imageUrl
        });
    
        this.showMessage(`Panel ${i + 1} generated successfully!`, 'success');
      }
    
      // Assemble and display the comic strip
      await this.assembleComicStrip();
      this.showMessage('Comic strip generated successfully!', 'success');
    
    } catch (error) {
      this.showMessage(error.message, 'error');
    } finally {
      this.isGenerating = false;
    }
  }

  // Function to export the comic strip as PDF
  async exportAsPDF() {
    if (this.pages.length === 0) {
      this.showMessage('Please generate the comic strip first.', 'error');
      return;
    }

    try {
      const storyTitle = this.storyTitleInput.value.trim() || 'My Comic Strip';

      const docDefinition = {
        content: [
          { text: storyTitle, style: 'header', alignment: 'center', margin: [0, 0, 0, 20] }
        ],
        styles: {
          header: {
            fontSize: 22,
            bold: true
          },
          dialogue: {
            italics: true,
            alignment: 'center',
            margin: [0, 10, 0, 10]
          }
        }
      };

      for (const page of this.pages) {
        docDefinition.content.push({ image: page.imageUrl, width: 500 });
        docDefinition.content.push({ text: `"${page.dialogue}"`, style: 'dialogue' });
        docDefinition.content.push({ text: '\n' }); // Spacer
      }

      pdfMake.createPdf(docDefinition).download(`${storyTitle}.pdf`);
      this.showMessage('Comic strip exported as PDF successfully!', 'success');
    } catch (error) {
      this.showMessage('Failed to export PDF. Please try again.', 'error');
    }
  }

  // Function to export the comic strip as a single image
  async exportAsImage() {
    if (this.pages.length === 0) {
      this.showMessage('Please generate the comic strip first.', 'error');
      return;
    }

    try {
      // Create a canvas to combine all panels vertically
      const canvas = document.createElement('canvas');
      const context = canvas.getContext('2d');
      const panelWidth = 512;
      let panelHeightTotal = 0;

      // Load all images
      const images = await Promise.all(this.pages.map(page => this.loadImage(page.imageUrl)));
      images.forEach(img => {
        panelHeightTotal += img.height;
      });

      canvas.width = panelWidth;
      canvas.height = panelHeightTotal;

      // Draw images onto the canvas
      let yOffset = 0;
      images.forEach((img, index) => {
        context.drawImage(img, 0, yOffset, panelWidth, img.height);
        yOffset += img.height;
        // Add dialogue text below each panel
        context.font = '16px Arial';
        context.fillStyle = '#000';
        context.textAlign = 'center';
        context.fillText(`"${this.pages[index].dialogue}"`, panelWidth / 2, yOffset - 10);
      });

      // Convert canvas to image and download
      canvas.toBlob(blob => {
        saveAs(blob, `${this.storyTitleInput.value.trim() || 'My_Comic_Strip'}.png`);
        this.showMessage('Comic strip exported as image successfully!', 'success');
      });
    } catch (error) {
      this.showMessage('Failed to export image. Please try again.', 'error');
    }
  }

  // Function to share the comic strip on social media
  shareOnSocial(platform) {
    if (this.pages.length === 0) {
      this.showMessage('Please generate the comic strip first.', 'error');
      return;
    }

    // For simplicity, we'll export as image and allow sharing manually
    this.exportAsImage();
    this.showMessage(`Comic strip exported. Please share it on ${platform.charAt(0).toUpperCase() + platform.slice(1)}!`, 'success');
  }

  // Function to load an image from URL
  loadImage(url) {
    return new Promise((resolve, reject) => {
      const img = new Image();
      img.crossOrigin = 'anonymous';
      img.onload = () => resolve(img);
      img.onerror = () => reject(new Error('Image failed to load.'));
      img.src = url;
    });
  }

  // Function to show messages
  showMessage(message, type = 'success') {
    this.messageBox.textContent = message;
    this.messageBox.className = `message ${type}`;
    this.messageBox.style.display = 'block';
    setTimeout(() => {
      this.messageBox.style.display = 'none';
    }, 4000);
  }
}

// Initialize the Application on DOM Content Loaded
document.addEventListener('DOMContentLoaded', () => {
  window.comicCreator = new PersonalizedComicStripCreator();
});
</script>
</body></html>