make it so that it doesn't go one by one instead its one json file with going down the list of the font names, just make it one json file that it reads from instead, so we can do large amount of data, now write the full complete code, keep the api key  this is just for testing: <html><head><base href="https://websim.example.com/font-organizer/"><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Font Organizer</title><link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap" rel="stylesheet"><script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.0/jszip.min.js"></script><style>
:root {
  --bg-primary: #ffffff;
  --bg-secondary: #f7f6f3;
  --text-primary: #37352f;
  --text-secondary: #6b6b6b;
  --accent: #e16745;
  --border: #e0e0e0;
  --card-bg: #ffffff;
  --hover-bg: #f1efea;
  --modal-bg: #ffffff;
}

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
  background-color: var(--bg-primary);
  color: var(--text-primary);
  height: 100vh;
  display: flex;
  flex-direction: column;
}

#app-container {
  flex: 1;
  display: flex;
  overflow: hidden;
  transition: filter 0.3s ease;
}

#app-container.blurred {
  filter: blur(5px);
}

header {
  background-color: transparent;
  backdrop-filter: blur(10px);
  padding: 16px 40px;
  box-shadow: none;
  border-bottom: 1px solid var(--border);
}

header h1 {
  font-family: 'Inter', sans-serif;
  font-weight: 700;
  font-size: 28px;
  color: var(--text-primary);
}

main {
  flex: 1;
  display: flex;
  overflow: hidden;
  position: relative;
  z-index: 0;
}

.sidebar {
  width: 250px;
  background-color: var(--bg-primary);
  border-right: 1px solid var(--border);
  padding: 20px;
  overflow-y: auto;
}

.sidebar h2 {
  font-size: 14px;
  text-transform: uppercase;
  color: var(--text-secondary);
  margin-bottom: 8px;
}

.sidebar ul {
  list-style: none;
}

.sidebar li {
  padding: 10px;
  margin-bottom: 2px;
  background-color: var(--bg-secondary);
  cursor: pointer;
  border-radius: 4px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  transition: background-color 0.2s;
}

.sidebar li.active, .sidebar li:hover {
  background-color: var(--hover-bg);
}

.sidebar button {
  background-color: var(--accent);
  color: #ffffff;
  border: none;
  padding: 10px 15px;
  border-radius: 4px;
  cursor: pointer;
  margin-top: 15px;
  width: 100%;
  transition: background-color 0.2s, transform 0.1s;
}

.sidebar button:hover {
  background-color: #d15a3c;
  transform: translateY(-1px);
}

.content {
  flex: 1;
  padding: 20px;
  overflow-y: auto;
}

.upload-section {
  margin-bottom: 20px;
  padding: 30px;
  background-color: var(--bg-secondary);
  border: 1px solid var(--border);
  border-radius: 4px;
  text-align: center;
  cursor: pointer;
  transition: background-color 0.3s, border-color 0.3s;
  position: relative;
}

.upload-section.dragover {
  background-color: var(--hover-bg);
  border-color: var(--accent);
}

.upload-section input {
  display: none;
}

.upload-section p {
  pointer-events: none;
  color: var(--text-secondary);
}

.fonts-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 20px;
}

.font-card {
  background-color: var(--bg-secondary);
  padding: 12px;
  border: 1px solid var(--border);
  border-radius: 4px;
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
  word-break: break-word;
  position: relative;
  cursor: pointer;
  transition: box-shadow 0.2s, transform 0.1s;
}

.font-card:hover {
  box-shadow: 0 1px 3px rgba(0,0,0,0.1);
  transform: translateY(-1px);
}

.font-card.dragging {
  opacity: 0.5;
}

.delete-btn {
  position: absolute;
  top: 5px;
  right: 5px;
  background: none;
  border: none;
  color: var(--text-secondary);
  font-size: 18px;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.2s;
}

.font-card:hover .delete-btn {
  opacity: 1;
}

.collections {
  margin-bottom: 20px;
}

.collections h3 {
  margin-bottom: 15px;
  font-size: 18px;
  color: var(--text-primary);
}

.collections ul {
  list-style: none;
}

.collections li {
  padding: 10px 15px;
  background-color: var(--bg-secondary);
  margin-bottom: 8px;
  border-radius: 4px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  transition: background-color 0.2s;
}

.collections li:hover {
  background-color: var(--hover-bg);
}

.collections li span {
  flex: 1;
}

.collections li button {
  background: none;
  border: none;
  color: var(--text-secondary);
  cursor: pointer;
  margin-left: 10px;
  transition: color 0.2s;
}

.collections li button:hover {
  color: var(--text-primary);
}

.download-section {
  padding: 20px;
  background-color: var(--bg-secondary);
  border-top: 1px solid var(--border);
  text-align: center;
}

.download-section button {
  background-color: var(--accent);
  color: #ffffff;
  border: none;
  padding: 12px 25px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 16px;
  transition: background-color 0.2s;
}

.download-section button:hover {
  background-color: #d15a3c;
}

.instructions {
  margin-top: 15px;
  font-size: 14px;
  color: var(--text-secondary);
}

.modal {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0,0,0,0.7);
  display: none;
  align-items: center;
  justify-content: center;
  padding: 20px;
  z-index: 10;
}

.modal-content {
  background-color: var(--modal-bg);
  padding: 30px;
  width: 100%;
  max-width: 500px;
  border-radius: 4px;
  box-shadow: 0 4px 20px rgba(0,0,0,0.2);
  position: relative;
}

.modal-content h3 {
  margin-bottom: 20px;
  font-size: 22px;
  color: var(--text-primary);
}

.modal-content input {
  width: 100%;
  padding: 12px;
  margin-bottom: 20px;
  border: 1px solid var(--border);
  background-color: var(--bg-primary);
  color: var(--text-primary);
  border-radius: 4px;
  font-size: 16px;
}

.modal-content button {
  background-color: var(--accent);
  color: #ffffff;
  border: none;
  padding: 12px 20px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 16px;
  transition: background-color 0.2s;
}

.modal-content button:hover {
  background-color: #d15a3c;
}

.close-modal {
  position: absolute;
  top: 15px;
  right: 20px;
  background: none;
  border: none;
  font-size: 24px;
  cursor: pointer;
  color: var(--text-secondary);
  transition: color 0.2s;
}

.close-modal:hover {
  color: var(--text-primary);
}

.preview-modal-content {
  background-color: var(--modal-bg);
  padding: 40px;
  width: 90%;
  max-width: 700px;
  border-radius: 4px;
  box-shadow: 0 4px 20px rgba(0,0,0,0.3);
  text-align: center;
  position: relative;
}

.preview-modal-content h3 {
  margin-bottom: 25px;
  font-size: 26px;
  color: var(--text-primary);
}

.preview-sample {
  margin-top: 25px;
  padding: 30px;
  border: 1px solid var(--border);
  border-radius: 4px;
  font-size: 28px;
  display: inline-block;
  min-width: 100%;
  word-wrap: break-word;
  color: var(--text-primary);
}

.close-preview-btn {
  position: absolute;
  top: 20px;
  right: 25px;
  background: none;
  border: none;
  font-size: 28px;
  cursor: pointer;
  color: var(--text-secondary);
  transition: color 0.2s;
}

.close-preview-btn:hover {
  color: var(--text-primary);
}

.type-mode-input {
  margin-top: 25px;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.type-mode-input input {
  width: 90%;
  max-width: 500px;
  padding: 12px;
  border: 1px solid var(--border);
  background-color: var(--bg-primary);
  color: var(--text-primary);
  border-radius: 4px;
  font-size: 18px;
}

#ai-organize-btn {
  background-color: #4285f4;
  color: #ffffff;
  border: none;
  padding: 10px 15px;
  border-radius: 4px;
  cursor: pointer;
  margin-top: 10px;
  width: 100%;
  transition: background-color 0.2s, transform 0.1s;
}

#ai-organize-btn:hover {
  background-color: #3367d6;
  transform: translateY(-1px);
}

#ai-progress-bar {
  width: 0%;
  height: 4px;
  background-color: var(--accent);
  margin-top: 10px;
  transition: width 0.3s ease-in-out;
}

#ai-status {
  margin-top: 15px;
  font-size: 14px;
  color: var(--text-secondary);
}

@media (max-width: 768px) {
  .sidebar {
    width: 200px;
  }

  .modal-content, .preview-modal-content {
    padding: 25px;
  }
}

@media (max-width: 480px) {
  .sidebar {
    display: none;
  }

  main {
    flex-direction: column;
  }

  .content {
    padding: 15px;
  }

  .fonts-grid {
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: 15px;
  }

  .preview-modal-content {
    padding: 30px;
  }

  .preview-sample {
    font-size: 24px;
  }
}
</style></head><body>

<header>
  <h1>Font Organizer</h1>
</header>

<div id="app-container">
  <main>
    <div class="sidebar">
      <h2>Collections</h2>
      <ul id="collection-list">
        <!-- Dynamic Collections -->
      </ul>
      <button id="add-collection-btn">+ Add Collection</button>
      <button id="ai-organize-btn">AI Organize</button>
    </div>

    <div class="content">
      <div class="upload-section" id="upload-section">
        <p>Drag &amp; Drop Fonts or ZIP Files Here or Click to Upload</p>
        <input type="file" id="font-input" multiple accept=".ttf,.otf,.woff,.woff2,.eot,.svg,.zip">
      </div>

      <div class="collections" id="current-collection">
        <h3>Select a collection to organize fonts</h3>
      </div>

      <div class="fonts-grid" id="fonts-grid">
        <!-- Uploaded Fonts -->
      </div>
    </div>
  </main>

  <div class="download-section">
    <button id="download-zip-btn">Download Organized Fonts as ZIP</button>
    <div class="instructions" id="instructions" style="display: none;">
      <p>After downloading, right-click the ZIP file and select "Extract All" or use your preferred unzipping tool.</p>
    </div>
  </div>
</div>

<div class="modal" id="modal">
  <div class="modal-content">
    <button class="close-modal" id="close-modal-btn">&times;</button>
    <h3>Add New Collection</h3>
    <input type="text" id="collection-name-input" placeholder="Collection Name">
    <button id="save-collection-btn">Save</button>
  </div>
</div>

<div class="modal" id="ai-modal">
  <div class="modal-content">
    <button class="close-modal" id="close-ai-modal-btn">&times;</button>
    <h3>AI Font Organization</h3>
    <p id="ai-status">Processing fonts...</p>
    <div id="ai-progress-bar"></div>
  </div>
</div>

<div class="modal" id="preview-modal">
  <div class="preview-modal-content">
    <button class="close-preview-btn" id="close-preview-btn">&times;</button>
    <h3 id="preview-font-name">Font Preview</h3>
    <div class="preview-sample" id="preview-sample">
      The quick brown fox jumps over the lazy dog.
    </div>
    <div class="type-mode-input">
      <input type="text" id="custom-text-input" placeholder="Type your custom text here...">
    </div>
  </div>
</div>

<script>
// DOM Elements
const uploadSection = document.getElementById('upload-section');
const fontInput = document.getElementById('font-input');
const fontsGrid = document.getElementById('fonts-grid');
const addCollectionBtn = document.getElementById('add-collection-btn');
const aiOrganizeBtn = document.getElementById('ai-organize-btn');
const aiModal = document.getElementById('ai-modal');
const aiStatus = document.getElementById('ai-status');
const aiProgressBar = document.getElementById('ai-progress-bar');
const closeAiModalBtn = document.getElementById('close-ai-modal-btn');
const modal = document.getElementById('modal');
const saveCollectionBtn = document.getElementById('save-collection-btn');
const collectionNameInput = document.getElementById('collection-name-input');
const collectionList = document.getElementById('collection-list');
const currentCollection = document.getElementById('current-collection');
const downloadZipBtn = document.getElementById('download-zip-btn');
const instructions = document.getElementById('instructions');
const closeModalBtn = document.getElementById('close-modal-btn');

// Preview Modal Elements
const previewModal = document.getElementById('preview-modal');
const closePreviewBtn = document.getElementById('close-preview-btn');
const previewFontName = document.getElementById('preview-font-name');
const previewSample = document.getElementById('preview-sample');
const customTextInput = document.getElementById('custom-text-input');

let fonts = [];
let fontUrls = {}; // To store dynamically generated font URLs
let fontsJSON = {};

// Initialize with Default Collection
let collections = {};
collections['Uncategorized'] = [];
let currentColl = 'Uncategorized';
renderCollections();

// Add this function to check for duplicates
function isDuplicate(newFont) {
    const newNameWithoutExt = newFont.name.split('.').slice(0, -1).join('.');
    return fonts.some(existingFont => {
        const existingNameWithoutExt = existingFont.name.split('.').slice(0, -1).join('.');
        return newNameWithoutExt.toLowerCase() === existingNameWithoutExt.toLowerCase();
    });
}

// Event Listeners for Upload
uploadSection.addEventListener('click', () => {
    fontInput.click();
});

fontInput.addEventListener('change', (e) => {
    handleFiles(e.target.files);
    fontInput.value = ''; // Reset the input
});

// Drag & Drop Events
uploadSection.addEventListener('dragover', (e) => {
    e.preventDefault();
    uploadSection.classList.add('dragover');
});

uploadSection.addEventListener('dragleave', (e) => {
    e.preventDefault();
    uploadSection.classList.remove('dragover');
});

uploadSection.addEventListener('drop', (e) => {
    e.preventDefault();
    uploadSection.classList.remove('dragover');
    if (e.dataTransfer.files) {
        handleFiles(e.dataTransfer.files);
    }
});

// Handle Uploaded Files (Individual Fonts or ZIPs)
async function handleFiles(files) {
    const filesArray = Array.from(files);
    if (filesArray.length === 0) return;

    for (let file of filesArray) {
        if (isFontFile(file.name)) {
            await processFontFile(file);
        } else if (isZipFile(file.name)) {
            await processZipFile(file);
        } else {
            alert(`Unsupported file type: ${file.name}`);
        }
    }
    renderFonts();
}

// Check if a file is a supported font file based on its extension
function isFontFile(fileName) {
    if (!fileName || typeof fileName !== 'string') return false;
    const fontExtensions = ['.ttf', '.otf', '.woff', '.woff2', '.eot', '.svg'];
    return fontExtensions.some(ext => fileName.toLowerCase().endsWith(ext));
}

// Check if a file is a ZIP file based on its extension
function isZipFile(fileName) {
    if (!fileName || typeof fileName !== 'string') return false;
    return fileName.toLowerCase().endsWith('.zip');
}

// Process Individual Font File
async function processFontFile(file) {
    try {
        if (isDuplicate({ name: file.name })) {
            console.log(`Duplicate font skipped: ${file.name}`);
            return;
        }

        const arrayBuffer = await file.arrayBuffer();
        const fontData = {
            id: generateUUID(),
            name: file.name,
            file: file,
            data: arrayBuffer,
            collection: currentColl
        };
        fonts.push(fontData);
        collections[currentColl].push(fontData);

        // Add to JSON structure
        fontsJSON[fontData.id] = {
            name: file.name,
            collection: currentColl,
            type: file.name.split('.').pop().toLowerCase(),
            size: file.size
        };
    } catch (error) {
        console.error(`Error processing font file ${file.name}:`, error);
        alert(`Failed to process font file: ${file.name}`);
    }
}

// Process ZIP File to Extract Fonts
async function processZipFile(file) {
    try {
        const zip = await JSZip.loadAsync(file);
        const fontEntries = [];

        // Iterate through all entries in the ZIP
        zip.forEach((relativePath, zipEntry) => {
            if (!zipEntry.dir && isFontFile(zipEntry.name)) {
                fontEntries.push(zipEntry);
            }
        });

        if (fontEntries.length === 0) {
            alert(`No supported font files found in ZIP: ${file.name}`);
            return;
        }

        // Process all font entries concurrently
        const fontPromises = fontEntries.map(zipEntry => 
            zipEntry.async('blob').then(blob => {
                const extractedFile = new File([blob], getFileName(zipEntry.name), { type: blob.type });
                return processFontFile(extractedFile);
            })
        );

        await Promise.all(fontPromises);

        // Optional: Log successfully extracted fonts
        console.log(`Successfully extracted ${fontEntries.length} font(s) from ${file.name}`);

    } catch (error) {
        console.error(`Error processing ZIP file ${file.name}:`, error);
        alert(`Failed to process ZIP file: ${file.name}`);
    }
}

// Extract File Name from Path (handles both '/' and '\' as separators)
function getFileName(path) {
    if (!path || typeof path !== 'string') return 'unknown-font';
    return path.split('/').pop().split('\\').pop();
}

// Generate UUID for each font (simple UUID generator)
function generateUUID() {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
        const r = Math.random() * 16 | 0;
        const v = c === 'x' ? r : (r & 0x3 | 0x8);
        return v.toString(16);
    });
}

// Render Collections in Sidebar
function renderCollections() {
    collectionList.innerHTML = '';
    for (let coll in collections) {
        const li = document.createElement('li');
        li.textContent = coll;
        if (coll === currentColl) {
            li.classList.add('active');
        }

        // Switch Collection on Click
        li.addEventListener('click', () => {
            currentColl = coll;
            renderCollections();
            renderFonts();
            renderCurrentCollection();
        });
        
        // Add drag and drop functionality to collection items
        li.addEventListener('dragover', (e) => {
            e.preventDefault();
            li.style.backgroundColor = 'var(--hover-bg)';
        });

        li.addEventListener('dragleave', () => {
            li.style.backgroundColor = '';
        });

        li.addEventListener('drop', (e) => {
            e.preventDefault();
            li.style.backgroundColor = '';
            const data = JSON.parse(e.dataTransfer.getData('text/plain'));
            if (data.sourceCollection !== coll) {
                moveFontToCollection(data.fontId, data.sourceCollection, coll);
                renderCollections();
                renderFonts();
            }
        });

        collectionList.appendChild(li);
    }
}

// Render Fonts in Content Area
function renderFonts() {
    fontsGrid.innerHTML = '';
    collections[currentColl].forEach((font) => {
        const card = document.createElement('div');
        card.classList.add('font-card');
        card.draggable = true;
        card.textContent = font.name;
        card.setAttribute('data-id', font.id);

        // Create Delete Button
        const deleteBtn = document.createElement('button');
        deleteBtn.classList.add('delete-btn');
        deleteBtn.innerHTML = '&times;';
        card.appendChild(deleteBtn);

        // Delete Font Event
        deleteBtn.addEventListener('click', (e) => {
            e.stopPropagation(); // Prevent triggering other events
            deleteFont(font.id);
        });

        // Modify the dragstart event
        card.addEventListener('dragstart', (e) => {
            e.dataTransfer.setData('text/plain', JSON.stringify({
                fontId: font.id,
                sourceCollection: currentColl
            }));
            setTimeout(() => {
                card.classList.add('dragging');
            }, 0);
        });

        // ... (keep existing dragend event)

        // Drop Event for Reordering
        card.addEventListener('dragover', (e) => {
            e.preventDefault();
            card.style.borderTop = '2px solid var(--accent)';
        });

        card.addEventListener('dragleave', () => {
            card.style.borderTop = '';
        });

        card.addEventListener('drop', (e) => {
            e.preventDefault();
            card.style.borderTop = '';
            const draggedData = JSON.parse(e.dataTransfer.getData('text/plain'));
            if (draggedData.fontId !== font.id) {
                moveFontToCollection(draggedData.fontId, draggedData.sourceCollection, currentColl);
                renderCollections();
                renderFonts();
            }
        });

        // Double-Click Event for Preview
        card.addEventListener('dblclick', () => {
            toggleFontPreview(font);
        });

        fontsGrid.appendChild(card);
    });
}

// Add this function to move a font between collections
function moveFontToCollection(fontId, sourceCollection, targetCollection) {
    const sourceCollectionFonts = collections[sourceCollection];
    const fontIndex = sourceCollectionFonts.findIndex(font => font.id === fontId);
    
    if (fontIndex !== -1) {
        const [movedFont] = sourceCollectionFonts.splice(fontIndex, 1);
        movedFont.collection = targetCollection;
        collections[targetCollection].push(movedFont);
        
        // Update the fonts array
        const globalFontIndex = fonts.findIndex(font => font.id === fontId);
        if (globalFontIndex !== -1) {
            fonts[globalFontIndex].collection = targetCollection;
        }

        // Update JSON structure
        if (fontsJSON[fontId]) {
            fontsJSON[fontId].collection = targetCollection;
        }
    }
}

// Toggle Font Preview
let currentPreviewFontId = null;

function toggleFontPreview(font) {
    if (currentPreviewFontId === font.id) {
        // Hide Preview
        closePreview();
    } else {
        // Show Preview
        showPreview(font);
    }
}

function showPreview(font) {
    // If another preview is open, close it first
    if (currentPreviewFontId) {
        closePreview();
    }

    currentPreviewFontId = font.id;

    // Generate a Blob URL for the font
    const blob = new Blob([font.file], { type: getMimeType(font.file.name) });
    const fontURL = URL.createObjectURL(blob);
    fontUrls[font.id] = fontURL;

    // Create @font-face dynamically
    const fontFace = `
        @font-face {
            font-family: 'preview-${font.id}';
            src: url('${fontURL}') format('${getFontFormat(font.file.name)}');
        }
    `;

    // Append to head
    const style = document.createElement('style');
    style.id = `font-style-${font.id}`;
    style.innerHTML = fontFace;
    document.head.appendChild(style);

    // Apply font to preview sample
    previewSample.style.fontFamily = `'preview-${font.id}'`;
    previewSample.textContent = 'The quick brown fox jumps over the lazy dog.';
    previewFontName.textContent = font.name;

    // Show Modal and Blur Background
    previewModal.style.display = 'flex';
    document.getElementById('app-container').classList.add('blurred');

    // Set focus to custom text input
    customTextInput.value = '';
    customTextInput.focus();
}

function closePreview() {
    if (currentPreviewFontId) {
        // Remove @font-face
        const style = document.getElementById(`font-style-${currentPreviewFontId}`);
        if (style) {
            style.remove();
        }

        // Revoke Object URL
        if (fontUrls[currentPreviewFontId]) {
            URL.revokeObjectURL(fontUrls[currentPreviewFontId]);
            delete fontUrls[currentPreviewFontId];
        }

        currentPreviewFontId = null;
    }

    // Reset preview sample
    previewSample.style.fontFamily = '';
    previewSample.textContent = 'The quick brown fox jumps over the lazy dog.';
    previewFontName.textContent = 'Font Preview';

    // Hide Modal and Remove Blur
    previewModal.style.display = 'none';
    document.getElementById('app-container').classList.remove('blurred');

    // Clear custom text input
    customTextInput.value = '';
}

// Utility to get MIME type based on file extension
function getMimeType(filename) {
    if (!filename || typeof filename !== 'string') return 'application/octet-stream';
    const ext = filename.split('.').pop().toLowerCase();
    const mimeTypes = {
        'ttf': 'font/ttf',
        'otf': 'font/otf',
        'woff': 'font/woff',
        'woff2': 'font/woff2',
        'eot': 'application/vnd.ms-fontobject',
        'svg': 'image/svg+xml'
    };
    return mimeTypes[ext] || 'application/octet-stream';
}

// Utility to get font format
function getFontFormat(filename) {
    if (!filename || typeof filename !== 'string') return 'truetype';
    const ext = filename.split('.').pop().toLowerCase();
    const formats = {
        'ttf': 'truetype',
        'otf': 'opentype',
        'woff': 'woff',
        'woff2': 'woff2',
        'eot': 'embedded-opentype',
        'svg': 'svg'
    };
    return formats[ext] || 'truetype';
}

// Close Preview Modal Event
closePreviewBtn.addEventListener('click', () => {
    closePreview();
});

// Close Preview Modal when clicking outside content
previewModal.addEventListener('click', (e) => {
    if (e.target === previewModal) {
        closePreview();
    }
});

// Handle Custom Text Input for Type Mode
customTextInput.addEventListener('input', (e) => {
    const text = e.target.value.trim() || 'The quick brown fox jumps over the lazy dog.';
    previewSample.textContent = text;
});

// Render Current Collection Info
function renderCurrentCollection() {
    currentCollection.innerHTML = '';
    if (currentColl === 'Uncategorized') {
        currentCollection.innerHTML = '<h3>Uncategorized Fonts</h3>';
    } else {
        const heading = document.createElement('h3');
        heading.textContent = `Collection: ${currentColl}`;
        currentCollection.appendChild(heading);
    }
}

// Add Collection
addCollectionBtn.addEventListener('click', () => {
    modal.style.display = 'flex';
    collectionNameInput.value = '';
    collectionNameInput.focus();
});

saveCollectionBtn.addEventListener('click', () => {
    const name = collectionNameInput.value.trim();
    if (name && !collections[name]) {
        collections[name] = [];
        currentColl = name;
        renderCollections();
        renderFonts();
        renderCurrentCollection();
        modal.style.display = 'none';
    } else if (collections[name]) {
        alert('Collection name already exists.');
    } else {
        alert('Please enter a valid collection name.');
    }
});

// AI Organize
async function organizeFontsWithAI() {
    aiModal.style.display = 'flex';
    aiStatus.textContent = 'Processing fonts...';
    aiProgressBar.style.width = '0%';

    const API_KEY = '<TRUFFLEHOG_REDACTED_GROQ>';
    const API_URL = 'https://api.groq.com/openai/v1/chat/completions';

    try {
        const prompt = `Analyze the following JSON object representing a collection of fonts. Each font object contains properties like name, type, and size. Based on these properties, create meaningful categories for the fonts. Consider factors such as font style (serif, sans-serif, script, display), weight, purpose (body text, headlines, decorative), and any other relevant characteristics you can infer from the names and metadata. Return the result as a JSON object where keys are category names and values are arrays of font IDs. Here's the font data:

        ${JSON.stringify(fontsJSON, null, 2)}

        Provide your categorization in the following format:
        {
          "category1": ["fontId1", "fontId2"],
          "category2": ["fontId3", "fontId4"],
          ...
        }
        Do not include any explanations or markdown formatting in your response, just the JSON object.`;

        const response = await fetch(API_URL, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'Authorization': `Bearer ${API_KEY}`,
            },
            body: JSON.stringify({
                model: "llama-3.1-70b-versatile",
                messages: [
                    { role: "system", content: "You are an AI assistant that specializes in font categorization." },
                    { role: "user", content: prompt }
                ],
      
            })
        });

        if (!response.ok) {
            throw new Error('API request failed');
        }

        const data = await response.json();
        let aiResponse = data.choices[0].message.content;

        // Parse the AI response
        let aiCategories = JSON.parse(aiResponse);

        // Create new collections and organize fonts
        Object.entries(aiCategories).forEach(([category, fontIds]) => {
            if (!collections[category]) {
                collections[category] = [];
            }
            fontIds.forEach(fontId => {
                const font = fonts.find(f => f.id === fontId);
                if (font) {
                    moveFontToCollection(font.id, font.collection, category);
                    fontsJSON[fontId].collection = category; // Update JSON structure
                }
            });
        });

        aiStatus.textContent = 'Font organization complete!';
        aiProgressBar.style.width = '100%';

        // Update UI
        renderCollections();
        renderFonts();
        renderCurrentCollection();

        setTimeout(() => {
            aiModal.style.display = 'none';
        }, 2000);

    } catch (error) {
        console.error('Error organizing fonts with AI:', error);
        aiStatus.textContent = 'Error organizing fonts. Please try again.';
    }
}

// Add event listener for AI Organize button
aiOrganizeBtn.addEventListener('click', organizeFontsWithAI);

// Close AI Modal when clicking outside content or on close button
closeAiModalBtn.addEventListener('click', () => {
    aiModal.style.display = 'none';
});

window.addEventListener('click', (e) => {
    if (e.target === modal) {
        modal.style.display = 'none';
    }
    if (e.target === aiModal) {
        aiModal.style.display = 'none';
    }
});

// Delete Font from Collection
function deleteFont(fontId) {
    // Find the collection containing this font
    for (let coll in collections) {
        const index = collections[coll].findIndex(font => font.id === fontId);
        if (index !== -1) {
            // Remove from fonts array
            fonts = fonts.filter(font => font.id !== fontId);
            // Remove from collection
            collections[coll].splice(index, 1);
            // Remove from JSON structure
            delete fontsJSON[fontId];
            break;
        }
    }
    renderFonts();
}

// Download ZIP
downloadZipBtn.addEventListener('click', async () => {
    if (fonts.length === 0) {
        alert('No fonts to download.');
        return;
    }

    const zip = new JSZip();

    // Supported font extensions
    const supportedExtensions = ['.ttf', '.otf', '.woff', '.woff2', '.eot', '.svg'];

    // Create a set to track unique file names to avoid duplicates in the ZIP
    const fileNamesSet = new Set();

    fonts.forEach((font) => {
        const ext = '.' + font.name.split('.').pop().toLowerCase();
        if (supportedExtensions.includes(ext)) {
            let uniqueName = font.name;
            // Ensure unique file names in the ZIP
            let counter = 1;
            while (fileNamesSet.has(uniqueName)) {
                const nameWithoutExt = font.name.substring(0, font.name.lastIndexOf('.')) || font.name;
                uniqueName = `${nameWithoutExt} (${counter})${ext}`;
                counter++;
            }
            fileNamesSet.add(uniqueName);
            zip.file(uniqueName, font.file);
        }
    });

    try {
        const content = await zip.generateAsync({ type: "blob" });
        const a = document.createElement('a');
        a.href = URL.createObjectURL(content);
        a.download = "organized_fonts.zip";
        a.click();

        instructions.style.display = 'block';
        setTimeout(() => {
            instructions.style.display = 'none';
        }, 5000);
    } catch (error) {
        console.error('Error generating ZIP:', error);
        alert('There was an error generating the ZIP file.');
    }
});

// Initial Render
renderFonts();
renderCurrentCollection();
</script>

</body></html>