/**
 * Sidebar UI Controller
 *
 * Manages the extension sidebar interface including project browsing,
 * file selection, and download management.
 */

console.log('[Sidebar] Script loaded - VERY FIRST LINE');

import { MESSAGE_TYPES, CONNECTION_STATE } from '../lib/constants.js';
import { isFeatureEnabled } from '../lib/feature-flags.js';
import { SessionManager } from './session-manager.js';

console.log('[Sidebar] Imports complete - constants loaded');

class SidebarController {
  constructor() {
    this.state = {
      connectionState: CONNECTION_STATE.DISCONNECTED,
      auth: null,
      projects: [],
      selectedProject: null,
      currentFolder: null,
      folderPath: [], // Array of { id, name } for breadcrumb navigation
      documents: [],
      folders: [], // Array of folder objects
      downloads: { queue: [], active: [] },
      showDownloads: false
    };

    this.elements = {};
    this.debounceTimer = null;
    this.sessionManager = null; // Will be initialized after cacheElements
  }

  /**
   * Initialize the sidebar
   */
  async init() {
    console.log('[Sidebar] Initializing sidebar...');
    this.cacheElements();
    this.sessionManager = new SessionManager(this.elements); // Initialize session manager
    this.applyFeatureFlags();
    this.attachEventListeners();
    await this.checkAuthState();
    this.listenForMessages();

    // Re-check auth state when sidebar becomes visible (handles late auth detection)
    document.addEventListener('visibilitychange', () => {
      if (!document.hidden) {
        console.log('[Sidebar] Sidebar became visible, re-checking auth state...');
        this.checkAuthState();
      }
    });

    // Check for current project and auto-load if found
    await this.checkCurrentProject();
    console.log('[Sidebar] Sidebar initialization complete');
  }
  
  /**
   * Check if user is currently viewing a project in Filevine and auto-load it
   */
  async checkCurrentProject() {
    try {
      const response = await chrome.runtime.sendMessage({
        type: MESSAGE_TYPES.GET_CURRENT_PROJECT
      });

      // Handle project type page context (for auto-filling forms)
      if (response?.projectTypeId && response?.orgId) {
        console.log('[Sidebar] Detected project type page on load');
        this.handlePageContextUpdate(response);
      }

      if (response?.projectId) {
        console.log('[Sidebar] Found current project:', response.projectId);
        // Auto-load this project
        await this.selectProject(response.projectId);
      } else {
        console.log('[Sidebar] No current project detected, showing project list');
      }
    } catch (error) {
      console.error('[Sidebar] Failed to check current project:', error);
      // Continue normally - show project list
    }
  }

  /**
   * Cache DOM element references
   */
  cacheElements() {
    this.elements = {
      connectionStatus: document.getElementById('connection-status'),
      statusText: document.querySelector('.status-text'),
      connectionPanel: document.getElementById('connection-panel'),
      retryConnectionBtn: document.getElementById('retry-connection-btn'),
      clearCacheBtn: document.getElementById('clear-cache-btn'),
      mainPanel: document.getElementById('main-panel'),
      downloadPanel: document.getElementById('download-panel'),
      orgSelector: document.getElementById('org-selector'),
      orgSelect: document.getElementById('org-select'),
      projectSearch: document.getElementById('project-search'),
      refreshBtn: document.getElementById('refresh-btn'),
      projectList: document.getElementById('project-list'),
      fileBrowser: document.getElementById('file-browser'),
      backToProjects: document.getElementById('back-to-projects'),
      currentProjectName: document.getElementById('current-project-name'),
      fileList: document.getElementById('file-list'),
      downloadList: document.getElementById('download-list'),
      toggleDownloads: document.getElementById('toggle-downloads'),
      downloadCount: document.getElementById('download-count'),
      clearDownloads: document.getElementById('clear-downloads'),
      settingsBtn: document.getElementById('settings-btn'),
      // Session management elements
      sessionInfo: document.getElementById('session-info'),
      sessionUserEmail: document.getElementById('session-user-email'),
      sessionOrgName: document.getElementById('session-org-name'),
      toggleSessions: document.getElementById('toggle-sessions'),
      sessionCountBadge: document.getElementById('session-count-badge'),
      activeSessionsList: document.getElementById('active-sessions-list'),
      sessionsContainer: document.getElementById('sessions-container'),
      refreshSessions: document.getElementById('refresh-sessions')
    };
  }

  /**
   * Apply feature flags to hide/show features
   */
  applyFeatureFlags() {
    console.log('[Sidebar] Applying feature flags...');

    // Hide Customs Editor tab if disabled
    if (!isFeatureEnabled('CUSTOMS_EDITOR_ENABLED')) {
      const customsTabBtn = document.getElementById('customs-tab-btn');
      const customsTabContent = document.getElementById('customs-tab');

      if (customsTabBtn) {
        customsTabBtn.style.display = 'none';
        console.log('[Sidebar] Customs Editor tab hidden');
      }
      if (customsTabContent) {
        customsTabContent.style.display = 'none';
      }
    }

    console.log('[Sidebar] Feature flags applied');
  }

  /**
   * Attach event listeners
   */
  attachEventListeners() {
    // Tab switching
    document.querySelectorAll('.tab-btn').forEach(btn => {
      btn.addEventListener('click', (e) => {
        const targetTab = e.target.dataset.tab;
        this.switchTab(targetTab);
      });
    });

    // Retry connection button
    this.elements.retryConnectionBtn?.addEventListener('click', async () => {
      console.log('[Sidebar] Retry connection button clicked');
      this.elements.retryConnectionBtn.textContent = 'Checking...';
      this.elements.retryConnectionBtn.disabled = true;
      await this.checkAuthState();
      this.elements.retryConnectionBtn.textContent = 'Check Connection';
      this.elements.retryConnectionBtn.disabled = false;
    });

    // Clear cache button
    this.elements.clearCacheBtn?.addEventListener('click', async () => {
      console.log('[Sidebar] Clear cache button clicked');
      this.elements.clearCacheBtn.textContent = 'Clearing...';
      this.elements.clearCacheBtn.disabled = true;

      try {
        // Send logout message to clear auth from background
        await chrome.runtime.sendMessage({ type: 'logout' });
        console.log('[Sidebar] Auth cleared from background');

        // Clear local state
        this.state.auth = null;
        this.state.connectionState = CONNECTION_STATE.DISCONNECTED;
        this.updateConnectionUI();

        // Wait a moment then recheck
        setTimeout(async () => {
          console.log('[Sidebar] Rechecking auth after cache clear...');
          await this.checkAuthState();
          this.elements.clearCacheBtn.textContent = 'Clear Cache';
          this.elements.clearCacheBtn.disabled = false;
        }, 1000);
      } catch (error) {
        console.error('[Sidebar] Failed to clear cache:', error);
        this.elements.clearCacheBtn.textContent = 'Clear Cache';
        this.elements.clearCacheBtn.disabled = false;
      }
    });

    // Project search
    this.elements.projectSearch?.addEventListener('input', (e) => {
      this.debounce(() => this.searchProjects(e.target.value), 300);
    });

    // Refresh button
    this.elements.refreshBtn?.addEventListener('click', () => {
      this.loadProjects();
    });

    // Back to projects
    this.elements.backToProjects?.addEventListener('click', () => {
      this.showProjectList();
    });

    // Org selector
    this.elements.orgSelect?.addEventListener('change', (e) => {
      this.switchOrg(e.target.value);
    });

    // Toggle downloads panel
    this.elements.toggleDownloads?.addEventListener('click', () => {
      this.toggleDownloadsPanel();
    });

    // Clear downloads
    this.elements.clearDownloads?.addEventListener('click', () => {
      this.clearDownloads();
    });

    // Custom field form
    const customFieldForm = document.getElementById('custom-field-form');
    if (customFieldForm) {
      customFieldForm.addEventListener('submit', async (e) => {
        e.preventDefault();
        await this.handleCustomFieldSubmit(e);
      });
    }

    // Close result button
    const closeResultBtn = document.getElementById('close-result');
    if (closeResultBtn) {
      closeResultBtn.addEventListener('click', () => {
        document.getElementById('field-result').classList.add('hidden');
      });
    }

    // Load sections button
    const loadSectionsBtn = document.getElementById('load-sections-btn');
    if (loadSectionsBtn) {
      loadSectionsBtn.addEventListener('click', async () => {
        await this.loadCustomSections();
      });
    }

    // AI Builder form
    const aiBuilderForm = document.getElementById('ai-builder-form');
    if (aiBuilderForm) {
      aiBuilderForm.addEventListener('submit', async (e) => {
        e.preventDefault();
        await this.handleAIBuilderSubmit(e);
      });
    }

    // AI Load sections button
    const aiLoadSectionsBtn = document.getElementById('ai-load-sections-btn');
    if (aiLoadSectionsBtn) {
      aiLoadSectionsBtn.addEventListener('click', async () => {
        await this.loadAISections();
      });
    }

    // Schema Viewer form
    const schemaViewerForm = document.getElementById('schema-viewer-form');
    if (schemaViewerForm) {
      schemaViewerForm.addEventListener('submit', async (e) => {
        e.preventDefault();
        await this.handleSchemaViewerSubmit(e);
      });
    }

    // Schema Load sections button
    const schemaLoadSectionsBtn = document.getElementById('schema-load-sections-btn');
    if (schemaLoadSectionsBtn) {
      schemaLoadSectionsBtn.addEventListener('click', async () => {
        await this.loadSchemaSections();
      });
    }

    // Preview action buttons
    const createFieldsBtn = document.getElementById('create-fields-btn');
    if (createFieldsBtn) {
      createFieldsBtn.addEventListener('click', async () => {
        await this.handleCreateFieldsFromPreview();
      });
    }

    const cancelPreviewBtn = document.getElementById('cancel-preview-btn');
    if (cancelPreviewBtn) {
      cancelPreviewBtn.addEventListener('click', () => {
        this.hideFieldPreview();
      });
    }
  }

  /**
   * Check authentication state
   */
  async checkAuthState() {
    try {
      console.log('[Sidebar] Checking auth state...');
      const response = await chrome.runtime.sendMessage({
        type: MESSAGE_TYPES.GET_AUTH_STATE
      });

      console.log('[Sidebar] Auth state response:', response);
      console.log('[Sidebar] Authenticated:', response?.authenticated);
      console.log('[Sidebar] Auth data:', response?.auth);

      if (response?.authenticated) {
        console.log('[Sidebar] User is authenticated, setting up UI...');
        this.state.connectionState = CONNECTION_STATE.CONNECTED;
        this.state.auth = response.auth;
        this.updateConnectionUI();
        this.setupOrgSelector();
        // Load projects but don't auto-select yet - checkCurrentProject will handle that
        await this.loadProjects();
      } else {
        console.log('[Sidebar] User not authenticated, showing connection panel');
        this.state.connectionState = response?.state || CONNECTION_STATE.DISCONNECTED;
        this.updateConnectionUI();
      }
    } catch (error) {
      console.error('[Sidebar] Failed to check auth state:', error);
      this.state.connectionState = CONNECTION_STATE.ERROR;
      this.updateConnectionUI();
    }
  }

  /**
   * Switch between tabs
   */
  switchTab(tabName) {
    console.log('[Sidebar] Switching to tab:', tabName);

    // Update tab buttons
    document.querySelectorAll('.tab-btn').forEach(btn => {
      if (btn.dataset.tab === tabName) {
        btn.classList.add('active');
      } else {
        btn.classList.remove('active');
      }
    });

    // Update tab content
    document.querySelectorAll('.tab-content').forEach(content => {
      if (content.id === `${tabName}-tab`) {
        content.classList.add('active');
      } else {
        content.classList.remove('active');
      }
    });

    // Pre-populate custom field form when switching to customs tab
    if (tabName === 'customs') {
      this.prepopulateCustomFieldForm();
    }
  }

  /**
   * Pre-populate custom field form with org ID and project type ID
   */
  async prepopulateCustomFieldForm() {
    console.log('[Sidebar] Pre-populating custom field forms');

    // Populate manual form
    const orgIdInput = document.getElementById('org-id');
    const projectTypeIdInput = document.getElementById('project-type-id');

    // Populate AI form
    const aiOrgIdInput = document.getElementById('ai-org-id');
    const aiProjectTypeIdInput = document.getElementById('ai-project-type-id');

    // Get org ID from auth state
    if (this.state.auth?.orgId) {
      if (orgIdInput && !orgIdInput.value) {
        orgIdInput.value = this.state.auth.orgId;
      }
      if (aiOrgIdInput && !aiOrgIdInput.value) {
        aiOrgIdInput.value = this.state.auth.orgId;
      }
      console.log('[Sidebar] Set org ID:', this.state.auth.orgId);
    }

    // Get project type ID from current project
    if (this.state.selectedProject) {
      try {
        // Fetch project details to get project type ID
        const response = await chrome.runtime.sendMessage({
          type: 'get_project',
          projectId: this.state.selectedProject.projectId
        });

        if (response?.projectTypeId) {
          if (projectTypeIdInput && !projectTypeIdInput.value) {
            projectTypeIdInput.value = response.projectTypeId.native;
          }
          if (aiProjectTypeIdInput && !aiProjectTypeIdInput.value) {
            aiProjectTypeIdInput.value = response.projectTypeId.native;
          }
          console.log('[Sidebar] Set project type ID:', response.projectTypeId.native);

          // Optionally auto-load sections if both fields are populated
          if (orgIdInput?.value && projectTypeIdInput?.value) {
            this.showNotification('Auto-loading sections...', 'info', 2000);
            await this.loadCustomSections();
          }
        }
      } catch (error) {
        console.error('[Sidebar] Failed to get project type ID:', error);
      }
    }
  }

  /**
   * Update connection status UI
   */
  updateConnectionUI() {
    const { connectionStatus, statusText, connectionPanel, mainPanel } = this.elements;

    // Update status indicator
    connectionStatus.className = `status ${this.state.connectionState}`;

    const statusMessages = {
      [CONNECTION_STATE.DISCONNECTED]: 'Disconnected',
      [CONNECTION_STATE.DETECTING]: 'Detecting...',
      [CONNECTION_STATE.CONNECTED]: 'Connected',
      [CONNECTION_STATE.ERROR]: 'Error'
    };
    statusText.textContent = statusMessages[this.state.connectionState] || 'Unknown';

    // Show appropriate panel
    if (this.state.connectionState === CONNECTION_STATE.CONNECTED) {
      connectionPanel.classList.add('hidden');
      mainPanel.classList.remove('hidden');

      // Update session info display
      if (this.sessionManager && this.state.auth) {
        this.sessionManager.updateSessionInfo(this.state.auth);
      }
    } else {
      connectionPanel.classList.remove('hidden');
      mainPanel.classList.add('hidden');

      // Hide session info when disconnected
      if (this.sessionManager) {
        this.sessionManager.hideSessionInfo();
      }
    }
  }

  /**
   * Setup org selector for multi-org users
   */
  setupOrgSelector() {
    const { orgSelector, orgSelect } = this.elements;
    const orgs = this.state.auth?.orgs || [];

    if (orgs.length > 1) {
      orgSelect.innerHTML = orgs.map(org => 
        `<option value="${org.orgId}" ${org.orgId === this.state.auth.orgId ? 'selected' : ''}>
          ${org.name || org.orgId}
        </option>`
      ).join('');
      orgSelector.classList.remove('hidden');
    } else {
      orgSelector.classList.add('hidden');
    }
  }

  /**
   * Load projects from API
   */
  async loadProjects(search = '') {
    const { projectList } = this.elements;
    projectList.innerHTML = '<div class="loading">Loading projects...</div>';

    try {
      console.log('[Sidebar] Requesting projects, search:', search);
      const response = await chrome.runtime.sendMessage({
        type: MESSAGE_TYPES.GET_PROJECTS,
        search,
        limit: 100  // Request more projects
      });

      console.log('[Sidebar] Projects response:', response);
      console.log('[Sidebar] Response type:', typeof response);
      console.log('[Sidebar] Response keys:', response ? Object.keys(response) : 'null');
      
      // Handle different response formats
      let projects = [];
      if (response) {
        if (response.items && Array.isArray(response.items)) {
          projects = response.items;
        } else if (Array.isArray(response)) {
          projects = response;
        } else if (response.data && Array.isArray(response.data)) {
          projects = response.data;
        }
      }
      
      console.log('[Sidebar] Extracted projects:', projects.length);
      this.state.projects = projects;
      this.renderProjectList();
    } catch (error) {
      console.error('[Sidebar] Failed to load projects:', error);
      projectList.innerHTML = `<div class="empty">Failed to load projects: ${error.message}</div>`;
    }
  }

  /**
   * Search projects
   */
  searchProjects(query) {
    this.loadProjects(query);
  }

  /**
   * Render project list
   */
  renderProjectList() {
    const { projectList } = this.elements;
    
    if (!this.state.projects.length) {
      projectList.innerHTML = '<div class="empty">No projects found</div>';
      return;
    }

    projectList.innerHTML = this.state.projects.map(project => {
      // Handle different field names from Filevine API
      const projectId = project.projectID || project.projectId || project.id;
      const projectName = project.projectName || project.name || 'Unnamed';
      const projectType = project.projectTypeName || project.projectType || project.type || '';
      
      return `
        <div class="list-item" data-project-id="${projectId}">
          <span class="icon">📁</span>
          <div class="info">
            <div class="name">${this.escapeHtml(projectName)}</div>
            <div class="meta">${this.escapeHtml(projectType)}</div>
          </div>
        </div>
      `;
    }).join('');

    // Attach click handlers
    projectList.querySelectorAll('.list-item').forEach(item => {
      item.addEventListener('click', () => {
        const projectId = item.dataset.projectId;
        this.selectProject(projectId);
      });
    });
  }

  /**
   * Select a project and show its documents
   * @param {string|number} projectId - Project ID to select
   * @param {object} projectData - Optional project data (if not provided, will try to find in loaded projects)
   */
  async selectProject(projectId, projectData = null) {
    // Try to find project in loaded list first
    let project = projectData || this.state.projects.find(
      p => String(p.projectID || p.projectId || p.id) === String(projectId)
    );
    
    // If project not found in list, create a minimal project object
    if (!project) {
      console.log('[Sidebar] Project not in loaded list, creating project object for:', projectId);
      project = {
        projectID: projectId,
        projectId: projectId,
        id: projectId,
        projectName: `Project ${projectId}`,
        name: `Project ${projectId}`
      };
    }

    console.log('[Sidebar] Selecting project:', project);
    this.state.selectedProject = project;
    this.state.currentFolder = null;
    this.state.folderPath = [];
    this.elements.currentProjectName.textContent = project.projectName || project.name || `Project ${projectId}`;
    
    // Show file browser
    this.elements.fileBrowser.classList.remove('hidden');
    document.querySelector('.browser:not(#file-browser)').classList.add('hidden');
    
    // Use projectID from the project object
    const actualProjectId = project.projectID || project.projectId || project.id;
    await this.loadDocuments(actualProjectId);
  }

  /**
   * Show project list
   */
  showProjectList() {
    this.state.selectedProject = null;
    this.state.currentFolder = null;
    this.state.folderPath = [];
    this.elements.fileBrowser.classList.add('hidden');
    document.querySelector('.browser:not(#file-browser)').classList.remove('hidden');
  }

  /**
   * Load documents and folders for a project
   */
  async loadDocuments(projectId, folderID = null) {
    const { fileList } = this.elements;
    fileList.innerHTML = '<div class="loading">Loading...</div>';

    try {
      console.log('[Sidebar] Loading documents for project:', projectId, 'folderID:', folderID);
      
      // Load documents
      const docsResponse = await chrome.runtime.sendMessage({
        type: MESSAGE_TYPES.GET_PROJECT_DOCS,
        projectId: String(projectId),
        folderID: folderID,
        limit: 100,
        offset: 0
      });

      console.log('[Sidebar] Documents response:', docsResponse);
      
      // Handle different response formats
      let documents = [];
      if (docsResponse) {
        if (docsResponse.items && Array.isArray(docsResponse.items)) {
          documents = docsResponse.items;
        } else if (Array.isArray(docsResponse)) {
          documents = docsResponse;
        } else if (docsResponse.data && Array.isArray(docsResponse.data)) {
          documents = docsResponse.data;
        }
      }
      
      // Load folder tree to get subfolders
      let folders = [];
      try {
        // First get basic folder tree to find root folder ID
        const basicFolderTreeResponse = await chrome.runtime.sendMessage({
          type: MESSAGE_TYPES.GET_FOLDER_TREE,
          projectId: String(projectId)
        });
        
        // Then request with descendantFolderIDs to get folder names
        // Include root folder and current folder (if not root) to get all folder names
        const rootFolderID = basicFolderTreeResponse?.rootFolderID;
        const currentFolderID = folderID || rootFolderID;
        const descendantFolderIDs = [rootFolderID];
        if (currentFolderID && currentFolderID !== rootFolderID) {
          descendantFolderIDs.push(currentFolderID);
        }
        
        // Get child folder IDs to include in request
        const childFolderIDs = basicFolderTreeResponse?.childrenLookup?.[String(currentFolderID)] || 
                              basicFolderTreeResponse?.childrenLookup?.[currentFolderID] || 
                              [];
        if (childFolderIDs.length > 0) {
          descendantFolderIDs.push(...childFolderIDs.slice(0, 30)); // Include up to 30 child folders
        }
        
        console.log('[Sidebar] Requesting folder tree with descendantFolderIDs:', descendantFolderIDs);
        
        const folderTreeResponse = await chrome.runtime.sendMessage({
          type: MESSAGE_TYPES.GET_FOLDER_TREE,
          projectId: String(projectId),
          descendantFolderIDs: descendantFolderIDs
        });
        
        console.log('[Sidebar] Folder tree response:', folderTreeResponse);
        
        if (folderTreeResponse && folderTreeResponse.childrenLookup) {
          // Get folders for current folder (or root)
          // childrenLookup uses string keys, so convert to string
          const currentFolderID = folderID || folderTreeResponse.rootFolderID;
          const currentFolderIDStr = String(currentFolderID);
          
          // Try both string and number keys
          const childFolderIDs = folderTreeResponse.childrenLookup[currentFolderIDStr] || 
                                 folderTreeResponse.childrenLookup[currentFolderID] || 
                                 [];
          
          console.log('[Sidebar] Current folder ID:', currentFolderID, '(string:', currentFolderIDStr + ')');
          console.log('[Sidebar] Child folder IDs:', childFolderIDs);
          console.log('[Sidebar] Children lookup keys:', Object.keys(folderTreeResponse.childrenLookup));
          console.log('[Sidebar] Folder lookup available:', !!folderTreeResponse.folderLookup);
          
          // Log folderLookup structure for debugging
          if (folderTreeResponse.folderLookup) {
            const folderLookupKeys = Object.keys(folderTreeResponse.folderLookup);
            console.log('[Sidebar] Folder lookup keys:', folderLookupKeys.slice(0, 10), '... (showing first 10)');
            if (folderLookupKeys.length > 0) {
              const firstKey = folderLookupKeys[0];
              const firstFolder = folderTreeResponse.folderLookup[firstKey];
              console.log('[Sidebar] Sample folder structure (key:', firstKey, '):', firstFolder);
              console.log('[Sidebar] Sample folder properties:', Object.keys(firstFolder || {}));
            }
          }
          
          // Strategy 1: Extract folder names from current documents and check for DICOM files
          const folderNamesFromDocs = {};
          const folderDicomMap = {}; // Map of folderId -> hasDicomFiles
          
          documents.forEach(doc => {
            if (doc.folderID && doc.folderName) {
              folderNamesFromDocs[doc.folderID] = doc.folderName;
              folderNamesFromDocs[String(doc.folderID)] = doc.folderName;
            }
            
            // Check if this document is a DICOM file
            const filename = (doc.filename || doc.name || '').toLowerCase();
            const mimeType = (doc.mimeType || doc.contentType || '').toLowerCase();
            const isDicom = filename.endsWith('.dcm') || 
                           filename.endsWith('.dicom') ||
                           mimeType === 'application/dicom';
            
            if (isDicom && doc.folderID) {
              folderDicomMap[doc.folderID] = true;
              folderDicomMap[String(doc.folderID)] = true;
            }
          });
          
          // Strategy 2: If at root, fetch ALL documents from root to build complete folder name map
          // This is more efficient than fetching each folder individually
          if (currentFolderID === folderTreeResponse.rootFolderID) {
            try {
              console.log('[Sidebar] Fetching all root documents to build folder name map...');
              const rootDocsResponse = await chrome.runtime.sendMessage({
                type: MESSAGE_TYPES.GET_PROJECT_DOCS,
                projectId: String(projectId),
                folderID: folderTreeResponse.rootFolderID,
                limit: 500, // Get many documents to cover all folders
                offset: 0
              });
              
              let rootDocs = [];
              if (rootDocsResponse) {
                if (rootDocsResponse.items && Array.isArray(rootDocsResponse.items)) {
                  rootDocs = rootDocsResponse.items;
                } else if (Array.isArray(rootDocsResponse)) {
                  rootDocs = rootDocsResponse;
                } else if (rootDocsResponse.data && Array.isArray(rootDocsResponse.data)) {
                  rootDocs = rootDocsResponse.data;
                }
              }
              
              // Build folder name map and DICOM detection from all documents
              rootDocs.forEach(doc => {
                if (doc.folderID && doc.folderName) {
                  folderNamesFromDocs[doc.folderID] = doc.folderName;
                  folderNamesFromDocs[String(doc.folderID)] = doc.folderName;
                }
                
                // Check if this document is a DICOM file
                const filename = (doc.filename || doc.name || '').toLowerCase();
                const mimeType = (doc.mimeType || doc.contentType || '').toLowerCase();
                const isDicom = filename.endsWith('.dcm') || 
                               filename.endsWith('.dicom') ||
                               mimeType === 'application/dicom';
                
                if (isDicom && doc.folderID) {
                  folderDicomMap[doc.folderID] = true;
                  folderDicomMap[String(doc.folderID)] = true;
                }
              });
              
              console.log('[Sidebar] Built folder name map from', rootDocs.length, 'root documents');
              console.log('[Sidebar] Folders with DICOM files:', Object.keys(folderDicomMap).filter(k => folderDicomMap[k]));
            } catch (error) {
              console.warn('[Sidebar] Could not fetch root documents for folder names:', error);
            }
          }
          
          // Strategy 3: For folders still without names, fetch one document from each folder
          // Only do this for folders we haven't found names for yet
          const foldersWithNames = await Promise.all(
            childFolderIDs.map(async (folderId) => {
              const folderIdStr = String(folderId);
              let folderName = null;
              // Check if we already know this folder has DICOM files from root scan
              let hasDicomFiles = folderDicomMap && (folderDicomMap[folderId] || folderDicomMap[folderIdStr]) || false;
              
              // Strategy 1: Try folderNameMap from folderTree (when descendantFolderIDs is provided)
              if (folderTreeResponse.folderNameMap) {
                folderName = folderTreeResponse.folderNameMap[folderId] || folderTreeResponse.folderNameMap[folderIdStr];
                if (folderName) {
                  console.log('[Sidebar] Got folder name from folderNameMap for', folderId, ':', folderName);
                }
              }
              
              // Strategy 2: Try folderLookup (usually empty)
              if (!folderName && folderTreeResponse.folderLookup && Object.keys(folderTreeResponse.folderLookup).length > 0) {
                const folderDetails = folderTreeResponse.folderLookup[folderIdStr] || 
                                    folderTreeResponse.folderLookup[folderId];
                if (folderDetails) {
                  folderName = folderDetails.folderName || folderDetails.name || folderDetails.folder_name;
                  if (folderName) {
                    console.log('[Sidebar] Got folder name from folderLookup for', folderId, ':', folderName);
                  }
                }
              }
              
              // Strategy 3: Try folder names from documents (current + root)
              if (!folderName) {
                folderName = folderNamesFromDocs[folderId] || folderNamesFromDocs[folderIdStr];
                if (folderName) {
                  console.log('[Sidebar] Got folder name from documents for', folderId, ':', folderName);
                }
              }
              
              // If still no name and folder has subfolders, request folder tree with this folder as descendant
              // This will return folderTree with folder names
              if (!folderName && folderTreeResponse.childrenLookup[folderIdStr]) {
                const subfolderIds = folderTreeResponse.childrenLookup[folderIdStr] || [];
                if (subfolderIds.length > 0) {
                  console.log('[Sidebar] Folder', folderId, 'has', subfolderIds.length, 'subfolders, requesting folder tree with descendantFolderIDs...');
                  
                  try {
                    // Request folder tree with this folder and its children as descendants
                    // This will return folderTree with folder names in the children structure
                    const detailedFolderTreeResponse = await chrome.runtime.sendMessage({
                      type: MESSAGE_TYPES.GET_FOLDER_TREE,
                      projectId: String(projectId),
                      descendantFolderIDs: [folderId, ...subfolderIds.slice(0, 20)] // Include folder and up to 20 subfolders
                    });
                    
                    // Check folderNameMap first (extracted from folderTree)
                    if (detailedFolderTreeResponse && detailedFolderTreeResponse.folderNameMap) {
                      folderName = detailedFolderTreeResponse.folderNameMap[folderId] || 
                                  detailedFolderTreeResponse.folderNameMap[folderIdStr];
                      if (folderName) {
                        console.log('[Sidebar] Got folder name from detailed folder tree folderNameMap for', folderId, ':', folderName);
                      }
                    }
                    
                    // Also check folderLookup as fallback
                    if (!folderName && detailedFolderTreeResponse && detailedFolderTreeResponse.folderLookup) {
                      const folderDetails = detailedFolderTreeResponse.folderLookup[folderIdStr] || 
                                          detailedFolderTreeResponse.folderLookup[folderId];
                      if (folderDetails) {
                        folderName = folderDetails.folderName || folderDetails.name || folderDetails.folder_name;
                        if (folderName) {
                          console.log('[Sidebar] Got folder name from detailed folder tree folderLookup for', folderId, ':', folderName);
                        }
                      }
                    }
                  } catch (error) {
                    console.warn('[Sidebar] Could not get detailed folder tree for folder', folderId, ':', error);
                  }
                }
              }
              
              // If still no name OR we haven't checked for DICOM files yet, fetch documents from this folder
              if (!folderName || !hasDicomFiles) {
                try {
                  console.log('[Sidebar] Fetching folder documents for folder', folderId, '(checking for DICOM files)');
                  const folderDocsResponse = await chrome.runtime.sendMessage({
                    type: MESSAGE_TYPES.GET_PROJECT_DOCS,
                    projectId: String(projectId),
                    folderID: folderId,
                    limit: 100, // Get more documents to check for DICOM files
                    offset: 0
                  });
                  
                  let folderDocs = [];
                  if (folderDocsResponse) {
                    if (folderDocsResponse.items && Array.isArray(folderDocsResponse.items)) {
                      folderDocs = folderDocsResponse.items;
                    } else if (Array.isArray(folderDocsResponse)) {
                      folderDocs = folderDocsResponse;
                    } else if (folderDocsResponse.data && Array.isArray(folderDocsResponse.data)) {
                      folderDocs = folderDocsResponse.data;
                    }
                  }
                  
                  // Check for DICOM files (if not already detected from root scan)
                  if (!hasDicomFiles) {
                    hasDicomFiles = folderDocs.some(doc => {
                      const filename = (doc.filename || doc.name || '').toLowerCase();
                      const mimeType = (doc.mimeType || doc.contentType || '').toLowerCase();
                      return filename.endsWith('.dcm') || 
                             filename.endsWith('.dicom') ||
                             mimeType === 'application/dicom';
                    });
                    
                    if (hasDicomFiles) {
                      console.log('[Sidebar] Folder', folderId, 'contains DICOM files');
                    }
                  }
                  
                  if (folderDocs.length > 0 && folderDocs[0].folderName) {
                    folderName = folderDocs[0].folderName;
                    console.log('[Sidebar] Got folder name from folder documents for', folderId, ':', folderName);
                  } else {
                    console.log('[Sidebar] Folder', folderId, 'has no documents directly');
                  }
                } catch (error) {
                  console.warn('[Sidebar] Could not fetch folder documents for', folderId, ':', error);
                }
              }
              
              // Final fallback
              if (!folderName) {
                folderName = `Folder ${folderId}`;
                console.log('[Sidebar] Using fallback name for folder', folderId);
              }
              
              return {
                id: folderId,
                name: folderName,
                parentID: currentFolderID,
                hasDicomFiles: hasDicomFiles
              };
            })
          );
          
          folders = foldersWithNames.filter(f => f);
          
          console.log('[Sidebar] Parsed folders:', folders.length, folders);
        } else {
          console.warn('[Sidebar] No childrenLookup in folder tree response');
          console.warn('[Sidebar] Folder tree response structure:', Object.keys(folderTreeResponse || {}));
        }
      } catch (error) {
        console.warn('[Sidebar] Could not load folder tree:', error);
        console.error('[Sidebar] Folder tree error details:', error);
      }
      
      console.log('[Sidebar] Extracted documents:', documents.length, 'folders:', folders.length);
      this.state.documents = documents;
      this.state.folders = folders;
      this.state.currentFolder = folderID;
      this.renderDocumentList();
    } catch (error) {
      console.error('[Sidebar] Failed to load documents:', error);
      fileList.innerHTML = `<div class="empty">Failed to load documents: ${error.message}</div>`;
    }
  }

  /**
   * Render document and folder list
   */
  renderDocumentList() {
    const { fileList } = this.elements;
    
    const folders = this.state.folders || [];
    const documents = this.state.documents || [];
    
    if (!folders.length && !documents.length) {
      fileList.innerHTML = '<div class="empty">No folders or documents found</div>';
      return;
    }

    let html = '';
    
    // Render folders first
    folders.forEach(folder => {
      // Check if folder contains DICOM files
      // First check the folder's hasDicomFiles property (set during folder loading)
      let hasDicomFiles = folder.hasDicomFiles || false;
      
      // Also check current documents view for DICOM files in this folder
      if (!hasDicomFiles) {
        const folderDocs = documents.filter(doc => {
          const docFolderId = doc.folderID || doc.folderId;
          return String(docFolderId) === String(folder.id);
        });
        
        hasDicomFiles = folderDocs.some(doc => {
          const filename = (doc.filename || doc.name || '').toLowerCase();
          const mimeType = (doc.mimeType || doc.contentType || '').toLowerCase();
          return filename.endsWith('.dcm') || 
                 filename.endsWith('.dicom') ||
                 mimeType === 'application/dicom';
        });
      }
      
      html += `
        <div class="list-item folder-item" data-folder-id="${folder.id}">
          <span class="icon">📁</span>
          <div class="info">
            <div class="name">${this.escapeHtml(folder.name)}</div>
            <div class="meta">Folder</div>
          </div>
          <div class="actions">
            ${hasDicomFiles ? `
              <button class="action-btn primary open-dicom-btn" data-folder-id="${folder.id}" title="Open DICOM files in viewer">
                Open Dicom
              </button>
            ` : ''}
            <button class="action-btn ${hasDicomFiles ? 'secondary' : 'primary'} download-folder-btn" data-folder-id="${folder.id}" title="Download all documents in folder">
              Download All
            </button>
          </div>
        </div>
      `;
    });
    
    // Render documents
    html += documents.map(doc => {
      // Handle different field names from Filevine API
      const docId = doc.id || doc.docId || doc.documentId;
      const filename = doc.filename || doc.name || doc.title || 'Unknown';
      const size = doc.size || 0;
      const icon = this.getFileIcon(filename);
      
      // Check if this is a DICOM file
      const isDicom = filename.toLowerCase().endsWith('.dcm') || 
                      filename.toLowerCase().endsWith('.dicom') ||
                      (doc.mimeType && doc.mimeType.toLowerCase() === 'application/dicom');
      
      return `
        <div class="list-item" data-doc-id="${docId}">
          <span class="icon">${icon}</span>
          <div class="info">
            <div class="name">${this.escapeHtml(filename)}</div>
            <div class="meta">${this.formatFileSize(size)}</div>
          </div>
          <div class="actions">
            ${isDicom ? `
              <button class="action-btn primary view-btn" data-doc-id="${docId}" title="View in DICOM viewer">
                View
              </button>
            ` : ''}
            <button class="action-btn ${isDicom ? 'secondary' : 'primary'} download-btn" data-doc-id="${docId}">
              Download
            </button>
          </div>
        </div>
      `;
    }).join('');
    
    fileList.innerHTML = html;

    // Attach folder click handlers
    fileList.querySelectorAll('.folder-item').forEach(item => {
      item.addEventListener('click', (e) => {
        if (!e.target.closest('.actions')) {
          const folderId = item.dataset.folderId;
          this.openFolder(folderId);
        }
      });
    });

    // Attach folder download handlers
    fileList.querySelectorAll('.download-folder-btn').forEach(btn => {
      btn.addEventListener('click', (e) => {
        e.stopPropagation();
        const folderId = btn.dataset.folderId;
        this.downloadFolder(folderId);
      });
    });

    // Attach open DICOM handlers
    fileList.querySelectorAll('.open-dicom-btn').forEach(btn => {
      btn.addEventListener('click', async (e) => {
        e.stopPropagation();
        e.preventDefault();
        const folderId = btn.dataset.folderId;
        const folder = this.state.folders.find(f => String(f.id) === String(folderId));
        console.log('[Sidebar] Open Dicom button clicked for folder:', folderId);
        
        // Show loading state
        const originalText = btn.textContent;
        const originalDisabled = btn.disabled;
        btn.disabled = true;
        btn.textContent = 'Loading...';
        btn.style.opacity = '0.6';
        btn.style.cursor = 'not-allowed';
        
        // Show notification
        this.showNotification(`Preparing DICOM viewer for "${folder?.name || 'folder'}"...`, 'info');
        
        try {
          await this.openFolderAsDicom(folderId);
          // Success - button will stay disabled since viewer is opening
          // Don't restore button immediately as viewer is opening
        } catch (error) {
          console.error('[Sidebar] Error in openFolderAsDicom:', error);
          this.showNotification(`Failed to open DICOM: ${error.message}`, 'error');
          // Restore button on error
          btn.disabled = originalDisabled;
          btn.textContent = originalText;
          btn.style.opacity = '1';
          btn.style.cursor = 'pointer';
        }
      });
    });

    // Attach document download handlers
    fileList.querySelectorAll('.download-btn').forEach(btn => {
      btn.addEventListener('click', (e) => {
        e.stopPropagation();
        const docId = btn.dataset.docId;
        this.downloadDocument(docId);
      });
    });

    // Attach view handlers for DICOM files
    fileList.querySelectorAll('.view-btn').forEach(btn => {
      btn.addEventListener('click', (e) => {
        e.stopPropagation();
        const docId = btn.dataset.docId;
        this.viewDocument(docId);
      });
    });
    
    // Update breadcrumb
    this.updateBreadcrumb();
  }
  
  /**
   * Open a folder
   */
  async openFolder(folderId) {
    const folder = this.state.folders.find(f => String(f.id) === String(folderId));
    if (!folder) {
      console.error('[Sidebar] Folder not found:', folderId);
      return;
    }
    
    // Add to folder path
    this.state.folderPath.push({
      id: folderId,
      name: folder.name
    });
    
    // Load documents in this folder
    const projectId = this.state.selectedProject?.projectID || this.state.selectedProject?.projectId || this.state.selectedProject?.id;
    await this.loadDocuments(projectId, folderId);
  }
  
  /**
   * Update breadcrumb navigation
   */
  updateBreadcrumb() {
    const breadcrumb = document.querySelector('#file-browser .breadcrumb');
    if (!breadcrumb) return;
    
    let html = '<button id="back-to-projects" class="text-btn">← Projects</button>';
    
    if (this.state.selectedProject) {
      html += `<span class="project-name">${this.escapeHtml(this.state.selectedProject.projectName || this.state.selectedProject.name)}</span>`;
    }
    
    // Add folder path
    this.state.folderPath.forEach((folder, index) => {
      html += ` <span class="separator">/</span> `;
      html += `<button class="text-btn folder-breadcrumb" data-folder-id="${folder.id}" data-path-index="${index}">${this.escapeHtml(folder.name)}</button>`;
    });
    
    breadcrumb.innerHTML = html;
    
    // Re-attach back to projects handler
    const backBtn = breadcrumb.querySelector('#back-to-projects');
    if (backBtn) {
      backBtn.addEventListener('click', () => {
        this.showProjectList();
      });
    }
    
    // Attach breadcrumb click handlers
    breadcrumb.querySelectorAll('.folder-breadcrumb').forEach(btn => {
      btn.addEventListener('click', () => {
        const pathIndex = parseInt(btn.dataset.pathIndex);
        // Navigate back to this folder
        this.state.folderPath = this.state.folderPath.slice(0, pathIndex + 1);
        const folderId = btn.dataset.folderId;
        const projectId = this.state.selectedProject?.projectID || this.state.selectedProject?.projectId || this.state.selectedProject?.id;
        this.loadDocuments(projectId, folderId);
      });
    });
  }
  
  /**
   * Open a folder as a DICOM series (without downloading)
   */
  async openFolderAsDicom(folderId) {
    const folder = this.state.folders.find(f => String(f.id) === String(folderId));
    if (!folder) {
      console.error('[Sidebar] Folder not found:', folderId);
      return;
    }
    
    const projectId = this.state.selectedProject?.projectID || this.state.selectedProject?.projectId || this.state.selectedProject?.id;
    
    try {
      console.log('[Sidebar] Opening folder as DICOM series:', folder.name, 'folderId:', folderId);
      
      // Show initial notification
      this.showNotification(`Scanning folder for DICOM files...`, 'info', 5000);
      
      // Fetch all documents in the folder
      const docsResponse = await chrome.runtime.sendMessage({
        type: MESSAGE_TYPES.GET_PROJECT_DOCS,
        projectId: String(projectId),
        folderID: folderId,
        limit: 500, // Get all documents
        offset: 0
      });
      
      // Handle different response formats
      let allDocuments = [];
      if (docsResponse) {
        if (docsResponse.items && Array.isArray(docsResponse.items)) {
          allDocuments = docsResponse.items;
        } else if (Array.isArray(docsResponse)) {
          allDocuments = docsResponse;
        } else if (docsResponse.data && Array.isArray(docsResponse.data)) {
          allDocuments = docsResponse.data;
        }
      }
      
      // Filter for DICOM files
      const dicomFiles = allDocuments.filter(doc => {
        const filename = (doc.filename || doc.name || '').toLowerCase();
        const mimeType = (doc.mimeType || doc.contentType || '').toLowerCase();
        return filename.endsWith('.dcm') || 
               filename.endsWith('.dicom') ||
               mimeType === 'application/dicom';
      });
      
      // Update notification
      this.showNotification(`Found ${dicomFiles.length} DICOM file${dicomFiles.length > 1 ? 's' : ''}`, 'info', 2000);
      
      if (dicomFiles.length === 0) {
        this.showNotification('No DICOM files found in this folder', 'warning', 4000);
        throw new Error('No DICOM files found');
      }
      
      if (dicomFiles.length === 1) {
        // Single DICOM file - open directly
        this.showNotification('Opening DICOM viewer...', 'info', 3000);
        const docId = dicomFiles[0].id || dicomFiles[0].docId || dicomFiles[0].documentId;
        await this.viewDocument(docId);
        return;
      }
      
      // Multiple DICOM files - create series and open
      const docIds = dicomFiles.map(doc => doc.id || doc.docId || doc.documentId);
      
      console.log('[Sidebar] Found', dicomFiles.length, 'DICOM files, creating series...');
      console.log('[Sidebar] Doc IDs:', docIds);
      
      // Update notification
      this.showNotification(`Downloading ${dicomFiles.length} DICOM files and preparing viewer...`, 'info', 6000);
      
      // Send message to background to create series and open it
      try {
        const response = await chrome.runtime.sendMessage({
          type: MESSAGE_TYPES.OPEN_FOLDER_AS_DICOM,
          projectId: projectId,
          folderId: folderId,
          folderName: folder.name,
          docIds: docIds
        });
        
        console.log('[Sidebar] Open folder as DICOM response:', response);
        
        // Show success notification
        this.showNotification(`Opening DICOM viewer with ${dicomFiles.length} images...`, 'success', 4000);
      } catch (error) {
        console.error('[Sidebar] Error sending OPEN_FOLDER_AS_DICOM message:', error);
        throw error;
      }
      
    } catch (error) {
      console.error('[Sidebar] Failed to open folder as DICOM:', error);
      console.error('[Sidebar] Error stack:', error.stack);
      throw error; // Re-throw so caller can handle it
    }
  }

  /**
   * Download all documents in a folder
   */
  async downloadFolder(folderId) {
    const folder = this.state.folders.find(f => String(f.id) === String(folderId));
    if (!folder) {
      console.error('[Sidebar] Folder not found:', folderId);
      return;
    }
    
    const projectId = this.state.selectedProject?.projectID || this.state.selectedProject?.projectId || this.state.selectedProject?.id;
    
    try {
      console.log('[Sidebar] Downloading folder:', folder.name, 'folderId:', folderId);
      
      await chrome.runtime.sendMessage({
        type: MESSAGE_TYPES.DOWNLOAD_FOLDER,
        projectId: projectId,
        folderId: folderId,
        folderName: folder.name
      });
      
      // Update download count
      this.updateDownloadCount();
    } catch (error) {
      console.error('[Sidebar] Failed to download folder:', error);
      alert(`Failed to download folder: ${error.message}`);
    }
  }

  /**
   * View a document directly (without downloading)
   */
  async viewDocument(docId) {
    const doc = this.state.documents.find(d => String(d.id || d.docId || d.documentId) === String(docId));
    if (!doc) {
      console.error('[Sidebar] Document not found:', docId);
      return;
    }

    try {
      const actualDocId = doc.id || doc.docId || doc.documentId;
      const projectId = this.state.selectedProject?.projectID || this.state.selectedProject?.projectId || this.state.selectedProject?.id;
      const filename = doc.filename || doc.name || doc.title;
      const mimeType = doc.mimeType || doc.contentType;
      
      console.log('[Sidebar] Viewing document directly:', {
        docId: actualDocId,
        projectId: projectId,
        filename: filename
      });
      
      await chrome.runtime.sendMessage({
        type: MESSAGE_TYPES.VIEW_FILE_DIRECT,
        docId: actualDocId,
        projectId: projectId,
        filename: filename,
        mimeType: mimeType
      });
    } catch (error) {
      console.error('[Sidebar] Failed to view document:', error);
      alert(`Failed to open viewer: ${error.message}`);
    }
  }

  /**
   * Download a document
   */
  async downloadDocument(docId) {
    const doc = this.state.documents.find(d => String(d.id || d.docId || d.documentId) === String(docId));
    if (!doc) {
      console.error('[Sidebar] Document not found:', docId);
      return;
    }

    try {
      const actualDocId = doc.id || doc.docId || doc.documentId;
      const projectId = this.state.selectedProject?.projectID || this.state.selectedProject?.projectId || this.state.selectedProject?.id;
      
      // Build folder path: current folder path + document's folder name (if different)
      let folderPath = [...this.state.folderPath.map(f => f.name)];
      
      // If document has a folderName and it's different from the current folder, add it
      if (doc.folderName && doc.folderID) {
        const currentFolderId = this.state.currentFolder;
        const docFolderId = doc.folderID;
        
        // If document is in a different folder than current, we might need to adjust path
        // For now, if we're viewing a folder and the doc is in that folder, use current path
        // Otherwise, use the document's folderName
        if (String(docFolderId) !== String(currentFolderId)) {
          // Document is in a different folder - use its folderName
          folderPath = [doc.folderName];
        }
      }
      
      console.log('[Sidebar] Downloading document:', {
        docId: actualDocId,
        projectId: projectId,
        filename: doc.filename || doc.name || doc.title,
        folderPath: folderPath
      });
      
      await chrome.runtime.sendMessage({
        type: MESSAGE_TYPES.DOWNLOAD_FILE,
        docId: actualDocId,
        projectId: projectId,
        filename: doc.filename || doc.name || doc.title,
        mimeType: doc.mimeType || doc.contentType,
        folderPath: folderPath, // Include folder path
        autoOpen: true
      });

      // Update UI to show download started
      this.updateDownloadCount();
    } catch (error) {
      console.error('[Sidebar] Failed to start download:', error);
      alert(`Download failed: ${error.message}`);
    }
  }

  /**
   * Toggle downloads panel
   */
  toggleDownloadsPanel() {
    this.state.showDownloads = !this.state.showDownloads;
    
    if (this.state.showDownloads) {
      this.elements.downloadPanel.classList.remove('hidden');
      this.elements.mainPanel.classList.add('hidden');
      this.loadDownloadState();
    } else {
      this.elements.downloadPanel.classList.add('hidden');
      this.elements.mainPanel.classList.remove('hidden');
    }
  }

  /**
   * Load current download state
   */
  async loadDownloadState() {
    try {
      const state = await chrome.runtime.sendMessage({ type: 'get_download_state' });
      this.state.downloads = state;
      this.renderDownloadList();
    } catch (error) {
      console.error('[Sidebar] Failed to load download state:', error);
    }
  }

  /**
   * Render download list
   */
  renderDownloadList() {
    const { downloadList } = this.elements;
    const allDownloads = [
      ...this.state.downloads.active,
      ...this.state.downloads.queue
    ];

    if (!allDownloads.length) {
      downloadList.innerHTML = '<div class="empty">No downloads</div>';
      return;
    }

    downloadList.innerHTML = allDownloads.map(dl => `
      <div class="download-item" data-doc-id="${dl.docId}">
        <div class="header">
          <span class="name">${this.escapeHtml(dl.filename)}</span>
          <span class="status ${dl.status}">${dl.status}</span>
        </div>
        ${dl.status === 'downloading' ? `
          <div class="progress-bar">
            <div class="fill" style="width: ${dl.progress}%"></div>
          </div>
        ` : ''}
        ${dl.error ? `<div class="error">${dl.error}</div>` : ''}
      </div>
    `).join('');
  }

  /**
   * Update download count badge
   */
  updateDownloadCount() {
    const count = this.state.downloads.queue.length + this.state.downloads.active.length;
    this.elements.downloadCount.textContent = count;
    this.elements.downloadCount.classList.toggle('hidden', count === 0);
  }

  /**
   * Clear all downloads
   */
  async clearDownloads() {
    try {
      await chrome.runtime.sendMessage({ type: 'clear_all_files' });
      this.state.downloads = { queue: [], active: [] };
      this.renderDownloadList();
      this.updateDownloadCount();
    } catch (error) {
      console.error('[Sidebar] Failed to clear downloads:', error);
    }
  }

  /**
   * Switch organization
   */
  async switchOrg(orgId) {
    try {
      await chrome.runtime.sendMessage({ type: 'switch_org', orgId });
      this.state.auth.orgId = orgId;
      await this.loadProjects();
    } catch (error) {
      console.error('[Sidebar] Failed to switch org:', error);
      alert(`Failed to switch organization: ${error.message}`);
    }
  }

  /**
   * Listen for messages from background
   */
  listenForMessages() {
    chrome.runtime.onMessage.addListener((message) => {
      switch (message.type) {
        case MESSAGE_TYPES.AUTH_STATE_CHANGED:
          this.state.connectionState = message.state?.authenticated 
            ? CONNECTION_STATE.CONNECTED 
            : CONNECTION_STATE.DISCONNECTED;
          this.state.auth = message.state?.auth;
          this.updateConnectionUI();
          if (message.state?.authenticated) {
            this.loadProjects();
          }
          break;

        case MESSAGE_TYPES.DOWNLOAD_PROGRESS:
          this.state.downloads = message.state;
          if (this.state.showDownloads) {
            this.renderDownloadList();
          }
          this.updateDownloadCount();
          break;

        case MESSAGE_TYPES.DOWNLOAD_COMPLETE:
          // Could show notification
          break;

        case 'PAGE_CONTEXT_UPDATE':
          // Auto-fill org ID and project type ID when user navigates to custom project type pages
          this.handlePageContextUpdate(message.context);
          break;
      }
    });
  }

  /**
   * Handle page context updates from content script
   */
  handlePageContextUpdate(context) {
    console.log('[Sidebar] Page context update:', context);

    // If we're on a custom project type page, auto-fill the org ID and project type ID
    if (context.projectTypeId && context.orgId) {
      console.log('[Sidebar] Auto-filling org ID and project type ID:', context.orgId, context.projectTypeId);

      // Fill AI Builder form
      const aiOrgId = document.getElementById('ai-org-id');
      const aiProjectTypeId = document.getElementById('ai-project-type-id');
      if (aiOrgId && aiProjectTypeId) {
        aiOrgId.value = context.orgId;
        aiProjectTypeId.value = context.projectTypeId;
        console.log('[Sidebar] Auto-filled AI Builder form');
      }

      // Fill Schema Viewer form
      const schemaOrgId = document.getElementById('schema-org-id');
      const schemaProjectTypeId = document.getElementById('schema-project-type-id');
      if (schemaOrgId && schemaProjectTypeId) {
        schemaOrgId.value = context.orgId;
        schemaProjectTypeId.value = context.projectTypeId;
        console.log('[Sidebar] Auto-filled Schema Viewer form');
      }

      // Fill Manual Field Creator form
      const manualOrgId = document.getElementById('org-id');
      const manualProjectTypeId = document.getElementById('project-type-id');
      if (manualOrgId && manualProjectTypeId) {
        manualOrgId.value = context.orgId;
        manualProjectTypeId.value = context.projectTypeId;
        console.log('[Sidebar] Auto-filled Manual Field Creator form');
      }

      // Show a subtle notification
      this.showNotification('Detected project type page - fields auto-filled!', 'info');
    }
  }

  /**
   * Utility: Debounce function calls
   */
  debounce(fn, delay) {
    clearTimeout(this.debounceTimer);
    this.debounceTimer = setTimeout(fn, delay);
  }

  /**
   * Utility: Escape HTML
   */
  escapeHtml(text) {
    const div = document.createElement('div');
    div.textContent = text;
    return div.innerHTML;
  }

  /**
   * Utility: Get file icon
   */
  getFileIcon(filename) {
    const ext = filename?.split('.').pop()?.toLowerCase();
    const icons = {
      pdf: '📄',
      doc: '📝',
      docx: '📝',
      xls: '📊',
      xlsx: '📊',
      ppt: '📽️',
      pptx: '📽️',
      jpg: '🖼️',
      jpeg: '🖼️',
      png: '🖼️',
      gif: '🖼️',
      dcm: '🏥',
      dicom: '🏥',
      zip: '📦',
      txt: '📃'
    };
    return icons[ext] || '📄';
  }

  /**
   * Utility: Format file size
   */
  formatFileSize(bytes) {
    if (!bytes) return '';
    const units = ['B', 'KB', 'MB', 'GB'];
    let size = bytes;
    let unitIndex = 0;
    while (size >= 1024 && unitIndex < units.length - 1) {
      size /= 1024;
      unitIndex++;
    }
    return `${size.toFixed(1)} ${units[unitIndex]}`;
  }

  /**
   * Show a notification/toast message
   */
  showNotification(message, type = 'info', duration = 3000) {
    // Remove existing notification if any
    const existing = document.getElementById('sidebar-notification');
    if (existing) {
      existing.remove();
    }

    // Create notification element
    const notification = document.createElement('div');
    notification.id = 'sidebar-notification';
    notification.className = `notification notification-${type}`;
    notification.textContent = message;

    // Add to container
    const container = document.querySelector('.container');
    if (container) {
      container.appendChild(notification);

      // Animate in
      setTimeout(() => {
        notification.classList.add('show');
      }, 10);

      // Auto-remove after duration (unless it's an error, which stays longer)
      const removeDelay = type === 'error' ? duration * 2 : duration;
      setTimeout(() => {
        notification.classList.remove('show');
        setTimeout(() => {
          if (notification.parentNode) {
            notification.remove();
          }
        }, 300); // Wait for fade out animation
      }, removeDelay);
    }
  }

  /**
   * Handle custom field form submission
   */
  async handleCustomFieldSubmit(event) {
    console.log('[Sidebar] Custom field form submitted');

    const form = event.target;
    const submitBtn = document.getElementById('create-field-btn');
    const resultContainer = document.getElementById('field-result');
    const resultContent = document.getElementById('result-content');

    // Get form values
    const formData = new FormData(form);
    const orgId = formData.get('orgId');
    const sectionId = formData.get('sectionId');
    const fieldName = formData.get('fieldName');
    const fieldSelector = formData.get('fieldSelector');
    const fieldType = formData.get('fieldType');
    const row = formData.get('row');
    const isRequired = formData.get('isRequired') === 'on';
    const notes = formData.get('notes');

    // Disable button and show loading state
    submitBtn.disabled = true;
    submitBtn.textContent = 'Creating...';

    try {
      // Send message to background to create the field
      const response = await chrome.runtime.sendMessage({
        type: 'create_custom_field',
        orgId: parseInt(orgId),
        sectionId: parseInt(sectionId),
        fieldData: {
          name: fieldName,
          fieldSelector: fieldSelector,
          customFieldType: parseInt(fieldType),
          row: parseInt(row),
          isRequired: isRequired,
          notes: notes || ''
        }
      });

      console.log('[Sidebar] Custom field creation response:', response);

      // Show result
      if (response.success) {
        resultContent.innerHTML = `
          <div class="result-success">✓ Field created successfully!</div>
          <div><strong>Field ID:</strong> ${response.data.id}</div>
          <div><strong>Name:</strong> ${response.data.name}</div>
          <div><strong>Internal Name:</strong> ${response.data.internalName}</div>
          <div><strong>Type:</strong> ${response.data.customFieldType}</div>
          <pre>${JSON.stringify(response.data, null, 2)}</pre>
        `;
        resultContainer.classList.remove('hidden');

        // Reset form on success
        form.reset();

        this.showNotification('Custom field created successfully!', 'success');
      } else {
        throw new Error(response.message || 'Failed to create field');
      }

    } catch (error) {
      console.error('[Sidebar] Error creating custom field:', error);

      resultContent.innerHTML = `
        <div class="result-error">✗ Error creating field</div>
        <pre>${error.message}</pre>
      `;
      resultContainer.classList.remove('hidden');

      this.showNotification('Failed to create custom field', 'error');
    } finally {
      // Re-enable button
      submitBtn.disabled = false;
      submitBtn.textContent = 'Create Field';
    }
  }

  /**
   * Load custom sections from project type
   */
  async loadCustomSections() {
    console.log('[Sidebar] Loading custom sections');

    const orgIdInput = document.getElementById('org-id');
    const projectTypeIdInput = document.getElementById('project-type-id');
    const sectionSelect = document.getElementById('section-id');
    const loadBtn = document.getElementById('load-sections-btn');

    const orgId = orgIdInput.value.trim();
    const projectTypeId = projectTypeIdInput.value.trim();

    if (!orgId || !projectTypeId) {
      this.showNotification('Please enter Organization ID and Project Type ID first', 'error');
      return;
    }

    // Disable button and show loading state
    loadBtn.disabled = true;
    loadBtn.textContent = 'Loading...';
    sectionSelect.disabled = true;

    try {
      // Send message to background to get project type
      const response = await chrome.runtime.sendMessage({
        type: 'get_custom_project_type',
        orgId: parseInt(orgId),
        projectTypeId: parseInt(projectTypeId)
      });

      console.log('[Sidebar] Project type response:', response);

      if (response.success && response.data?.customSections) {
        const sections = response.data.customSections;

        // Clear and populate dropdown
        sectionSelect.innerHTML = '<option value="">Select a section...</option>';

        sections.forEach(section => {
          const option = document.createElement('option');
          option.value = section.id;
          option.textContent = `${section.name} (ID: ${section.id})`;
          sectionSelect.appendChild(option);
        });

        sectionSelect.disabled = false;
        this.showNotification(`Loaded ${sections.length} sections`, 'success');
      } else {
        throw new Error(response.message || 'Failed to load sections');
      }

    } catch (error) {
      console.error('[Sidebar] Error loading sections:', error);
      sectionSelect.innerHTML = '<option value="">Error loading sections</option>';
      this.showNotification('Failed to load sections', 'error');
    } finally {
      // Re-enable button
      loadBtn.disabled = false;
      loadBtn.textContent = 'Load Sections';
    }
  }

  /**
   * Load sections for AI builder
   */
  async loadAISections() {
    const orgIdInput = document.getElementById('ai-org-id');
    const projectTypeIdInput = document.getElementById('ai-project-type-id');
    const sectionSelect = document.getElementById('ai-section-id');
    const loadBtn = document.getElementById('ai-load-sections-btn');

    const orgId = orgIdInput.value.trim();
    const projectTypeId = projectTypeIdInput.value.trim();

    if (!orgId || !projectTypeId) {
      this.showNotification('Please enter Organization ID and Project Type ID first', 'error');
      return;
    }

    loadBtn.disabled = true;
    loadBtn.textContent = 'Loading...';
    sectionSelect.disabled = true;

    try {
      const response = await chrome.runtime.sendMessage({
        type: 'get_custom_project_type',
        orgId: parseInt(orgId),
        projectTypeId: parseInt(projectTypeId)
      });

      if (response.success && response.data?.customSections) {
        const sections = response.data.customSections;

        // Auto-populate org ID and project type ID from the first section
        if (sections.length > 0 && sections[0].customProjectTypeID) {
          if (!orgIdInput.value && sections[0].orgID) {
            orgIdInput.value = sections[0].orgID;
            console.log('[Sidebar] Auto-filled org ID:', sections[0].orgID);
          }
          if (!projectTypeIdInput.value) {
            projectTypeIdInput.value = sections[0].customProjectTypeID;
            console.log('[Sidebar] Auto-filled project type ID:', sections[0].customProjectTypeID);
          }
        }

        sectionSelect.innerHTML = '<option value="">Select a section...</option>';

        sections.forEach(section => {
          const option = document.createElement('option');
          option.value = section.id;
          option.textContent = `${section.name} (ID: ${section.id})`;
          option.dataset.sectionName = section.name;
          sectionSelect.appendChild(option);
        });

        sectionSelect.disabled = false;
        this.showNotification(`Loaded ${sections.length} sections`, 'success');
      } else {
        throw new Error(response.message || 'Failed to load sections');
      }
    } catch (error) {
      console.error('[Sidebar] Error loading sections:', error);
      sectionSelect.innerHTML = '<option value="">Error loading sections</option>';
      this.showNotification('Failed to load sections', 'error');
    } finally {
      loadBtn.disabled = false;
      loadBtn.textContent = 'Load Sections';
    }
  }

  /**
   * Handle AI builder form submission
   */
  async handleAIBuilderSubmit(event) {
    const form = event.target;
    const submitBtn = document.getElementById('ai-generate-btn');
    const progressDiv = document.getElementById('ai-progress');
    const progressContent = document.getElementById('ai-progress-content');
    const previewDiv = document.getElementById('ai-preview');

    const formData = new FormData(form);
    const orgId = formData.get('orgId');
    const projectTypeId = formData.get('projectTypeId');
    const sectionId = formData.get('sectionId');
    const requirements = formData.get('requirements');

    submitBtn.disabled = true;
    submitBtn.textContent = 'Generating...';
    progressDiv.classList.remove('hidden');
    progressContent.innerHTML = '';
    previewDiv.classList.add('hidden'); // Hide preview during generation

    try {
      // Check if API key is configured
      const configCheck = await chrome.runtime.sendMessage({
        type: 'ai_check_config'
      });

      if (!configCheck.configured) {
        const apiKey = prompt('Please enter your Anthropic API key:');
        if (!apiKey) {
          throw new Error('API key is required');
        }

        await chrome.runtime.sendMessage({
          type: 'ai_set_api_key',
          apiKey: apiKey
        });
      }

      // Step 1: Generate fields
      this.addProgressStep('generate', 'Analyzing requirements with AI...', 'processing');

      const sectionSelect = document.getElementById('ai-section-id');
      const selectedOption = sectionSelect.options[sectionSelect.selectedIndex];
      const sectionName = selectedOption?.dataset?.sectionName || '';

      const generateResponse = await chrome.runtime.sendMessage({
        type: 'ai_generate_fields',
        requirements: requirements,
        context: {
          sectionName: sectionName
        }
      });

      if (!generateResponse.success || !generateResponse.fields || generateResponse.fields.length === 0) {
        throw new Error('No fields generated by AI');
      }

      this.updateProgressStep('generate', 'success', `Generated ${generateResponse.fields.length} fields`);

      // Step 2: Show preview instead of creating immediately
      await this.showFieldPreview(generateResponse.fields, {
        orgId: parseInt(orgId),
        projectTypeId: parseInt(projectTypeId),
        sectionId: parseInt(sectionId),
        sectionName: sectionName
      });

      // Hide progress and show success message
      setTimeout(() => {
        progressDiv.classList.add('hidden');
      }, 1000);

      this.showNotification('Fields generated! Review them below and click "Create These Fields" to proceed.', 'success');

    } catch (error) {
      console.error('[Sidebar] AI builder error:', error);

      const lastStep = progressContent.lastElementChild;
      if (lastStep && lastStep.classList.contains('processing')) {
        this.updateProgressStep(lastStep.dataset.stepId, 'error', error.message);
      } else {
        this.addProgressStep('error', error.message, 'error');
      }

      this.showNotification('Failed to generate fields', 'error');
    } finally {
      submitBtn.disabled = false;
      submitBtn.textContent = 'Generate Fields with AI';
    }
  }

  /**
   * Add a progress step to the AI progress UI
   */
  addProgressStep(stepId, message, status = 'pending') {
    const progressContent = document.getElementById('ai-progress-content');
    const existingStep = progressContent.querySelector(`[data-step-id="${stepId}"]`);

    if (existingStep) {
      this.updateProgressStep(stepId, status, message);
      return;
    }

    const icons = {
      pending: '⏳',
      processing: '⚙️',
      success: '✓',
      error: '✗'
    };

    const step = document.createElement('div');
    step.className = `progress-step ${status}`;
    step.dataset.stepId = stepId;
    step.innerHTML = `
      <div class="progress-icon ${status === 'processing' ? 'spinner' : ''}">${icons[status]}</div>
      <div class="progress-details">
        <div class="progress-message">${message}</div>
      </div>
    `;

    progressContent.appendChild(step);
  }

  /**
   * Update an existing progress step
   */
  updateProgressStep(stepId, status, message) {
    const progressContent = document.getElementById('ai-progress-content');
    const step = progressContent.querySelector(`[data-step-id="${stepId}"]`);

    if (!step) {
      this.addProgressStep(stepId, message, status);
      return;
    }

    const icons = {
      pending: '⏳',
      processing: '⚙️',
      success: '✓',
      error: '✗'
    };

    step.className = `progress-step ${status}`;
    step.querySelector('.progress-icon').textContent = icons[status];
    step.querySelector('.progress-icon').classList.toggle('spinner', status === 'processing');
    step.querySelector('.progress-message').textContent = message;
  }

  /**
   * Load sections for schema viewer
   */
  async loadSchemaSections() {
    const orgIdInput = document.getElementById('schema-org-id');
    const projectTypeIdInput = document.getElementById('schema-project-type-id');
    const sectionSelect = document.getElementById('schema-section-id');
    const loadBtn = document.getElementById('schema-load-sections-btn');

    const orgId = orgIdInput.value.trim();
    const projectTypeId = projectTypeIdInput.value.trim();

    if (!orgId || !projectTypeId) {
      this.showNotification('Please enter Organization ID and Project Type ID first', 'error');
      return;
    }

    loadBtn.disabled = true;
    loadBtn.textContent = 'Loading...';
    sectionSelect.disabled = true;

    try {
      const response = await chrome.runtime.sendMessage({
        type: 'get_custom_project_type',
        orgId: parseInt(orgId),
        projectTypeId: parseInt(projectTypeId)
      });

      if (response.success && response.data?.customSections) {
        const sections = response.data.customSections;

        sectionSelect.innerHTML = '<option value="">Select a section...</option>';

        sections.forEach(section => {
          const option = document.createElement('option');
          option.value = section.id;
          option.textContent = `${section.name} (ID: ${section.id})`;
          option.dataset.sectionData = JSON.stringify(section);
          sectionSelect.appendChild(option);
        });

        sectionSelect.disabled = false;
        this.showNotification(`Loaded ${sections.length} sections`, 'success');
      } else {
        throw new Error(response.message || 'Failed to load sections');
      }
    } catch (error) {
      console.error('[Sidebar] Error loading sections:', error);
      sectionSelect.innerHTML = '<option value="">Error loading sections</option>';
      this.showNotification('Failed to load sections', 'error');
    } finally {
      loadBtn.disabled = false;
      loadBtn.textContent = 'Load Sections';
    }
  }

  /**
   * Handle schema viewer form submission
   */
  async handleSchemaViewerSubmit(event) {
    const form = event.target;
    const submitBtn = document.getElementById('view-schema-btn');
    const sectionSelect = document.getElementById('schema-section-id');
    const schemaDisplay = document.getElementById('schema-display');

    const selectedOption = sectionSelect.options[sectionSelect.selectedIndex];
    if (!selectedOption || !selectedOption.dataset.sectionData) {
      this.showNotification('Please select a section first', 'error');
      return;
    }

    submitBtn.disabled = true;
    submitBtn.textContent = 'Loading Schema...';

    try {
      const sectionData = JSON.parse(selectedOption.dataset.sectionData);

      console.log('[Sidebar] Displaying schema for section:', sectionData.name);

      this.displaySchema(sectionData);
      schemaDisplay.classList.remove('hidden');

      this.showNotification('Schema loaded successfully', 'success');
    } catch (error) {
      console.error('[Sidebar] Error displaying schema:', error);
      this.showNotification('Failed to display schema', 'error');
    } finally {
      submitBtn.disabled = false;
      submitBtn.textContent = 'View Schema';
    }
  }

  /**
   * Display schema in a readable format
   */
  displaySchema(section) {
    const sectionName = document.getElementById('schema-section-name');
    const fieldCount = document.getElementById('schema-field-count');
    const schemaContent = document.getElementById('schema-content');

    // Update header
    sectionName.textContent = section.name || 'Section Schema';

    // Get fields
    const fields = section.customFields || [];
    fieldCount.textContent = `${fields.length} field${fields.length !== 1 ? 's' : ''}`;

    // Sort fields by row number, then by orderInRow
    const sortedFields = [...fields].sort((a, b) => {
      const rowDiff = (a.row || 0) - (b.row || 0);
      if (rowDiff !== 0) return rowDiff;
      return (a.orderInRow || 0) - (b.orderInRow || 0);
    });

    // Clear content
    schemaContent.innerHTML = '';

    if (sortedFields.length === 0) {
      schemaContent.innerHTML = `
        <div class="no-schema">
          <div class="no-schema-icon">📋</div>
          <div class="no-schema-text">No fields found in this section</div>
        </div>
      `;
      return;
    }

    // Render each field
    sortedFields.forEach(field => {
      const fieldCard = this.createFieldCard(field);
      schemaContent.appendChild(fieldCard);
    });
  }

  /**
   * Create a field card element
   * @param {Object} field - Field data
   * @param {boolean} isNew - Whether this is a new field (for visual distinction)
   */
  createFieldCard(field, isNew = false) {
    const card = document.createElement('div');
    card.className = isNew ? 'field-card field-card-new' : 'field-card';

    // Determine field type name
    const fieldTypeName = this.getFieldTypeName(field.customFieldType);

    // Check if it's a header
    const isHeader = field.customFieldType === 10;

    card.innerHTML = `
      <div class="field-card-header">
        <span class="field-name">${this.escapeHtml(field.name || 'Unnamed Field')}</span>
        <div class="field-card-badges">
          ${isNew ? '<span class="field-new-badge">NEW</span>' : ''}
          ${isHeader ? '<span class="field-header-badge">HEADER</span>' : `<span class="field-type-badge">${fieldTypeName}</span>`}
        </div>
      </div>

      <div class="field-details">
        <div class="field-detail-item">
          <span class="field-detail-label">Field Selector</span>
          <span class="field-detail-value">${this.escapeHtml(field.fieldSelector || 'N/A')}</span>
        </div>
        <div class="field-detail-item">
          <span class="field-detail-label">Row</span>
          <span class="field-detail-value">${field.row || 'N/A'}</span>
        </div>
        <div class="field-detail-item">
          <span class="field-detail-label">Order in Row</span>
          <span class="field-detail-value">${field.orderInRow !== undefined ? field.orderInRow : 'N/A'}</span>
        </div>
        <div class="field-detail-item">
          <span class="field-detail-label">Field ID</span>
          <span class="field-detail-value">${field.id || 'N/A'}</span>
        </div>
        <div class="field-detail-item">
          <span class="field-detail-label">Type ID</span>
          <span class="field-detail-value">${field.customFieldType}</span>
        </div>
      </div>

      ${field.isRequired || field.notes ? `
        <div class="field-badges">
          ${field.isRequired ? '<span class="field-badge required">Required</span>' : ''}
        </div>
      ` : ''}

      ${field.notes ? `
        <div class="field-notes">
          ${this.escapeHtml(field.notes)}
        </div>
      ` : ''}

      ${field.dropdownItems && field.dropdownItems.length > 0 ? `
        <div class="field-dropdown-items">
          <div class="dropdown-items-label">Dropdown Options:</div>
          <div class="dropdown-items-list">
            ${field.dropdownItems.map(item => `<span class="dropdown-item-chip">${this.escapeHtml(item)}</span>`).join('')}
          </div>
        </div>
      ` : ''}
    `;

    return card;
  }

  /**
   * Get field type name from field type ID
   */
  getFieldTypeName(typeId) {
    const fieldTypes = {
      1: 'Amount - Number',
      2: 'Amount - Currency',
      3: 'Text - Single Line',
      4: 'Date',
      5: 'Yes/No',
      6: 'Text - Multiple Lines',
      7: 'Person',
      8: 'File Attachment',
      9: 'Dropdown List',
      10: 'Sub Section Header',
      11: 'Multiple File Attachments',
      12: 'Doc Generation',
      13: 'Amount - Decimal',
      14: 'Amount - Percent',
      15: 'Deadline',
      17: 'Text - Large',
      18: 'Incident Date',
      19: 'Case Number',
      20: 'Action Button',
      21: 'Instructions',
      22: 'URL',
      23: 'URL List',
      24: 'Text List',
      25: 'Person List',
      26: 'Multi-Select List',
      27: 'Project Link',
      28: 'Project Link List',
      29: 'Doc Gen Multi-template',
      101: 'Calculated Number',
      102: 'Calculated Currency',
      113: 'Calculated Decimal',
      114: 'Calculated Percentage',
      150: 'Reference Field',
      1009: 'Report Fusion',
      1010: 'Report Fusion Multi',
      1100: 'Outlaw Template'
    };

    return fieldTypes[typeId] || `Unknown (${typeId})`;
  }

  /**
   * Escape HTML to prevent XSS
   */
  escapeHtml(text) {
    const div = document.createElement('div');
    div.textContent = text;
    return div.innerHTML;
  }

  /**
   * Show field preview with generated fields and existing fields
   */
  async showFieldPreview(fields, context) {
    // Store fields and context for later creation
    this.previewFields = fields;
    this.previewContext = context;

    const previewDiv = document.getElementById('ai-preview');
    const previewContent = document.getElementById('preview-content');
    const fieldCount = document.getElementById('preview-field-count');

    // Show loading state
    previewContent.innerHTML = '<div class="loading">Loading existing fields...</div>';
    previewDiv.classList.remove('hidden');

    try {
      // Fetch existing fields from the section
      let existingFields = [];
      if (context.orgId && context.projectTypeId && context.sectionId) {
        console.log('[Sidebar] Fetching existing fields for section', context.sectionId);

        const response = await chrome.runtime.sendMessage({
          type: 'get_custom_project_type',
          orgId: context.orgId,
          projectTypeId: context.projectTypeId
        });

        console.log('[Sidebar] Get custom project type response:', response);

        if (response.success && response.projectType) {
          console.log('[Sidebar] Project type has', response.projectType.customSections?.length, 'sections');

          // Find the section with matching sectionId (convert both to numbers for comparison)
          const targetSectionId = parseInt(context.sectionId);
          const section = response.projectType.customSections?.find(
            s => parseInt(s.id) === targetSectionId
          );

          console.log('[Sidebar] Looking for section ID:', targetSectionId);
          console.log('[Sidebar] Found section:', section ? section.name : 'NOT FOUND');

          if (section && section.customFields) {
            existingFields = section.customFields;
            console.log('[Sidebar] Found', existingFields.length, 'existing fields in section');
          } else {
            console.warn('[Sidebar] Section not found or has no custom fields');
          }
        } else {
          console.warn('[Sidebar] Failed to get project type or response not successful:', response);
        }
      } else {
        console.warn('[Sidebar] Missing context data for fetching existing fields:', {
          orgId: context.orgId,
          projectTypeId: context.projectTypeId,
          sectionId: context.sectionId
        });
      }

      // Combine existing fields with new fields
      // Mark new fields for visual distinction
      const newFieldsMarked = fields.map(f => ({ ...f, isNew: true }));
      const allFields = [...existingFields, ...newFieldsMarked];

      // Update field count to show both
      const newCount = fields.length;
      const existingCount = existingFields.length;
      fieldCount.textContent = `${newCount} new, ${existingCount} existing`;

      // Sort all fields by row and orderInRow
      const sortedFields = [...allFields].sort((a, b) => {
        const rowDiff = (a.row || 0) - (b.row || 0);
        if (rowDiff !== 0) return rowDiff;
        return (a.orderInRow || 0) - (b.orderInRow || 0);
      });

      // Clear and populate preview content
      previewContent.innerHTML = '';

      if (sortedFields.length === 0) {
        previewContent.innerHTML = `
          <div class="no-schema">
            <div class="no-schema-icon">📋</div>
            <div class="no-schema-text">No fields to preview</div>
          </div>
        `;
      } else {
        // Add section header if we have a section name
        if (context.sectionName && existingFields.length > 0) {
          const sectionHeader = document.createElement('div');
          sectionHeader.className = 'preview-section-header';
          sectionHeader.innerHTML = `
            <h4>${this.escapeHtml(context.sectionName)}</h4>
            <p class="preview-section-subtitle">Preview of section after adding new fields</p>
          `;
          previewContent.appendChild(sectionHeader);
        }

        // Render each field
        sortedFields.forEach(field => {
          const fieldCard = this.createFieldCard(field, field.isNew);
          previewContent.appendChild(fieldCard);
        });
      }

      // Scroll to preview
      setTimeout(() => {
        previewDiv.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
      }, 100);

    } catch (error) {
      console.error('[Sidebar] Error loading existing fields for preview:', error);

      // Fall back to showing just the new fields
      const sortedFields = [...fields].sort((a, b) => {
        const rowDiff = (a.row || 0) - (b.row || 0);
        if (rowDiff !== 0) return rowDiff;
        return (a.orderInRow || 0) - (b.orderInRow || 0);
      });

      previewContent.innerHTML = '';
      fieldCount.textContent = `${fields.length} new field${fields.length !== 1 ? 's' : ''}`;

      sortedFields.forEach(field => {
        const fieldCard = this.createFieldCard(field, true);
        previewContent.appendChild(fieldCard);
      });
    }
  }

  /**
   * Hide field preview
   */
  hideFieldPreview() {
    const previewDiv = document.getElementById('ai-preview');
    previewDiv.classList.add('hidden');
    this.previewFields = null;
    this.previewContext = null;
  }

  /**
   * Create fields from preview
   */
  async handleCreateFieldsFromPreview() {
    if (!this.previewFields || !this.previewContext) {
      this.showNotification('No fields to create', 'error');
      return;
    }

    const createBtn = document.getElementById('create-fields-btn');
    const originalText = createBtn.textContent;

    createBtn.disabled = true;
    createBtn.textContent = 'Creating...';

    // Show progress
    const progressDiv = document.getElementById('ai-progress');
    const progressContent = document.getElementById('ai-progress-content');
    progressDiv.classList.remove('hidden');
    progressContent.innerHTML = '';

    try {
      this.addProgressStep('create', `Creating ${this.previewFields.length} fields...`, 'processing');

      const createResponse = await chrome.runtime.sendMessage({
        type: 'ai_create_fields_batch',
        orgId: this.previewContext.orgId,
        sectionId: this.previewContext.sectionId,
        fields: this.previewFields
      });

      if (!createResponse.success) {
        throw new Error('Failed to create fields');
      }

      this.updateProgressStep('create', 'success',
        `Created ${createResponse.successCount} fields successfully` +
        (createResponse.failureCount > 0 ? `, ${createResponse.failureCount} failed` : '')
      );

      // Show details
      createResponse.results.forEach((result, index) => {
        const status = result.success ? 'success' : 'error';
        const message = result.success
          ? `${result.field.name} (ID: ${result.result.id})`
          : `${result.field.name}: ${result.error}`;

        this.addProgressStep(`field-${index}`, message, status);
      });

      this.showNotification('Fields created successfully!', 'success');

      // Hide preview and clear stored data
      this.hideFieldPreview();

      // Reset the AI builder form
      const aiBuilderForm = document.getElementById('ai-builder-form');
      if (aiBuilderForm) {
        aiBuilderForm.reset();
      }

      // Hide progress after a delay
      setTimeout(() => {
        progressDiv.classList.add('hidden');
      }, 3000);

    } catch (error) {
      console.error('[Sidebar] Create fields error:', error);

      const lastStep = progressContent.lastElementChild;
      if (lastStep && lastStep.classList.contains('processing')) {
        this.updateProgressStep(lastStep.dataset.stepId, 'error', error.message);
      } else {
        this.addProgressStep('error', error.message, 'error');
      }

      this.showNotification('Failed to create fields', 'error');
    } finally {
      createBtn.disabled = false;
      createBtn.textContent = originalText;
    }
  }
}

// Initialize when DOM is ready
document.addEventListener('DOMContentLoaded', () => {
  const sidebar = new SidebarController();
  sidebar.init();
});
