Source: modules/ui.js

/**
 * UI management module for updating DOM elements and managing user interface components.
 * @module modules/ui
 */

import {
  fetchComponentsByModel,
  fetchComponentsByType,
  deleteComponent,
  updateComponent,
} from './servlet.js';
import { displayError, displaySuccess, clearMessages } from './utils.js';
import { componentFields } from './forms.js';

/**
 * Updates the component section display with component details.
 * @param {string} type - The component type
 * @param {Array<Object>} components - Array of component objects
 */
export function updateComponentSection(type, components) {
  const detailsElement = document.getElementById(`${type}-details`);
  if (!detailsElement || !components || components.length === 0) return;

  const list = document.createElement('ul');
  list.className = 'space-y-2';

  components.forEach((comp) => {
    const item = document.createElement('li');
    item.className = 'flex justify-between items-center';

    // Show details based on component type
    let details = '';
    switch (type) {
      case 'coaxial':
        details = `Pérdida: ${comp.atenuacion_coaxial}dB`;
        break;
      case 'derivador':
        details = `IL: ${comp.atenuacion_insercion}dB, BL: ${comp.atenuacion_derivacion}dB`;
        break;
      case 'distribuidor':
        details = `Pérdida: ${comp.atenuacion_distribucion}dB`;
        break;
      case 'toma':
        details = `Nivel: ${comp.nivel_senal}dB`;
        break;
    }

    item.innerHTML = `
            <span class="font-medium">${comp.modelo || 'N/A'}</span>
            <span class="text-sm text-zinc-500 dark:text-zinc-400">${details}</span>
        `;
    list.appendChild(item);
  });

  detailsElement.innerHTML = '';
  detailsElement.appendChild(list);
}

/**
 * Updates the signal quality summary display with simulation results.
 * @param {Array<Object>} data - Array of floor data with signal levels
 */
export function updateSignalQualitySummary(data) {
  const summaryElement = document.getElementById('signal-quality-summary');
  if (!summaryElement || !data || data.length === 0) return;

  const validFloors = data.filter((floor) => floor.is_valid).length;
  const totalFloors = data.length;
  const averageSignal = data.reduce((sum, floor) => sum + floor.nivel_senal, 0) / totalFloors;

  const summary = document.createElement('div');
  summary.className = 'space-y-4';
  summary.innerHTML = `
        <div class="grid grid-cols-3 gap-4">
            <div class="text-center">
                <div class="text-2xl font-bold ${
                  validFloors === totalFloors
                    ? 'text-green-600 dark:text-green-400'
                    : 'text-yellow-600 dark:text-yellow-400'
                }">
                    ${validFloors}/${totalFloors}
                </div>
                <div class="text-sm text-zinc-600 dark:text-zinc-400">Pisos Válidos</div>
            </div>
            <div class="text-center">
                <div class="text-2xl font-bold text-blue-600 dark:text-blue-400">
                    ${averageSignal.toFixed(1)}
                </div>
                <div class="text-sm text-zinc-600 dark:text-zinc-400">Señal Promedio (dB)</div>
            </div>
            <div class="text-center">
                <div class="text-2xl font-bold ${
                  validFloors === totalFloors
                    ? 'text-green-600 dark:text-green-400'
                    : 'text-red-600 dark:text-red-400'
                }">
                    ${validFloors === totalFloors ? 'APROBADO' : 'REVISAR'}
                </div>
                <div class="text-sm text-zinc-600 dark:text-zinc-400">Estado</div>
            </div>
        </div>
    `;

  summaryElement.innerHTML = '';
  summaryElement.appendChild(summary);
}

// Helper: Generate property details for a component
function generateComponentPropertyDetails(type, componentData) {
  const propertyDefinitions = {
    coaxial: [
      { label: 'Aten. 470MHz', key: 'atenuacion_470mhz', unit: 'dB/100m', decimals: 2 },
      { label: 'Aten. 694MHz', key: 'atenuacion_694mhz', unit: 'dB/100m', decimals: 2 },
    ],
    derivador: [
      { label: 'Aten. Deriv.', key: 'atenuacion_derivacion', unit: 'dB', decimals: 1 },
      { label: 'Aten. Paso', key: 'atenuacion_paso', unit: 'dB', decimals: 1 },
      { label: 'Directividad', key: 'directividad', unit: 'dB', decimals: 1 },
      { label: 'Desacoplo', key: 'desacoplo', unit: 'dB', decimals: 1 },
      { label: 'Pérd. Retorno', key: 'perdidas_retorno', unit: 'dB', decimals: 1 },
    ],
    distribuidor: [
      { label: 'Nº Salidas', key: 'numero_salidas', unit: '', decimals: 0 },
      { label: 'Aten. Distrib.', key: 'atenuacion_distribucion', unit: 'dB', decimals: 1 },
      { label: 'Desacoplo', key: 'desacoplo', unit: 'dB', decimals: 1 },
      { label: 'Pérd. Retorno', key: 'perdidas_retorno', unit: 'dB', decimals: 1 },
    ],
    toma: [
      { label: 'Atenuación', key: 'atenuacion', unit: 'dB', decimals: 1 },
      { label: 'Desacoplo', key: 'desacoplo', unit: 'dB', decimals: 1 },
    ],
  };

  const properties = propertyDefinitions[type] || [];
  return properties
    .map((prop) => {
      const value = componentData[prop.key];
      const formattedValue =
        value != null ? (prop.decimals > 0 ? value.toFixed(prop.decimals) : value) : '-';
      const displayValue = prop.unit ? `${formattedValue} ${prop.unit}` : formattedValue;
      return `<div class="flex justify-between items-center">
            <span class="text-zinc-600 dark:text-zinc-400">${prop.label}:</span>
            <span class="font-medium text-zinc-800 dark:text-zinc-200">${displayValue}</span>
        </div>`;
    })
    .join('');
}

export function updateDetailedComponentList(type, models, listId) {
  const listElement = document.getElementById(listId);
  if (!listElement) return;

  listElement.innerHTML = '';
  if (!Array.isArray(models) || models.length === 0) {
    listElement.innerHTML = `<div class="text-center text-sm text-zinc-500 dark:text-zinc-400 italic py-4">No hay ${type} disponibles.</div>`;
    return;
  }
  listElement.className = 'space-y-2 pb-4';
  const fragment = document.createDocumentFragment();

  models.forEach((modelo) => {
    const item = document.createElement('li');
    item.className =
      'bg-zinc-200 dark:bg-zinc-800/50 rounded-lg shadow border border-zinc-200 dark:border-zinc-700 p-4';
    item.dataset.modelo = modelo;

    const content = document.createElement('div');
    content.className = 'space-y-2';

    // Model name header
    const modelName = document.createElement('h3');
    modelName.className = 'text-base font-semibold text-primary-700 dark:text-primary-400';
    modelName.textContent = modelo;
    content.appendChild(modelName);

    // Details section (populated async)
    const details = document.createElement('div');
    details.className = 'text-xs space-y-1 border-t border-zinc-200 dark:border-zinc-700 pt-2 mt-2';
    details.innerHTML =
      '<p class="text-zinc-400 dark:text-zinc-500 italic">Cargando detalles...</p>';
    content.appendChild(details);

    // Action buttons
    const actions = document.createElement('div');
    actions.className =
      'flex justify-end space-x-2 mt-2 pt-2 border-t border-zinc-200 dark:border-zinc-700';

    // Edit
    const editButton = document.createElement('button');
    editButton.className =
      'text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300 px-2 py-1 rounded-md text-sm';
    editButton.textContent = 'Editar';
    editButton.onclick = () => handleEditComponent(type, modelo);
    actions.appendChild(editButton);

    // Delete
    const deleteButton = document.createElement('button');
    deleteButton.className =
      'text-red-600 hover:text-red-800 dark:text-red-400 dark:hover:text-red-300 px-2 py-1 rounded-md text-sm';
    deleteButton.textContent = 'Eliminar';
    deleteButton.onclick = () => handleDeleteComponent(type, modelo);
    actions.appendChild(deleteButton);

    content.appendChild(actions);
    item.appendChild(content);
    fragment.appendChild(item);

    // Fetch and display component details
    fetchComponentsByModel(type, modelo)
      .then((componentData) => {
        if (!componentData || typeof componentData.costo === 'undefined') {
          details.innerHTML =
            '<p class="text-red-500 dark:text-red-400">Error al cargar detalles.</p>';
          return;
        }
        let detailsHTML = `<div class="flex justify-between items-center">
                                    <span class="text-zinc-600 dark:text-zinc-400">Costo:</span>
                                    <span class="font-medium text-zinc-800 dark:text-zinc-200">${componentData.costo.toFixed(2)} €</span>
                                  </div>`;
        detailsHTML += generateComponentPropertyDetails(type, componentData);
        details.innerHTML = detailsHTML;
      })
      .catch(() => {
        details.innerHTML =
          '<p class="text-red-500 dark:text-red-400">Error al cargar detalles.</p>';
      });
  });
  listElement.appendChild(fragment);
}

export function updateSimpleComponentList(type, data, listId) {
  const listElement = document.getElementById(listId);
  if (!listElement) return;

  if (!Array.isArray(data) || data.length === 0) {
    listElement.innerHTML = `<div class="text-zinc-500 dark:text-zinc-400">No hay ${type} disponibles</div>`;
    return;
  }

  const list = document.createElement('ul');
  list.className = 'space-y-2';

  data.forEach((modelo) => {
    const item = document.createElement('li');
    item.className =
      'p-2 bg-zinc-200 dark:bg-zinc-800 rounded-lg shadow-2xs hover:shadow-md transition-shadow cursor-pointer';
    item.dataset.modelo = modelo;

    const content = document.createElement('div');
    content.className = 'flex justify-between items-center';

    const nameAndCost = document.createElement('div');
    nameAndCost.className = 'flex flex-col';

    const name = document.createElement('span');
    name.className = 'font-medium text-zinc-900 dark:text-white';
    name.textContent = modelo || 'Sin nombre';

    const cost = document.createElement('span');
    cost.className = 'text-sm text-zinc-500 dark:text-zinc-400';
    cost.textContent = 'Cargando...';

    nameAndCost.appendChild(name);
    nameAndCost.appendChild(cost);
    content.appendChild(nameAndCost);

    const addButton = document.createElement('button');
    addButton.className =
      'text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300 px-2 py-1 rounded-md text-sm';
    addButton.textContent = 'Añadir';
    content.appendChild(addButton);

    addButton.addEventListener('click', (e) => {
      e.stopPropagation();
      document.dispatchEvent(
        new CustomEvent('addComponent', {
          detail: {
            type: type,
            model: modelo,
          },
        }),
      );
    });

    // Fetch and display component cost
    fetchComponentsByModel(type, modelo)
      .then((details) => {
        if (details && details.costo) {
          cost.textContent = `Costo: ${details.costo.toFixed(2)}€`;
        } else {
          cost.textContent = 'Error al cargar costo';
        }
      })
      .catch(() => {
        cost.textContent = 'Error al cargar costo';
      });

    item.appendChild(content);
    list.appendChild(item);
  });

  listElement.innerHTML = '';
  listElement.appendChild(list);
}

export function updateComponentList(type, data, customListId = null) {
  // Use simple or detailed list depending on context
  const isSimulationList = customListId?.startsWith('simulation-');
  if (isSimulationList) {
    updateSimpleComponentList(type, data, customListId);
  } else {
    updateDetailedComponentList(type, data, customListId || `${type}-list`);
  }
}

export function updateConfigSelect(configurations, configSelect) {
  if (!configSelect) return;
  const currentVal = configSelect.value;
  configSelect.innerHTML =
    '<option value="">-- Seleccione --</option>' +
    configurations
      .map((config) => {
        const id = config.id_configuraciones || config.id;
        const name = config.nombre || `Configuración ${id}`;
        const dataString = JSON.stringify(config);
        return `<option value="${id}" data-config='${dataString}'>${name}</option>`;
      })
      .join('');
  if (configSelect.querySelector(`option[value="${currentVal}"]`)) {
    configSelect.value = currentVal;
    configSelect.dispatchEvent(new Event('change', { bubbles: true }));
  }
}

export function updateSignalTypeSelect(signalTypes, signalTypeSelect) {
  if (!signalTypeSelect) return;
  const currentVal = signalTypeSelect.value;
  signalTypeSelect.innerHTML =
    '<option value="">-- Seleccione --</option>' +
    signalTypes
      .map(
        (typeObj) =>
          `<option value="${typeObj.type}" data-min="${typeObj.min}" data-max="${typeObj.max}">${typeObj.type} (${typeObj.min}-${typeObj.max} dB)</option>`,
      )
      .join('');
  if (signalTypeSelect.querySelector(`option[value="${currentVal}"]`)) {
    signalTypeSelect.value = currentVal;
  }
}

export function updateSimulationResults(results) {
  const signalLevelsTableBody = document.getElementById('signal-levels-table');
  const simulationSummaryContainer = document.getElementById('simulation-summary');
  const headendLevelEl = document.getElementById('headend-level');
  const qualityMarginsEl = document.getElementById('quality-margins');
  const totalCostEl = document.getElementById('total-cost');
  const overallStatusEl = document.getElementById('overall-status');

  // If any required element is missing, reset display
  if (
    !signalLevelsTableBody ||
    !simulationSummaryContainer ||
    !headendLevelEl ||
    !qualityMarginsEl ||
    !totalCostEl ||
    !overallStatusEl ||
    !results
  ) {
    if (signalLevelsTableBody)
      signalLevelsTableBody.innerHTML =
        '<tr><td colspan="4" class="px-6 py-10 text-center text-sm text-zinc-500 dark:text-zinc-400">No hay resultados disponibles.</td></tr>';
    if (simulationSummaryContainer)
      simulationSummaryContainer.querySelector('p.text-xs')?.classList.remove('hidden');
    if (headendLevelEl) headendLevelEl.textContent = '-';
    if (qualityMarginsEl) qualityMarginsEl.textContent = '-';
    if (totalCostEl) totalCostEl.textContent = '-';
    if (overallStatusEl) overallStatusEl.textContent = '-';
    updateChartPlaceholder(true);
    return;
  }

  // --- Update Signal Levels Table ---
  if (results.signal_levels && results.signal_levels.length > 0) {
    signalLevelsTableBody.innerHTML = results.signal_levels
      .sort((a, b) => a.floor - b.floor)
      .map((floor) => {
        const level = typeof floor.level === 'number' ? floor.level.toFixed(1) : 'N/A';
        const cost = typeof floor.floor_cost === 'number' ? floor.floor_cost.toFixed(2) : 'N/A';
        const statusText = floor.status === 'ok' ? 'OK' : 'Error';
        const statusClass =
          floor.status === 'ok'
            ? 'bg-green-100 text-green-800 dark:bg-green-900/50 dark:text-green-300'
            : 'bg-red-100 text-red-800 dark:bg-red-900/50 dark:text-red-300';
        return `
                        <tr class="hover:bg-zinc-50/50 dark:hover:bg-zinc-50/5 transition-colors duration-150">
                            <td class="px-4 py-2 whitespace-nowrap text-sm font-medium text-zinc-800 dark:text-zinc-200">${floor.floor}</td>
                            <td class="px-4 py-2 whitespace-nowrap text-sm text-zinc-700 dark:text-zinc-300">${level} dBμV</td>
                            <td class="px-4 py-2 whitespace-nowrap text-center">
                                <span class="px-2.5 py-0.5 inline-flex text-xs leading-5 font-semibold rounded-full ${statusClass}">
                                    ${statusText}
                                </span>
                            </td>
                            <td class="px-4 py-2 whitespace-nowrap text-sm text-zinc-700 dark:text-zinc-300 text-right">${cost} €</td>
                        </tr>
                    `;
      })
      .join('');
  } else {
    signalLevelsTableBody.innerHTML =
      '<tr><td colspan="4" class="px-6 py-10 text-center text-sm text-zinc-500 dark:text-zinc-400">No se generaron niveles de señal.</td></tr>';
  }

  // --- Update Summary Section ---
  simulationSummaryContainer.querySelector('p.text-xs')?.classList.add('hidden');
  headendLevelEl.textContent = results.nivel_cabecera
    ? `${results.nivel_cabecera.toFixed(1)} dBμV`
    : '-';
  qualityMarginsEl.textContent = results.margins
    ? `${results.margins.min.toFixed(1)} - ${results.margins.max.toFixed(1)} dBμV`
    : '-';
  totalCostEl.textContent =
    typeof results.total_cost === 'number' ? `${results.total_cost.toFixed(2)} €` : '-';
  const allOk = results.signal_levels && results.signal_levels.every((f) => f.status === 'ok');
  overallStatusEl.textContent = allOk ? 'OK' : 'Revisar';
  overallStatusEl.className = `font-medium text-right ${
    allOk ? 'text-green-600 dark:text-green-400' : 'text-red-600 dark:text-red-400'
  }`;

  // --- Update Chart ---
  const chartCanvas = document.getElementById('results-chart');
  if (
    chartCanvas &&
    typeof Chart !== 'undefined' &&
    results.signal_levels &&
    results.signal_levels.length > 0
  ) {
    updateChartPlaceholder(false);
    const floorLabels = results.signal_levels.map((f) => `Piso ${f.floor}`);
    const signalData = results.signal_levels.map((f) => f.level);
    const minMargin = results.margins?.min;
    const maxMargin = results.margins?.max;

    // Destroy previous chart instance if it exists
    const existingChart = Chart.getChart(chartCanvas);
    if (existingChart) {
      existingChart.destroy();
    }

    // Get current theme colors
    const getThemeColors = () => {
      const isDarkMode = document.documentElement.classList.contains('dark');
      return {
        gridColor: isDarkMode ? 'rgba(113, 113, 122, 0.2)' : 'rgba(212, 212, 216, 0.4)',
        textColor: isDarkMode ? 'rgb(228, 228, 231)' : 'rgb(63, 63, 70)',
        pointColor: isDarkMode ? 'rgb(161, 161, 170)' : 'rgb(82, 82, 91)',
      };
    };

    const themeColors = getThemeColors();
    const chart = new Chart(chartCanvas, {
      type: 'line',
      data: {
        labels: floorLabels,
        datasets: [
          {
            label: 'Nivel de Señal (dBμV)',
            data: signalData,
            borderColor: themeColors.pointColor,
            backgroundColor: themeColors.pointColor + '33',
            tension: 0.1,
            fill: false,
            pointRadius: 4,
            pointHoverRadius: 6,
          },
        ],
      },
      options: {
        responsive: true,
        maintainAspectRatio: false,
        scales: {
          y: {
            beginAtZero: false,
            grid: { color: themeColors.gridColor },
            ticks: { color: themeColors.textColor, padding: 10 },
            title: {
              display: true,
              text: 'Nivel Señal (dBμV)',
              color: themeColors.textColor,
              font: { size: 10 },
            },
          },
          x: {
            grid: { display: false },
            ticks: { color: themeColors.textColor, padding: 10 },
            title: {
              display: true,
              text: 'Piso',
              color: themeColors.textColor,
              font: { size: 10 },
            },
          },
        },
        plugins: {
          legend: { display: false },
          annotation: {
            annotations: {
              ...(minMargin !== undefined && {
                lineMin: {
                  type: 'line',
                  yMin: minMargin,
                  yMax: minMargin,
                  borderColor: 'rgba(239, 68, 68, 0.6)',
                  borderWidth: 1,
                  borderDash: [6, 6],
                  label: {
                    content: `Min: ${minMargin.toFixed(1)}`,
                    enabled: true,
                    position: 'start',
                    backgroundColor: 'rgba(239, 68, 68, 0.6)',
                    color: 'white',
                    font: { size: 9 },
                    xPadding: 3,
                    yPadding: 3,
                    borderRadius: 2,
                  },
                },
              }),
              ...(maxMargin !== undefined && {
                lineMax: {
                  type: 'line',
                  yMin: maxMargin,
                  yMax: maxMargin,
                  borderColor: 'rgba(239, 68, 68, 0.6)',
                  borderWidth: 1,
                  borderDash: [6, 6],
                  label: {
                    content: `Max: ${maxMargin.toFixed(1)}`,
                    enabled: true,
                    position: 'start',
                    backgroundColor: 'rgba(239, 68, 68, 0.6)',
                    color: 'white',
                    font: { size: 9 },
                    xPadding: 3,
                    yPadding: 3,
                    borderRadius: 2,
                  },
                },
              }),
            },
          },
        },
      },
    });

    // Update chart colors on theme change
    const themeObserver = new MutationObserver(() => {
      const newColors = getThemeColors();
      chart.options.scales.y.grid.color = newColors.gridColor;
      chart.options.scales.y.ticks.color = newColors.textColor;
      chart.options.scales.y.title.color = newColors.textColor;
      chart.options.scales.x.ticks.color = newColors.textColor;
      chart.options.scales.x.title.color = newColors.textColor;
      chart.data.datasets[0].borderColor = newColors.pointColor;
      chart.data.datasets[0].backgroundColor = newColors.pointColor + '33';
      chart.update();
    });
    themeObserver.observe(document.documentElement, {
      attributes: true,
      attributeFilter: ['class'],
    });
    chart.themeObserver = themeObserver;
  } else {
    updateChartPlaceholder(true);
  }
}

// --- Simulation Component Management ---
export const simulationComponentManager = {
  components: {},
  componentsByFloor: {},
  currentFloor: null,

  addComponent(type, model, floor) {
    if (!floor) return false;
    if (!this.componentsByFloor[floor]) {
      this.componentsByFloor[floor] = {};
    }
    if (!this.componentsByFloor[floor][type]) {
      this.componentsByFloor[floor][type] = new Set();
    }
    this.componentsByFloor[floor][type].add(model);
    return true;
  },
  removeComponent(type, model, floor) {
    if (!floor || !this.componentsByFloor[floor] || !this.componentsByFloor[floor][type]) {
      return false;
    }
    return this.componentsByFloor[floor][type].delete(model);
  },
  getComponentsByFloor(floor) {
    return this.componentsByFloor[floor] || {};
  },
  getAllComponents() {
    return this.componentsByFloor;
  },
  setCurrentFloor(floor) {
    this.currentFloor = floor;
  },
  getCurrentFloor() {
    return this.currentFloor;
  },
  clearFloor(floor) {
    if (this.componentsByFloor[floor]) {
      delete this.componentsByFloor[floor];
    }
  },
  clearAllFloors() {
    this.componentsByFloor = {};
    this.currentFloor = null;
  },
};

// Helper: Get display name for component type
function getComponentTypeName(type) {
  switch (type) {
    case 'coaxial':
      return 'Cables Coaxiales';
    case 'derivador':
      return 'Derivadores';
    case 'distribuidor':
      return 'Distribuidores';
    case 'toma':
      return 'Tomas';
    default:
      return type;
  }
}

export function updateSelectedComponentsDisplay() {
  const componentsByFloor = document.getElementById('components-by-floor');
  if (!componentsByFloor) return;
  const allComponents = simulationComponentManager.getAllComponents();
  const floors = Object.keys(allComponents).sort((a, b) => a - b);
  if (floors.length === 0) {
    componentsByFloor.innerHTML =
      '<p class="text-zinc-500 dark:text-zinc-400">No hay componentes seleccionados</p>';
    return;
  }
  let html = '';
  floors.forEach((floor) => {
    const floorComponents = allComponents[floor];
    if (!floorComponents) return;
    html += `
            <div class="py-3 first:pt-0">
                <h3 class="mb-2 font-medium text-zinc-900 dark:text-zinc-100">Piso ${floor}</h3>
                <div class="space-y-2">
        `;
    Object.entries(floorComponents).forEach(([type, models]) => {
      if (models.length === 0) return;
      html += `
                <div class="pl-4">
                    <h4 class="mb-1 text-sm font-medium text-zinc-700 dark:text-zinc-300">${getComponentTypeName(
                      type,
                    )}</h4>
                    <ul class="space-y-1">
            `;
      models.forEach((model) => {
        html += `
                    <li class="flex items-center justify-between text-sm">
                        <span class="text-zinc-600 dark:text-zinc-400">${model}</span>
                        <button
                            class="text-red-600 hover:text-red-800 dark:text-red-400 dark:hover:text-red-300"
                            onclick="document.dispatchEvent(new CustomEvent('removeComponent', {
                                detail: {
                                    type: '${type}',
                                    model: '${model}',
                                    floor: ${floor}
                                }
                            }))"
                        >
                            Eliminar
                        </button>
                    </li>
                `;
      });
      html += `
                    </ul>
                </div>
            `;
    });
    html += `
                </div>
            </div>
        `;
  });
  componentsByFloor.innerHTML = html;
}

export function updateFloorSelector(numPisos) {
  const floorSelect = document.getElementById('simulation-floor');
  if (!floorSelect) return;
  const currentVal = floorSelect.value;
  floorSelect.innerHTML = '<option value="">-- Seleccione Piso --</option>';
  if (numPisos && numPisos > 0) {
    for (let i = 1; i <= numPisos; i++) {
      const option = document.createElement('option');
      option.value = i;
      option.textContent = `Piso ${i}`;
      floorSelect.appendChild(option);
    }
    if (floorSelect.querySelector(`option[value="${currentVal}"]`)) {
      floorSelect.value = currentVal;
    }
  } else {
    floorSelect.innerHTML = '<option value="">-- Seleccione Configuración --</option>';
  }
}

// --- Chart Placeholder ---
function updateChartPlaceholder(show = true) {
  const canvas = document.getElementById('results-chart');
  const placeholder = document.getElementById('chart-placeholder-text');
  if (canvas && placeholder) {
    canvas.style.display = show ? 'none' : 'block';
    placeholder.style.display = show ? 'block' : 'none';
  }
}

// --- Component Delete/Edit Handlers ---
async function handleDeleteComponent(type, model) {
  if (!confirm(`¿Está seguro de que desea eliminar el componente ${model}?`)) {
    return;
  }
  const errorMessageElement = document.getElementById('error-message');
  const successMessageElement = document.getElementById('success-message');
  try {
    const response = await deleteComponent(type, model);
    clearMessages(errorMessageElement, successMessageElement);
    displaySuccess(
      response.message || `Componente ${model} eliminado correctamente.`,
      successMessageElement,
      errorMessageElement,
    );
    const componentListType = document.getElementById('component-list-type');
    if (componentListType) {
      const components = await fetchComponentsByType(componentListType.value);
      updateDetailedComponentList(
        componentListType.value,
        components,
        `${componentListType.value}-list`,
      );
    }
  } catch (error) {
    clearMessages(errorMessageElement, successMessageElement);
    displayError(
      `Error al eliminar el componente: ${error.message}`,
      errorMessageElement,
      successMessageElement,
    );
  }
}

async function handleEditComponent(type, model) {
  const errorMessageElement = document.getElementById('error-message');
  const successMessageElement = document.getElementById('success-message');
  try {
    const componentData = await fetchComponentsByModel(type, model);
    const form = document.createElement('form');
    form.className = 'space-y-4';
    form.id = 'edit-component-form';
    // Hidden fields
    const typeInput = document.createElement('input');
    typeInput.type = 'hidden';
    typeInput.name = 'type';
    typeInput.value = type;
    form.appendChild(typeInput);
    const modelInput = document.createElement('input');
    modelInput.type = 'hidden';
    modelInput.name = 'modelo';
    modelInput.value = model;
    form.appendChild(modelInput);
    // Cost field
    const costField = document.createElement('div');
    costField.innerHTML = `
            <label for="costo" class="block text-sm font-medium text-zinc-700 dark:text-zinc-300 mb-1">Costo (€)</label>
            <input type="number" step="0.01" id="costo" name="costo" value="${componentData.costo}" required
                class="block w-full rounded-lg border-zinc-300 bg-zinc-200 shadow-sm transition focus:border-primary-500 focus:ring focus:ring-primary-500 focus:ring-opacity-50 dark:border-zinc-700 dark:bg-zinc-800 dark:text-white dark:focus:border-primary-400 dark:focus:ring-primary-400">
        `;
    form.appendChild(costField);
    // Component-specific fields
    const fieldsContainer = document.createElement('div');
    fieldsContainer.className = 'space-y-4';
    if (componentFields[type]) {
      componentFields[type].forEach((field) => {
        const fieldWrapper = document.createElement('div');
        fieldWrapper.innerHTML = `
                    <label for="${
                      field.name
                    }" class="block text-sm font-medium text-zinc-700 dark:text-zinc-300 mb-1">${field.label}</label>
                    <input type="${field.type}" id="${field.name}" name="${field.name}"
                        value="${componentData[field.name]}" required
                        ${field.step ? `step="${field.step}"` : ''}
                        class="block w-full rounded-lg border-zinc-300 bg-zinc-200 shadow-sm transition focus:border-primary-500 focus:ring focus:ring-primary-500 focus:ring-opacity-50 dark:border-zinc-700 dark:bg-zinc-800 dark:text-white dark:focus:border-primary-400 dark:focus:ring-primary-400">
                `;
        fieldsContainer.appendChild(fieldWrapper);
      });
    }
    form.appendChild(fieldsContainer);
    // Submit button
    const submitButton = document.createElement('button');
    submitButton.type = 'submit';
    submitButton.className =
      'w-full bg-primary-600 hover:bg-primary-700 focus:ring-primary-500 dark:bg-primary-500 dark:hover:bg-primary-600 dark:focus:ring-primary-400 rounded-lg px-5 py-2.5 text-sm font-medium text-white shadow-md transition focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-white dark:focus:ring-offset-zinc-900';
    submitButton.textContent = 'Guardar Cambios';
    form.appendChild(submitButton);
    // Modal
    const modal = document.createElement('div');
    modal.className = 'fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50';
    modal.innerHTML = `
            <div class="bg-zinc-50 dark:bg-zinc-900 rounded-lg shadow-lg p-6 max-w-md w-full mx-4">
                <div class="flex justify-between items-center mb-4">
                    <h3 class="text-lg font-semibold text-zinc-900 dark:text-white">Editar ${model}</h3>
                    <button class="text-zinc-500 hover:text-zinc-700 dark:text-zinc-400 dark:hover:text-zinc-300" onclick="this.closest('.fixed').remove()">
                        <svg class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
                        </svg>
                    </button>
                </div>
            </div>
        `;
    modal.querySelector('.rounded-lg').appendChild(form);
    document.body.appendChild(modal);
    form.addEventListener('submit', async (e) => {
      e.preventDefault();
      const formData = new FormData(form);
      try {
        const response = await updateComponent(type, model, formData);
        clearMessages(errorMessageElement, successMessageElement);
        displaySuccess(
          response.message || `Componente ${model} actualizado correctamente.`,
          successMessageElement,
          errorMessageElement,
        );
        modal.remove();
        const componentListType = document.getElementById('component-list-type');
        if (componentListType) {
          const components = await fetchComponentsByType(componentListType.value);
          updateDetailedComponentList(
            componentListType.value,
            components,
            `${componentListType.value}-list`,
          );
        }
      } catch (error) {
        clearMessages(errorMessageElement, successMessageElement);
        displayError(
          `Error al actualizar el componente: ${error.message}`,
          errorMessageElement,
          successMessageElement,
        );
      }
    });
  } catch (error) {
    clearMessages(errorMessageElement, successMessageElement);
    displayError(
      'Error al cargar los datos del componente. Por favor, intente de nuevo.',
      errorMessageElement,
      successMessageElement,
    );
  }
}

export function updateSimulationHistoryTable(simulations) {
  const tableBody = document.getElementById('simulation-history-table');
  if (!tableBody) return;
  if (!simulations || simulations.length === 0) {
    tableBody.innerHTML = `
            <tr>
                <td colspan="7" class="px-6 py-10 text-center text-sm text-zinc-500 dark:text-zinc-400">
                    No hay simulaciones guardadas.
                </td>
            </tr>
        `;
    return;
  }
  let html = '';
  simulations.forEach((simulation) => {
    html += `
            <tr class="border-b border-zinc-200 dark:border-zinc-700 hover:bg-zinc-50 dark:hover:bg-zinc-800">
                <td class="px-4 py-2.5">${simulation.nombre_edificio || '-'}</td>
                <td class="px-4 py-2.5">${simulation.nivel_cabecera ? `${simulation.nivel_cabecera} dBμV` : '-'}</td>
                <td class="px-4 py-2.5">${simulation.num_pisos || '-'}</td>
                <td class="px-4 py-2.5">${simulation.frecuencia ? `${simulation.frecuencia} MHz` : '-'}</td>
                <td class="px-4 py-2.5">${simulation.costo_total ? `€${simulation.costo_total}` : '-'}</td>
                <td class="px-4 py-2.5">
                    <span class="px-2 py-1 rounded-full text-xs ${
                      simulation.estado === 'ok'
                        ? 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200'
                        : 'bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200'
                    }">
                        ${simulation.estado || '-'}
                    </span>
                </td>
                <td class="px-4 py-2.5">
                    <div class="flex flex-col space-y-2">
                        <button class="text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300 load-schematic"
                                data-simulation-id="${simulation.id_simulaciones}">
                            Ver Esquemático
                        </button>
                        <button class="text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300 load-results"
                                data-simulation-id="${simulation.id_simulaciones}">
                            Ver Resultados
                        </button>
                        <button class="text-red-600 hover:text-red-800 dark:text-red-400 dark:hover:text-red-300 delete-simulation"
                                data-simulation-id="${simulation.id_simulaciones}">
                            Eliminar
                        </button>
                    </div>
                </td>
            </tr>
        `;
  });
  tableBody.innerHTML = html;
}

// Helper: Generate configuration form fields
function generateConfigFormFields(configData) {
  const fieldDefinitions = [
    {
      id: 'edit-config-name',
      name: 'nombre',
      label: 'Nombre',
      type: 'text',
      value: configData.nombre,
      required: true,
    },
    {
      id: 'edit-nivel-cabecera',
      name: 'nivel_cabecera',
      label: 'Nivel de Cabecera (70-120 dBμV)',
      type: 'number',
      value: configData.nivel_cabecera,
      required: true,
      min: 70,
      max: 120,
      step: 0.1,
    },
    {
      id: 'edit-num-pisos',
      name: 'num_pisos',
      label: 'Número de Pisos',
      type: 'number',
      value: configData.num_pisos,
      required: true,
      min: 1,
    },
  ];
  return fieldDefinitions
    .map(
      (field) => `
        <div>
            <label for="${field.id}" class="block text-sm font-medium text-zinc-700 dark:text-zinc-300 mb-1">${field.label}</label>
            <input type="${field.type}"
                   id="${field.id}"
                   name="${field.name}"
                   value="${field.value}"
                   ${field.required ? 'required' : ''}
                   ${field.min !== undefined ? `min="${field.min}"` : ''}
                   ${field.max !== undefined ? `max="${field.max}"` : ''}
                   ${field.step !== undefined ? `step="${field.step}"` : ''}
                   class="block w-full rounded-lg border-zinc-300 bg-zinc-200 shadow-sm transition focus:border-primary-500 focus:ring focus:ring-primary-500 focus:ring-opacity-50 dark:border-zinc-700 dark:bg-zinc-800 dark:text-white dark:focus:border-primary-400 dark:focus:ring-primary-400">
        </div>
    `,
    )
    .join('');
}

export async function handleEditConfiguration(configId, configData, updateCallback) {
  const errorMessageElement = document.getElementById('error-message');
  const successMessageElement = document.getElementById('success-message');
  try {
    // Create edit form modal
    const modal = document.createElement('div');
    modal.className = 'fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50';
    modal.innerHTML = `
            <div class="bg-zinc-50 dark:bg-zinc-900 rounded-lg shadow-lg p-6 max-w-md w-full mx-4">
                <div class="flex justify-between items-center mb-4">
                    <h3 class="text-lg font-semibold text-zinc-900 dark:text-white">Editar ${configData.nombre}</h3>
                    <button class="text-zinc-500 hover:text-zinc-700 dark:text-zinc-400 dark:hover:text-zinc-300" onclick="this.closest('.fixed').remove()">
                        <svg class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
                        </svg>
                    </button>
                </div>
                <form id="edit-config-form" class="space-y-4">
                    ${generateConfigFormFields(configData)}
                    <div class="pt-2">
                        <button type="submit" class="w-full bg-primary-600 hover:bg-primary-700 focus:ring-primary-500 dark:bg-primary-500 dark:hover:bg-primary-600 dark:focus:ring-primary-400 rounded-lg px-5 py-2.5 text-sm font-medium text-white shadow-md transition focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-white dark:focus:ring-offset-zinc-900">
                            Guardar Cambios
                        </button>
                    </div>
                </form>
            </div>
        `;
    document.body.appendChild(modal);
    const editForm = document.getElementById('edit-config-form');
    editForm.addEventListener('submit', async (e) => {
      e.preventDefault();
      const formData = new FormData(editForm);
      try {
        await updateCallback(configId, formData);
        modal.remove();
      } catch (error) {
        displayError(
          `Error al actualizar la configuración: ${error.message}`,
          errorMessageElement,
          successMessageElement,
        );
      }
    });
  } catch (error) {
    displayError(
      'Error al crear el formulario de edición. Por favor, intente de nuevo.',
      errorMessageElement,
      successMessageElement,
    );
  }
}