New changes: // manifest.json
{
  "manifest_version": 3,
  "name": "Enhanced CORS Handler Pro",
  "version": "2.0",
  "description": "Advanced CORS handling with full customization and real-time feedback",
  "permissions": [
    "declarativeNetRequest",
    "activeTab",
    "storage",
    "webNavigation"
  ],
  "host_permissions": [
    "<all_urls>"
  ],
  "action": {
    "default_popup": "popup.html",
    "default_icon": {
      "16": "icons/icon16-off.png",
      "48": "icons/icon48-off.png",
      "128": "icons/icon128-off.png"
    }
  },
  "background": {
    "service_worker": "background.js",
    "type": "module"
  },
  "icons": {
    "16": "icons/icon16-off.png",
    "48": "icons/icon48-off.png",
    "128": "icons/icon128-off.png"
  }
}

// background.js
const defaultConfig = {
  enabled: false,
  responseHeaders: [
    { name: "Access-Control-Allow-Origin", value: "*", enabled: true, priority: 100 },
    { name: "Access-Control-Allow-Methods", value: "GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS", enabled: true, priority: 90 },
    { name: "Access-Control-Allow-Headers", value: "*", enabled: true, priority: 80 },
    { name: "Access-Control-Allow-Credentials", value: "true", enabled: true, priority: 70 },
    { name: "Access-Control-Expose-Headers", value: "*", enabled: true, priority: 60 },
    { name: "Access-Control-Max-Age", value: "86400", enabled: true, priority: 50 },
    { name: "Cross-Origin-Opener-Policy", value: "same-origin", enabled: true, priority: 40 },
    { name: "Cross-Origin-Resource-Policy", value: "cross-origin", enabled: true, priority: 30 },
    { name: "Cross-Origin-Embedder-Policy", value: "require-corp", enabled: true, priority: 20 },
    { name: "Timing-Allow-Origin", value: "*", enabled: true, priority: 10 }
  ],
  requestHeaders: [
    { name: "Origin", value: "null", enabled: true, priority: 100 },
    { name: "Access-Control-Request-Method", value: "*", enabled: true, priority: 90 },
    { name: "Access-Control-Request-Headers", value: "*", enabled: true, priority: 80 }
  ],
  urlRules: [
    { pattern: "*://*/*", enabled: true, resourceTypes: ["all"], priority: 100 }
  ],
  advanced: {
    enablePreflightCaching: true,
    preflightMaxAge: 86400,
    allowCredentials: true,
    allowPrivateNetwork: true,
    enableDebugHeaders: false
  }
};

class CORSHandler {
  constructor() {
    this.currentConfig = null;
    this.activeTabId = null;
    this.activeOrigin = null;
    this.ruleIdCounter = 1000;
    this.initialize();
  }

  async initialize() {
    const config = await this.loadConfig();
    await this.updateRules(config);
    this.setupListeners();
  }

  async loadConfig() {
    try {
      const result = await chrome.storage.local.get('corsConfig');
      this.currentConfig = result.corsConfig || structuredClone(defaultConfig);
      return this.currentConfig;
    } catch (error) {
      this.currentConfig = structuredClone(defaultConfig);
      return this.currentConfig;
    }
  }

  setupListeners() {
    chrome.runtime.onMessage.addListener(this.handleMessage.bind(this));
    chrome.webNavigation.onBeforeNavigate.addListener(this.handleNavigation.bind(this));
    chrome.tabs.onActivated.addListener(this.handleTabChange.bind(this));
  }

  async handleMessage(message, sender, sendResponse) {
    switch (message.type) {
      case 'updateRules':
        await this.updateRules(message.config);
        break;
      case 'getStatus':
        sendResponse({
          enabled: this.currentConfig.enabled,
          activeOrigin: this.activeOrigin,
          activeRules: await this.getActiveRules()
        });
        break;
    }
  }

  async handleNavigation(details) {
    if (details.frameId === 0) {
      this.activeTabId = details.tabId;
      this.activeOrigin = new URL(details.url).origin;
      await this.updateBadge();
    }
  }

  async handleTabChange(activeInfo) {
    const tab = await chrome.tabs.get(activeInfo.tabId);
    if (tab.url) {
      this.activeTabId = tab.id;
      this.activeOrigin = new URL(tab.url).origin;
      await this.updateBadge();
    }
  }

  async updateRules(config) {
    if (!config) return;
    
    try {
      // Remove existing rules
      const existingRules = await chrome.declarativeNetRequest.getDynamicRules();
      await chrome.declarativeNetRequest.updateDynamicRules({
        removeRuleIds: existingRules.map(rule => rule.id)
      });

      if (!config.enabled) {
        await this.updateIcon(false);
        return;
      }

      // Create and apply new rules
      const rules = this.createRules(config);
      await chrome.declarativeNetRequest.updateDynamicRules({
        addRules: rules
      });

      this.currentConfig = config;
      await this.updateIcon(true);
      await this.updateBadge();
    } catch (error) {
      console.error('Error updating rules:', error);
    }
  }

  createRules(config) {
    const rules = [];

    config.urlRules.forEach(urlRule => {
      if (!urlRule.enabled) return;

      // Prepare headers
      const responseHeaders = config.responseHeaders
        .filter(h => h.enabled)
        .sort((a, b) => b.priority - a.priority)
        .map(h => ({
          header: h.name,
          operation: "set",
          value: this.processHeaderValue(h.name, h.value)
        }));

      const requestHeaders = config.requestHeaders
        .filter(h => h.enabled)
        .sort((a, b) => b.priority - a.priority)
        .map(h => ({
          header: h.name,
          operation: "set",
          value: this.processHeaderValue(h.name, h.value)
        }));

      // Add preflight handling rule
      rules.push({
        id: this.ruleIdCounter++,
        priority: urlRule.priority,
        action: {
          type: "modifyHeaders",
          responseHeaders: responseHeaders,
          requestHeaders: requestHeaders
        },
        condition: {
          urlFilter: urlRule.pattern,
          resourceTypes: urlRule.resourceTypes === "all" ? [
            "main_frame",
            "sub_frame",
            "stylesheet",
            "script",
            "image",
            "font",
            "object",
            "xmlhttprequest",
            "ping",
            "csp_report",
            "media",
            "websocket",
            "webtransport",
            "webbundle",
            "other"
          ] : urlRule.resourceTypes,
        }
      });

      // Add special handling for OPTIONS requests
      if (config.advanced.enablePreflightCaching) {
        rules.push({
          id: this.ruleIdCounter++,
          priority: urlRule.priority + 1,
          action: {
            type: "modifyHeaders",
            responseHeaders: [
              ...responseHeaders,
              {
                header: "Access-Control-Max-Age",
                operation: "set",
                value: config.advanced.preflightMaxAge.toString()
              }
            ]
          },
          condition: {
            urlFilter: urlRule.pattern,
            resourceTypes: ["main_frame", "sub_frame", "xmlhttprequest", "websocket"],
            requestMethods: ["OPTIONS"]
          }
        });
      }
    });

    return rules;
  }

  processHeaderValue(name, value) {
    // Special processing for certain headers
    switch (name.toLowerCase()) {
      case 'access-control-allow-origin':
        return value === '*' && this.currentConfig.advanced.allowCredentials ? this.activeOrigin || '*' : value;
      case 'access-control-allow-credentials':
        return this.currentConfig.advanced.allowCredentials.toString();
      case 'access-control-allow-private-network':
        return this.currentConfig.advanced.allowPrivateNetwork.toString();
      default:
        return value;
    }
  }

  async getActiveRules() {
    try {
      return await chrome.declarativeNetRequest.getDynamicRules();
    } catch (error) {
      return [];
    }
  }

  async updateIcon(enabled) {
    const iconState = enabled ? "-on" : "-off";
    await chrome.action.setIcon({
      path: {
        "16": `icons/icon16${iconState}.png`,
        "48": `icons/icon48${iconState}.png`,
        "128": `icons/icon128${iconState}.png`
      }
    });
  }

  async updateBadge() {
    if (!this.currentConfig.enabled) {
      await chrome.action.setBadgeText({ text: "" });
      return;
    }

    const activeRules = await this.getActiveRules();
    await chrome.action.setBadgeText({ 
      text: activeRules.length.toString()
    });
    await chrome.action.setBadgeBackgroundColor({ 
      color: "#4CAF50"
    });
  }
}

// Initialize the CORS handler
const handler = new CORSHandler();

// popup.js modifications (only showing new/modified parts)
class CORSPopupManager {
  constructor() {
    this.config = null;
    this.initialize();
  }

  async initialize() {
    await this.loadConfig();
    this.setupEventListeners();
    this.setupAdvancedSettings();
    this.startStatusUpdates();
  }

  setupAdvancedSettings() {
    const advancedSection = document.createElement('div');
    advancedSection.className = 'advanced-settings';
    advancedSection.innerHTML = `
      <h3>Advanced Settings</h3>
      <div class="setting-item">
        <label>
          <input type="checkbox" id="enablePreflightCaching">
          Enable Preflight Caching
        </label>
      </div>
      <div class="setting-item">
        <label>
          <input type="checkbox" id="allowCredentials">
          Allow Credentials
        </label>
      </div>
      <div class="setting-item">
        <label>
          <input type="checkbox" id="allowPrivateNetwork">
          Allow Private Network Access
        </label>
      </div>
      <div class="setting-item">
        <label>
          <input type="checkbox" id="enableDebugHeaders">
          Enable Debug Headers
        </label>
      </div>
      <div class="setting-item">
        <label>
          Preflight Max Age (seconds)
          <input type="number" id="preflightMaxAge" min="0" max="86400">
        </label>
      </div>
    `;
    
    document.querySelector('.settings-container').appendChild(advancedSection);
  }

  startStatusUpdates() {
    const updateStatus = async () => {
      const status = await chrome.runtime.sendMessage({ type: 'getStatus' });
      this.updateStatusDisplay(status);
    };

    updateStatus();
    setInterval(updateStatus, 1000);
  }

  updateStatusDisplay(status) {
    const statusDiv = document.getElementById('currentStatus');
    if (!statusDiv) return;

    statusDiv.innerHTML = `
      <div class="status-item">
        <span class="status-label">Status:</span>
        <span class="status-value ${status.enabled ? 'enabled' : 'disabled'}">
          ${status.enabled ? 'Active' : 'Inactive'}
        </span>
      </div>
      <div class="status-item">
        <span class="status-label">Active Origin:</span>
        <span class="status-value">${status.activeOrigin || 'None'}</span>
      </div>
      <div class="status-item">
        <span class="status-label">Active Rules:</span>
        <span class="status-value">${status.activeRules.length}</span>
      </div>
    `;
  }
}

// Additional CSS for popup.css
.advanced-settings {
  margin-top: 20px;
  padding: 16px;
  background: #f8f8f8;
  border-radius: 4px;
}

.setting-item {
  margin-bottom: 12px;
}

.status-item {
  display: flex;
  justify-content: space-between;
  margin-bottom: 8px;
}

.status-value.enabled {
  color: #4CAF50;
}

.status-value.disabled {
  color: #ff4444;
}

.debug-panel {
  margin-top: 16px;
  padding: 12px;
  background: #f0f0f0;
  border-radius: 4px;
  font-family: monospace;
  font-size: 12px;
}
 Main codes:
{
  "manifest_version": 3,
  "name": "Advanced CORS Handler",
  "version": "1.2",
  "description": "Powerful CORS handling with full customization for development",
  "permissions": [
    "declarativeNetRequest",
    "activeTab",
    "storage"
  ],
  "host_permissions": [
    "<all_urls>"
  ],
  "action": {
    "default_popup": "popup.html",
    "default_icon": {
      "16": "icons/icon16-off.png",
      "48": "icons/icon48-off.png",
      "128": "icons/icon128-off.png"
    }
  },
  "background": {
    "service_worker": "background.js"
  },
  "icons": {
    "16": "icons/icon16-off.png",
    "48": "icons/icon48-off.png",
    "128": "icons/icon128-off.png"
  }
} <!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>CORS Handler Settings</title>
  <link rel="stylesheet" href="popup.css">
</head>
<body>
  <div class="container">
    <div class="header">
      <h2>CORS Handler</h2>
      <div class="toggle-container">
        <label class="switch">
          <input type="checkbox" id="globalToggle">
          <span class="slider"></span>
        </label>
        <span id="statusText">Disabled</span>
      </div>
    </div>

    <div class="settings-container">
      <div class="tab-container">
        <button class="tab-button active" data-tab="response">Response Headers</button>
        <button class="tab-button" data-tab="request">Request Headers</button>
        <button class="tab-button" data-tab="rules">URL Rules</button>
      </div>

      <div class="tab-content active" id="response">
        <div class="header-list" id="responseHeaders">
          <!-- Dynamically populated -->
        </div>
        <button class="add-header" id="addResponseHeader">+ Add Response Header</button>
      </div>

      <div class="tab-content" id="request">
        <div class="header-list" id="requestHeaders">
          <!-- Dynamically populated -->
        </div>
        <button class="add-header" id="addRequestHeader">+ Add Request Header</button>
      </div>

      <div class="tab-content" id="rules">
        <div class="url-rules" id="urlRules">
          <!-- Dynamically populated -->
        </div>
        <button class="add-rule" id="addUrlRule">+ Add URL Rule</button>
      </div>
    </div>

    <div class="footer">
      <button id="saveButton">Save Changes</button>
      <button id="resetDefault">Reset to Default</button>
    </div>
  </div>
  <script src="popup.js"></script>
</body>
</html> .container {
  width: 400px;
  padding: 16px;
  font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Roboto;
}

.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.toggle-container {
  display: flex;
  align-items: center;
  gap: 8px;
}

.switch {
  position: relative;
  display: inline-block;
  width: 48px;
  height: 24px;
}

.switch input {
  opacity: 0;
  width: 0;
  height: 0;
}

.slider {
  position: absolute;
  cursor: pointer;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: #ccc;
  transition: .4s;
  border-radius: 24px;
}

.slider:before {
  position: absolute;
  content: "";
  height: 18px;
  width: 18px;
  left: 3px;
  bottom: 3px;
  background-color: white;
  transition: .4s;
  border-radius: 50%;
}

input:checked + .slider {
  background-color: #2196F3;
}

input:checked + .slider:before {
  transform: translateX(24px);
}

.tab-container {
  display: flex;
  gap: 8px;
  margin-bottom: 16px;
}

.tab-button {
  padding: 8px 16px;
  border: none;
  background: #f0f0f0;
  cursor: pointer;
  border-radius: 4px;
}

.tab-button.active {
  background: #2196F3;
  color: white;
}

.tab-content {
  display: none;
  padding: 16px;
  background: #f8f8f8;
  border-radius: 4px;
  max-height: 300px;
  overflow-y: auto;
}

.tab-content.active {
  display: block;
}

.header-item {
  display: flex;
  gap: 8px;
  margin-bottom: 12px;
  align-items: center;
  position: relative;
}

.header-item input[type="text"] {
  padding: 6px;
  border: 1px solid #ddd;
  border-radius: 4px;
  flex: 1;
}

.header-item input[type="text"].invalid {
  border-color: #ff4444;
}

.header-item .error-message {
  color: #ff4444;
  font-size: 12px;
  position: absolute;
  top: 100%;
  left: 0;
}

.remove-button {
  padding: 4px 8px;
  background: #ff4444;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.add-header, .add-rule {
  width: 100%;
  padding: 8px;
  margin-top: 12px;
  background: #2196F3;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.footer {
  margin-top: 20px;
  display: flex;
  justify-content: space-between;
}

.footer button {
  padding: 8px 16px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

#saveButton {
  background: #4CAF50;
  color: white;
}

#resetDefault {
  background: #f0f0f0;
}

.disabled {
  opacity: 0.6;
  cursor: not-allowed;
} // popup.js

const defaultConfig = {
  enabled: false,
  responseHeaders: [
    { name: "Access-Control-Allow-Origin", value: "*", enabled: true },
    { name: "Access-Control-Allow-Methods", value: "GET, PUT, POST, DELETE, HEAD, OPTIONS, PATCH", enabled: true },
    { name: "Access-Control-Allow-Headers", value: "*", enabled: true },
    { name: "Access-Control-Allow-Credentials", value: "false", enabled: true },
    { name: "Access-Control-Expose-Headers", value: "*", enabled: true },
    { name: "Access-Control-Max-Age", value: "1728000", enabled: true },
    { name: "Cross-Origin-Resource-Policy", value: "cross-origin", enabled: true },
    { name: "Cross-Origin-Embedder-Policy", value: "credentialless", enabled: true }
  ],
  requestHeaders: [
    { name: "Origin", value: "https://allowed-origin.com", enabled: true },
    { name: "Access-Control-Request-Method", value: "*", enabled: true },
    { name: "Access-Control-Request-Headers", value: "*", enabled: true }
  ],
  urlRules: [
    { pattern: "*://*/*", enabled: true }
  ]
};

let currentConfig = null;
let hasValidationErrors = false;

// Load configuration
async function loadConfig() {
  try {
    const result = await chrome.storage.local.get('corsConfig');
    currentConfig = result.corsConfig || JSON.parse(JSON.stringify(defaultConfig));
    renderUI();
  } catch (error) {
    console.error('Error loading configuration:', error);
    currentConfig = JSON.parse(JSON.stringify(defaultConfig));
    renderUI();
  }
}

// Save configuration
async function saveConfig() {
  if (hasValidationErrors) {
    alert("Please fix validation errors before saving.");
    return;
  }

  // Additional cross-field validation
  if (!validateCrossHeaders()) {
    alert("Invalid configuration: 'Access-Control-Allow-Origin' cannot be '*' when 'Access-Control-Allow-Credentials' is 'true'. Please adjust accordingly.");
    return;
  }

  try {
    await chrome.storage.local.set({ corsConfig: currentConfig });
    await updateExtensionRules();
    showSaveSuccess();
  } catch (error) {
    console.error('Error saving configuration:', error);
    showSaveError();
  }
}

// Validate cross-header dependencies
function validateCrossHeaders() {
  const allowOriginHeader = currentConfig.responseHeaders.find(header => header.name.toLowerCase() === 'access-control-allow-origin' && header.enabled);
  const allowCredentialsHeader = currentConfig.responseHeaders.find(header => header.name.toLowerCase() === 'access-control-allow-credentials' && header.enabled);

  if (allowOriginHeader && allowCredentialsHeader) {
    if (allowOriginHeader.value.trim() === '*' && allowCredentialsHeader.value.toLowerCase() === 'true') {
      return false;
    }
  }
  return true;
}

// Update extension rules
async function updateExtensionRules() {
  const message = {
    type: 'updateRules',
    config: currentConfig
  };
  await chrome.runtime.sendMessage(message);
}

// UI Rendering
function renderUI() {
  const globalToggle = document.getElementById('globalToggle');
  globalToggle.checked = currentConfig.enabled;
  document.getElementById('statusText').textContent = currentConfig.enabled ? 'Enabled' : 'Disabled';

  renderHeaderList('responseHeaders');
  renderHeaderList('requestHeaders');
  renderUrlRules();

  toggleEnableControls(currentConfig.enabled);
}

function renderHeaderList(type) {
  const container = document.getElementById(type);
  container.innerHTML = '';

  currentConfig[type].forEach((header, index) => {
    const headerItem = createHeaderItem(header, index, type);
    container.appendChild(headerItem);
  });
}

function createHeaderItem(header, index, type) {
  const div = document.createElement('div');
  div.className = 'header-item';

  const enabledCheckbox = document.createElement('input');
  enabledCheckbox.type = 'checkbox';
  enabledCheckbox.checked = header.enabled;
  enabledCheckbox.onchange = () => {
    currentConfig[type][index].enabled = enabledCheckbox.checked;
    validateAllHeaders();
  };

  const nameInput = document.createElement('input');
  nameInput.type = 'text';
  nameInput.value = header.name;
  nameInput.placeholder = 'Header Name';
  nameInput.oninput = () => {
    currentConfig[type][index].name = nameInput.value;
    validateHeaderInput(nameInput, type, index);
    validateAllHeaders();
  };

  const valueInput = document.createElement('input');
  valueInput.type = 'text';
  valueInput.value = header.value;
  valueInput.placeholder = 'Header Value';
  valueInput.oninput = () => {
    currentConfig[type][index].value = valueInput.value;
    validateHeaderInput(valueInput, type, index);
    validateAllHeaders();
  };

  const removeButton = document.createElement('button');
  removeButton.textContent = '×';
  removeButton.className = 'remove-button';
  removeButton.onclick = () => {
    currentConfig[type].splice(index, 1);
    renderHeaderList(type);
    validateAllHeaders();
  };

  div.appendChild(enabledCheckbox);
  div.appendChild(nameInput);
  div.appendChild(valueInput);
  div.appendChild(removeButton);

  // Error message container
  const errorMsg = document.createElement('div');
  errorMsg.className = 'error-message';
  errorMsg.style.display = 'none';
  div.appendChild(errorMsg);

  return div;
}

function renderUrlRules() {
  const container = document.getElementById('urlRules');
  container.innerHTML = '';

  currentConfig.urlRules.forEach((rule, index) => {
    const ruleItem = createUrlRuleItem(rule, index);
    container.appendChild(ruleItem);
  });
}

function createUrlRuleItem(rule, index) {
  const div = document.createElement('div');
  div.className = 'header-item';

  const enabledCheckbox = document.createElement('input');
  enabledCheckbox.type = 'checkbox';
  enabledCheckbox.checked = rule.enabled;
  enabledCheckbox.onchange = () => {
    currentConfig.urlRules[index].enabled = enabledCheckbox.checked;
    validateUrlRuleInput(patternInput);
  };

  const patternInput = document.createElement('input');
  patternInput.type = 'text';
  patternInput.value = rule.pattern;
  patternInput.placeholder = 'URL Pattern (e.g., *://*.example.com/*)';
  patternInput.oninput = () => {
    currentConfig.urlRules[index].pattern = patternInput.value;
    validateUrlRuleInput(patternInput);
    validateAllHeaders();
  };

  const removeButton = document.createElement('button');
  removeButton.textContent = '×';
  removeButton.className = 'remove-button';
  removeButton.onclick = () => {
    currentConfig.urlRules.splice(index, 1);
    renderUrlRules();
    validateAllHeaders();
  };

  div.appendChild(enabledCheckbox);
  div.appendChild(patternInput);
  div.appendChild(removeButton);

  // Error message container
  const errorMsg = document.createElement('div');
  errorMsg.className = 'error-message';
  errorMsg.style.display = 'none';
  div.appendChild(errorMsg);

  return div;
}

// Enable or disable controls based on global toggle
function toggleEnableControls(enabled) {
  const addButtons = document.querySelectorAll('.add-header, .add-rule');
  addButtons.forEach(button => {
    if (enabled) {
      button.disabled = false;
      button.classList.remove('disabled');
    } else {
      button.disabled = true;
      button.classList.add('disabled');
    }
  });

  const inputs = document.querySelectorAll('.header-item input[type="text"]');
  inputs.forEach(input => {
    if (enabled) {
      input.disabled = false;
      input.classList.remove('disabled');
    } else {
      input.disabled = true;
      input.classList.add('disabled');
    }
  });

  const checkboxes = document.querySelectorAll('.header-item input[type="checkbox"]');
  checkboxes.forEach(checkbox => {
    if (enabled) {
      checkbox.disabled = false;
      checkbox.classList.remove('disabled');
    } else {
      checkbox.disabled = true;
      checkbox.classList.add('disabled');
    }
  });
}

// Event Handlers
document.getElementById('globalToggle').addEventListener('change', async (e) => {
  currentConfig.enabled = e.target.checked;
  document.getElementById('statusText').textContent = currentConfig.enabled ? 'Enabled' : 'Disabled';
  toggleEnableControls(currentConfig.enabled);
  await saveConfig();
});

document.getElementById('addResponseHeader').addEventListener('click', () => {
  currentConfig.responseHeaders.push({ name: '', value: '', enabled: true });
  renderHeaderList('responseHeaders');
});

document.getElementById('addRequestHeader').addEventListener('click', () => {
  currentConfig.requestHeaders.push({ name: '', value: '', enabled: true });
  renderHeaderList('requestHeaders');
});

document.getElementById('addUrlRule').addEventListener('click', () => {
  currentConfig.urlRules.push({ pattern: '*://*/*', enabled: true });
  renderUrlRules();
});

document.getElementById('saveButton').addEventListener('click', saveConfig);

document.getElementById('resetDefault').addEventListener('click', () => {
  currentConfig = JSON.parse(JSON.stringify(defaultConfig));
  renderUI();
  saveConfig();
});

// Tab Handling
document.querySelectorAll('.tab-button').forEach(button => {
  button.addEventListener('click', () => {
    document.querySelectorAll('.tab-button').forEach(b => b.classList.remove('active'));
    document.querySelectorAll('.tab-content').forEach(c => c.classList.remove('active'));
    button.classList.add('active');
    document.getElementById(button.dataset.tab).classList.add('active');
  });
});

// Initialize
document.addEventListener('DOMContentLoaded', loadConfig);

// Validation Functions

function validateHeaderInput(inputElement, type, index) {
  const header = currentConfig[type][index];
  const errorMsg = inputElement.parentElement.querySelector('.error-message');

  if (!validateHeaderName(header.name)) {
    inputElement.classList.add('invalid');
    errorMsg.textContent = 'Invalid header name.';
    errorMsg.style.display = 'block';
    hasValidationErrors = true;
    return;
  } else if (!validateHeaderValue(header.name, header.value)) {
    inputElement.classList.add('invalid');
    errorMsg.textContent = 'Invalid header value.';
    errorMsg.style.display = 'block';
    hasValidationErrors = true;
    return;
  } else {
    inputElement.classList.remove('invalid');
    errorMsg.textContent = '';
    errorMsg.style.display = 'none';
  }
}

function validateUrlRuleInput(inputElement) {
  const pattern = inputElement.value.trim();
  const errorMsg = inputElement.parentElement.querySelector('.error-message');

  if (!validateURLPattern(pattern)) {
    inputElement.classList.add('invalid');
    errorMsg.textContent = 'Invalid URL pattern.';
    errorMsg.style.display = 'block';
    hasValidationErrors = true;
    return;
  } else {
    inputElement.classList.remove('invalid');
    errorMsg.textContent = '';
    errorMsg.style.display = 'none';
  }
}

function validateAllHeaders() {
  hasValidationErrors = false;

  // Validate response headers
  currentConfig.responseHeaders.forEach((header, index) => {
    if (header.enabled) {
      validateHeaderNameValue(header, 'responseHeaders', index);
    }
  });

  // Validate request headers
  currentConfig.requestHeaders.forEach((header, index) => {
    if (header.enabled) {
      validateHeaderNameValue(header, 'requestHeaders', index);
    }
  });

  // Validate URL rules
  currentConfig.urlRules.forEach((rule, index) => {
    if (rule.enabled) {
      const pattern = rule.pattern.trim();
      const valid = validateURLPattern(pattern);
      const urlRuleElements = document.getElementById('urlRules').children;
      const inputElement = urlRuleElements[index].querySelector('input[type="text"]');
      const errorMsg = urlRuleElements[index].querySelector('.error-message');

      if (!valid) {
        inputElement.classList.add('invalid');
        errorMsg.textContent = 'Invalid URL pattern.';
        errorMsg.style.display = 'block';
        hasValidationErrors = true;
      } else {
        inputElement.classList.remove('invalid');
        errorMsg.textContent = '';
        errorMsg.style.display = 'none';
      }
    }
  });
}

function validateHeaderNameValue(header, type, index) {
  const container = type === 'responseHeaders' ? document.getElementById('responseHeaders') : document.getElementById('requestHeaders');
  const headerElement = container.children[index];
  const nameInput = headerElement.querySelector('input[type="text"]');
  const valueInput = headerElement.querySelectorAll('input[type="text"]')[1];
  const errorMsg = headerElement.querySelector('.error-message');

  if (!validateHeaderName(header.name)) {
    nameInput.classList.add('invalid');
    errorMsg.textContent = 'Invalid header name.';
    errorMsg.style.display = 'block';
    hasValidationErrors = true;
    return;
  }

  if (!validateHeaderValue(header.name, header.value)) {
    valueInput.classList.add('invalid');
    errorMsg.textContent = 'Invalid header value.';
    errorMsg.style.display = 'block';
    hasValidationErrors = true;
    return;
  }

  nameInput.classList.remove('invalid');
  valueInput.classList.remove('invalid');
  errorMsg.textContent = '';
  errorMsg.style.display = 'none';
}

// Header Name Validation
function validateHeaderName(name) {
  const regex = /^[a-zA-Z0-9\-]+$/;
  return regex.test(name.trim());
}

// Header Value Validation
function validateHeaderValue(headerName, value) {
  headerName = headerName.toLowerCase();
  value = value.trim();

  const standardHeaders = {
    'access-control-allow-origin': validateAllowOrigin,
    'access-control-allow-methods': validateAllowMethods,
    'access-control-allow-headers': validateAllowHeaders,
    'access-control-allow-credentials': validateAllowCredentials,
    'access-control-expose-headers': validateExposeHeaders,
    'access-control-max-age': validateMaxAge,
    'cross-origin-resource-policy': validateResourcePolicy,
    'cross-origin-embedder-policy': validateEmbedderPolicy
  };

  if (standardHeaders[headerName]) {
    return standardHeaders[headerName](value);
  }

  // Allow custom headers with basic validation
  return /^[\w\-]+$/.test(value);
}

// Specific Header Validations

function validateAllowOrigin(value) {
  if (value === '*') return true;
  try {
    const url = new URL(value);
    return true;
  } catch {
    return false;
  }
}

function validateAllowMethods(value) {
  const validMethods = ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'PATCH', 'HEAD'];
  const methods = value.split(',').map(m => m.trim().toUpperCase());
  return methods.every(m => validMethods.includes(m) || m === '*');
}

function validateAllowHeaders(value) {
  if (value === '*') return true;
  const headers = value.split(',').map(h => h.trim());
  return headers.every(h => /^[a-zA-Z0-9\-]+$/.test(h));
}

function validateAllowCredentials(value) {
  return value.toLowerCase() === 'true' || value.toLowerCase() === 'false';
}

function validateExposeHeaders(value) {
  if (value === '*') return true;
  const headers = value.split(',').map(h => h.trim());
  return headers.every(h => /^[a-zA-Z0-9\-]+$/.test(h));
}

function validateMaxAge(value) {
  const num = parseInt(value, 10);
  return !isNaN(num) && num >= 0;
}

function validateResourcePolicy(value) {
  const validPolicies = ['cross-origin', 'same-origin', 'same-site'];
  return validPolicies.includes(value.toLowerCase());
}

function validateEmbedderPolicy(value) {
  const validPolicies = ['require-corp', 'credentialless'];
  return validPolicies.includes(value.toLowerCase());
}

// URL Pattern Validation
function validateURLPattern(pattern) {
  // Basic validation: must include scheme and wildcard properly
  const regex = /^(\*\:\/\/|\w+\:\/\/)(\*\.)?[\w\-\.]+\.\w+(\/*)*$/;
  return regex.test(pattern);
}

// Utility Functions

function showSaveSuccess() {
  const saveButton = document.getElementById('saveButton');
  const originalText = saveButton.textContent;
  saveButton.textContent = '✓ Saved';
  saveButton.style.backgroundColor = '#4CAF50';
  saveButton.disabled = true;

  setTimeout(() => {
    saveButton.textContent = originalText;
    saveButton.style.backgroundColor = '';
    saveButton.disabled = false;
  }, 2000);
}

function showSaveError() {
  const saveButton = document.getElementById('saveButton');
  const originalText = saveButton.textContent;
  saveButton.textContent = '× Error';
  saveButton.style.backgroundColor = '#ff4444';
  saveButton.disabled = true;

  setTimeout(() => {
    saveButton.textContent = originalText;
    saveButton.style.backgroundColor = '';
    saveButton.disabled = false;
  }, 2000);
} // background.js

// Define defaultConfig in background.js to ensure it's available in the service worker
const defaultConfig = {
  enabled: false,
  responseHeaders: [
    { name: "Access-Control-Allow-Origin", value: "*", enabled: true },
    { name: "Access-Control-Allow-Methods", value: "GET, PUT, POST, DELETE, HEAD, OPTIONS, PATCH", enabled: true },
    { name: "Access-Control-Allow-Headers", value: "*", enabled: true },
    { name: "Access-Control-Allow-Credentials", value: "false", enabled: true },
    { name: "Access-Control-Expose-Headers", value: "*", enabled: true },
    { name: "Access-Control-Max-Age", value: "1728000", enabled: true },
    { name: "Cross-Origin-Resource-Policy", value: "cross-origin", enabled: true },
    { name: "Cross-Origin-Embedder-Policy", value: "credentialless", enabled: true }
  ],
  requestHeaders: [
    { name: "Origin", value: "https://allowed-origin.com", enabled: true },
    { name: "Access-Control-Request-Method", value: "*", enabled: true },
    { name: "Access-Control-Request-Headers", value: "*", enabled: true }
  ],
  urlRules: [
    { pattern: "*://*/*", enabled: true }
  ]
};

let currentRules = [];
const RULE_ID_START = 1000; // Start from a higher number to avoid conflicts

// Listen for messages from popup.js
chrome.runtime.onMessage.addListener(async (message, sender, sendResponse) => {
  if (message.type === 'updateRules') {
    await updateRules(message.config);
  }
});

// Function to update rules based on config
async function updateRules(config) {
  try {
    // Remove existing rules
    const existingRules = await chrome.declarativeNetRequest.getDynamicRules();
    const ruleIdsToRemove = existingRules.map(rule => rule.id);
    await chrome.declarativeNetRequest.updateDynamicRules({
      removeRuleIds: ruleIdsToRemove,
      addRules: []
    });

    if (!config.enabled) {
      await updateIcon(false);
      return;
    }

    // Create new rules
    const newRules = createRulesFromConfig(config);
    await chrome.declarativeNetRequest.updateDynamicRules({
      addRules: newRules
    });

    await updateIcon(true);
  } catch (error) {
    // Silently fail to avoid unnecessary logging
  }
}

// Function to create rules from config
function createRulesFromConfig(config) {
  const rules = [];
  let ruleId = RULE_ID_START;

  config.urlRules.forEach(urlRule => {
    if (!urlRule.enabled) return;

    const responseHeadersToModify = config.responseHeaders
      .filter(header => header.enabled)
      .map(header => ({
        header: header.name,
        operation: "set",
        value: header.value
      }));

    const requestHeadersToModify = config.requestHeaders
      .filter(header => header.enabled)
      .map(header => ({
        header: header.name,
        operation: "set",
        value: header.value
      }));

    rules.push({
      id: ruleId++,
      priority: 1,
      action: {
        type: "modifyHeaders",
        responseHeaders: responseHeadersToModify,
        requestHeaders: requestHeadersToModify
      },
      condition: {
        urlFilter: urlRule.pattern,
        resourceTypes: [
          "xmlhttprequest",
          "fetch",
          "websocket",
          "other",
          "main_frame",
          "sub_frame",
          "script",
          "image",
          "stylesheet",
          "font"
        ]
      }
    });
  });

  return rules;
}

// Function to update the extension icon based on enabled state
async function updateIcon(enabled) {
  const iconState = enabled ? "-on" : "-off";
  await chrome.action.setIcon({
    path: {
      "16": `icons/icon16${iconState}.png`,
      "48": `icons/icon48${iconState}.png`,
      "128": `icons/icon128${iconState}.png`
    }
  });
}

// Initialize extension state on installation
chrome.runtime.onInstalled.addListener(async () => {
  try {
    const result = await chrome.storage.local.get('corsConfig');
    const config = result.corsConfig || JSON.parse(JSON.stringify(defaultConfig));

    await chrome.storage.local.set({ corsConfig: config });
    await updateRules(config);
  } catch (error) {
    // Silently fail to avoid unnecessary logging
  }
});

// Handle startup
chrome.runtime.onStartup.addListener(async () => {
  try {
    const result = await chrome.storage.local.get('corsConfig');
    const config = result.corsConfig || JSON.parse(JSON.stringify(defaultConfig));

    await updateRules(config);
  } catch (error) {
    // Silently fail to avoid unnecessary logging
  }
});