document.addEventListener('DOMContentLoaded', () => {
  let selectedIndex = null;

  const getTab = async (zoneId) => {
    const response = await fetch(`/zones/${zoneId}`, {
      headers: { Accept: 'application/json' },
    });
    if (!response.ok) {
      throw new Error('No zone found');
    }
    return response.json();
  };

  const saveTabColors = async (zoneId, colors) => {
    const response = await fetch(`/zones/${zoneId}`, {
      method: 'PUT',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ colors }),
    });
    if (!response.ok) {
      throw new Error('Failed to save zone colors');
    }
    return response.json();
  };

  const renderPalette = (paletteContainer, colors, onColorChange, onRemoveColor, onReorder) => {
    paletteContainer.innerHTML = '';
    if (!colors.length) {
      const empty = document.createElement('div');
      empty.className = 'muted-text';
      empty.textContent = 'No colors in palette.';
      paletteContainer.appendChild(empty);
      return;
    }

    colors.forEach((color, index) => {
      const swatch = document.createElement('div');
      swatch.className = 'color-swatch';
      swatch.draggable = true;
      swatch.dataset.index = String(index);
      if (index === selectedIndex) {
        swatch.classList.add('selected');
      }

      const preview = document.createElement('div');
      preview.className = 'color-swatch-preview';
      preview.style.backgroundColor = color;

      const label = document.createElement('span');
      label.className = 'color-swatch-label';
      label.textContent = color;

      const colorPicker = document.createElement('input');
      colorPicker.type = 'color';
      colorPicker.className = 'color-picker-input';
      colorPicker.value = color;
      colorPicker.addEventListener('change', async (event) => {
        const newColor = event.target.value;
        await onColorChange(index, newColor);
      });

      const removeButton = document.createElement('button');
      removeButton.className = 'btn btn-danger btn-small';
      removeButton.textContent = 'Remove';
      removeButton.addEventListener('click', async (event) => {
        event.stopPropagation();
        await onRemoveColor(index);
      });

      swatch.addEventListener('dragstart', (event) => {
        event.dataTransfer.setData('text/plain', String(index));
        event.dataTransfer.effectAllowed = 'move';
      });
      swatch.addEventListener('dragover', (event) => {
        event.preventDefault();
        event.dataTransfer.dropEffect = 'move';
      });
      swatch.addEventListener('drop', async (event) => {
        event.preventDefault();
        const fromIndex = parseInt(event.dataTransfer.getData('text/plain'), 10);
        const toIndex = parseInt(swatch.dataset.index || '-1', 10);
        if (Number.isNaN(fromIndex) || Number.isNaN(toIndex) || fromIndex === toIndex) {
          return;
        }
        await onReorder(fromIndex, toIndex);
      });

      swatch.appendChild(preview);
      swatch.appendChild(label);
      swatch.appendChild(colorPicker);
      swatch.appendChild(removeButton);
      swatch.addEventListener('click', () => {
        selectedIndex = index;
        renderPalette(paletteContainer, colors, onColorChange, onRemoveColor, onReorder);
        colorPicker.click();
      });

      paletteContainer.appendChild(swatch);
    });
  };

  const initTabPalette = async () => {
    const paletteContainer = document.getElementById('color-palette');
    const addButton = document.getElementById('zone-color-add-btn');
    const addFromPaletteButton = document.getElementById('zone-color-add-from-palette-btn');
    const colorInput = document.getElementById('zone-color-input');

    if (!paletteContainer || !addButton || !colorInput) {
      return;
    }

    const zoneId = paletteContainer.dataset.zoneId;
    if (!zoneId) {
      renderPalette(paletteContainer, []);
      return;
    }

    let tabData;
    try {
      tabData = await getTab(zoneId);
    } catch (error) {
      renderPalette(paletteContainer, []);
      return;
    }

    let colors = tabData.colors || [];
    if (!Array.isArray(colors)) {
      colors = [];
    }
    const onRemoveColor = async (index) => {
      if (index === null || index < 0 || index >= colors.length) {
        alert('Select a color to remove.');
        return;
      }
      try {
        const updated = colors.filter((_, i) => i !== index);
        const saved = await saveTabColors(zoneId, updated);
        colors = saved.colors || updated;
        selectedIndex = null;
        renderPalette(paletteContainer, colors, onColorChange, onRemoveColor, onReorder);
      } catch (error) {
        console.error('Failed to remove color:', error);
        alert('Failed to remove color.');
      }
    };

    const onReorder = async (fromIndex, toIndex) => {
      if (fromIndex < 0 || fromIndex >= colors.length || toIndex < 0 || toIndex >= colors.length) {
        return;
      }
      try {
        const updated = [...colors];
        const [moved] = updated.splice(fromIndex, 1);
        updated.splice(toIndex, 0, moved);
        const saved = await saveTabColors(zoneId, updated);
        colors = saved.colors || updated;
        selectedIndex = toIndex;
        renderPalette(paletteContainer, colors, onColorChange, onRemoveColor, onReorder);
      } catch (error) {
        console.error('Failed to reorder colors:', error);
        alert('Failed to reorder colors.');
      }
    };

    const onColorChange = async (index, newColor) => {
      if (!newColor || index < 0 || index >= colors.length) {
        return;
      }
      try {
        const updated = [...colors];
        updated[index] = newColor;
        const saved = await saveTabColors(zoneId, updated);
        colors = saved.colors || updated;
        selectedIndex = index;
        renderPalette(paletteContainer, colors, onColorChange, onRemoveColor, onReorder);
      } catch (error) {
        console.error('Failed to update color:', error);
        alert('Failed to update color.');
      }
    };

    renderPalette(paletteContainer, colors, onColorChange, onRemoveColor, onReorder);

    addButton.onclick = async () => {
      const newColor = colorInput.value;
      if (!newColor) {
        return;
      }
      if (colors.includes(newColor)) {
        alert('Color already in palette.');
        return;
      }
      try {
        const updated = [...colors, newColor];
        const saved = await saveTabColors(zoneId, updated);
        colors = saved.colors || updated;
        selectedIndex = colors.length - 1;
        renderPalette(paletteContainer, colors, onColorChange, onRemoveColor, onReorder);
      } catch (error) {
        console.error('Failed to add color:', error);
        alert('Failed to add color.');
      }
    };

    if (addFromPaletteButton) {
      addFromPaletteButton.onclick = () => {
        const openButton = document.getElementById('color-palette-btn');
        if (openButton) {
          openButton.click();
        }
        const modal = document.getElementById('color-palette-modal');
        const modalList = document.getElementById('palette-container');
        if (modal) {
          modal.classList.add('active');
        }
        if (!modalList) {
          return;
        }

        const handlePick = async (event) => {
          const row = event.target.closest('[data-color]');
          if (!row) {
            return;
          }
          const picked = row.dataset.color;
          if (!picked) {
            return;
          }
          try {
            if (!colors.includes(picked)) {
              const updated = [...colors, picked];
              const saved = await saveTabColors(zoneId, updated);
              colors = saved.colors || updated;
              selectedIndex = colors.indexOf(picked);
              renderPalette(paletteContainer, colors, onColorChange, onRemoveColor, onReorder);
            }
            if (modal) {
              modal.classList.remove('active');
            }
          } catch (error) {
            console.error('Failed to add palette color:', error);
            alert('Failed to add palette color.');
          } finally {
            modalList.removeEventListener('click', handlePick);
          }
        };

        modalList.addEventListener('click', handlePick);
      };
    }

  };

  document.body.addEventListener('htmx:afterSwap', (event) => {
    if (event.target && event.target.id === 'zone-content') {
      selectedIndex = null;
      initTabPalette();
    }
  });

  initTabPalette();
});
