'use strict';

document.addEventListener('DOMContentLoaded', () => {
  const isEmbeddedSerenataView = window.self !== window.top;
  const requestParentModalClose = () => {
    if (!isEmbeddedSerenataView) return;

    try {
      window.parent.postMessage(
        {
          type: 'serenata-embed-close-request',
          context: 'serenata-detail'
        },
        window.location.origin
      );
    } catch (error) {
      // no-op
    }
  };

  if (isEmbeddedSerenataView) {
    document.addEventListener(
      'keydown',
      event => {
        if (event.key !== 'Escape') return;

        // Si ya hay un submodal visible dentro del iframe, dejamos que Bootstrap lo cierre primero.
        if (document.querySelector('.modal.show')) {
          return;
        }

        requestParentModalClose();
      },
      true
    );
  }

  const notyf = typeof Notyf !== 'undefined'
    ? new Notyf({
        duration: 2800,
        position: { x: 'right', y: 'top' },
        types: [
          { type: 'success', className: 'notyf__success', icon: { className: 'icon-base ti tabler-check' } },
          { type: 'error', className: 'notyf__error', icon: { className: 'icon-base ti tabler-alert-circle' } }
        ]
      })
    : null;

  const showToast = (type, message) => {
    if (notyf) {
      notyf.open({ type, message });
      return;
    }
    // fallback mínimo si no carga Notyf
    // eslint-disable-next-line no-alert
    alert(message);
  };

  const copyToClipboard = async text => {
    if (!text) return false;
    if (navigator.clipboard && window.isSecureContext) {
      await navigator.clipboard.writeText(text);
      return true;
    }
    const tmp = document.createElement('textarea');
    tmp.value = text;
    tmp.setAttribute('readonly', 'readonly');
    tmp.style.position = 'fixed';
    tmp.style.opacity = '0';
    document.body.appendChild(tmp);
    tmp.focus();
    tmp.select();
    const ok = document.execCommand('copy');
    document.body.removeChild(tmp);
    return ok;
  };

  document.addEventListener('click', async event => {
    const copyBtn = event.target.closest('.btn-copy-serenata');
    if (!copyBtn) return;
    event.preventDefault();

    const targetId = copyBtn.getAttribute('data-copy-target');
    const source = targetId ? document.getElementById(targetId) : null;
    const text = source ? source.value : '';
    if (!text) {
      showToast('error', 'No hay datos para copiar.');
      return;
    }
    try {
      await copyToClipboard(text);
      showToast('success', 'Serenata copiada para WhatsApp.');
    } catch (error) {
      showToast('error', 'No se pudo copiar la serenata.');
    }
  });

  document.addEventListener('click', async event => {
    const copyBtn = event.target.closest('.btn-copy-address-share');
    if (!copyBtn) return;
    event.preventDefault();

    const targetId = copyBtn.getAttribute('data-copy-target');
    const source = targetId ? document.getElementById(targetId) : null;
    const text = source ? source.value : '';
    if (!text) {
      showToast('error', 'No hay ubicación para copiar.');
      return;
    }
    try {
      await copyToClipboard(text);
      showToast('success', 'Ubicación copiada para WhatsApp.');
    } catch (error) {
      showToast('error', 'No se pudo copiar la ubicación.');
    }
  });

  const initTimeWindowPicker = () => {
    const input = document.getElementById('edit_event_time');
    const displayInput = document.getElementById('edit_event_time_display');
    const modeInput = document.getElementById('edit_event_time_window_mode');
    const button = document.getElementById('btnEditEventTimePicker');
    const preview = document.getElementById('edit_event_time_window_preview');
    const modeButtons = Array.from(document.querySelectorAll('#editEventTimeModeButtons .event-window-mode-btn'));
    const modalElement = document.getElementById('modalEditEventTimeWindowPicker');
    const modalModeButtons = Array.from(document.querySelectorAll('#modalEditEventTimeModeButtons .event-window-mode-btn'));
    const modalPreview = document.getElementById('modalEditEventTimeWindowPreview');
    const modalReferenceLabel = document.getElementById('modalEditEventTimeReferenceLabel');
    const modalMeridiem = document.getElementById('modalEditEventTimeMeridiem');
    const modalCenterLabel = document.getElementById('modalEditEventTimeCenterLabel');
    const hourButtons = Array.from(document.querySelectorAll('.js-edit-event-clock-hour'));
    const applyButton = document.getElementById('btnApplyEditEventTimeWindow');

    if (!input || !displayInput || !modeInput) return;

    const pad2 = value => String(value).padStart(2, '0');
    const formatHourLabel = hour => {
      const normalized = ((Number(hour) % 24) + 24) % 24;
      const suffix = normalized >= 12 ? 'PM' : 'AM';
      const hour12 = normalized % 12 || 12;
      return `${pad2(hour12)}:00 ${suffix}`;
    };
    const getMode = () => (modeInput.value === 'before' ? 'before' : 'after');
    const getStoredStartHour = () => {
      const match = String(input.value || '').trim().match(/^(\d{1,2}):(\d{2})$/);
      if (!match) return 20;
      return Math.max(0, Math.min(23, Number(match[1]) || 20));
    };
    const getReferenceHour = () => {
      const startHour = getStoredStartHour();
      return getMode() === 'before' ? (startHour + 1) % 24 : startHour;
    };
    const getWindowRange = (referenceHour = getReferenceHour(), mode = getMode()) => {
      const normalizedRef = ((Number(referenceHour) % 24) + 24) % 24;
      const startHour = mode === 'before' ? (normalizedRef + 23) % 24 : normalizedRef;
      const endHour = (startHour + 1) % 24;

      return {
        startHour,
        endHour,
        referenceHour: normalizedRef,
        startValue: `${pad2(startHour)}:00`,
        windowLabel: `${formatHourLabel(startHour)} - ${formatHourLabel(endHour)}`,
        referenceLabel: formatHourLabel(normalizedRef),
        meridiem: normalizedRef >= 12 ? 'PM' : 'AM'
      };
    };
    const renderModeButtons = mode => {
      [...modeButtons, ...modalModeButtons].forEach(buttonElement => {
        buttonElement.classList.toggle('active', buttonElement.dataset.mode === mode);
      });
    };
    const renderState = () => {
      const range = getWindowRange();
      if (preview) preview.textContent = range.windowLabel;
      displayInput.value = range.windowLabel;
      if (modalPreview) modalPreview.textContent = range.windowLabel;
      if (modalReferenceLabel) modalReferenceLabel.textContent = range.referenceLabel;
      if (modalMeridiem) modalMeridiem.textContent = range.meridiem;
      if (modalCenterLabel) modalCenterLabel.textContent = range.referenceLabel;
      hourButtons.forEach(buttonElement => {
        buttonElement.classList.toggle('active', Number(buttonElement.dataset.hour) === range.referenceHour);
      });
      renderModeButtons(getMode());
    };
    const setReferenceHour = hour => {
      const range = getWindowRange(hour, getMode());
      input.value = range.startValue;
      input.dispatchEvent(new Event('input', { bubbles: true }));
      input.dispatchEvent(new Event('change', { bubbles: true }));
      renderState();
    };
    const setMode = mode => {
      const currentReferenceHour = getReferenceHour();
      modeInput.value = mode === 'before' ? 'before' : 'after';
      setReferenceHour(currentReferenceHour);
    };
    const parseManualReferenceHour = value => {
      const textValue = String(value || '').trim().toLowerCase();
      if (!textValue) return null;
      if (textValue.includes('-')) return null;

      const match = textValue.match(/\b(\d{1,2})(?::(\d{2}))?\s*(am|pm)?\b/);
      if (!match) return null;

      let hour = Number(match[1] || 0);
      const meridiem = (match[3] || '').toLowerCase();
      if (meridiem === 'pm' && hour < 12) hour += 12;
      if (meridiem === 'am' && hour === 12) hour = 0;
      if (!meridiem && hour === 24) hour = 0;
      if (hour < 0 || hour > 23) return null;

      return hour;
    };

    input.addEventListener('input', renderState);
    input.addEventListener('change', renderState);
    displayInput.addEventListener('focus', () => displayInput.select());
    displayInput.addEventListener('blur', () => {
      const parsedHour = parseManualReferenceHour(displayInput.value);
      if (parsedHour === null) {
        renderState();
        return;
      }
      setReferenceHour(parsedHour);
    });

    modeButtons.forEach(buttonElement => {
      buttonElement.addEventListener('click', event => {
        event.preventDefault();
        setMode(buttonElement.dataset.mode || 'after');
      });
    });
    modalModeButtons.forEach(buttonElement => {
      buttonElement.addEventListener('click', event => {
        event.preventDefault();
        setMode(buttonElement.dataset.mode || 'after');
      });
    });
    hourButtons.forEach(buttonElement => {
      buttonElement.addEventListener('click', event => {
        event.preventDefault();
        setReferenceHour(Number(buttonElement.dataset.hour || 20));
      });
    });

    if (button && modalElement && window.bootstrap?.Modal) {
      button.addEventListener('click', event => {
        event.preventDefault();
        renderState();
        window.bootstrap.Modal.getOrCreateInstance(modalElement).show();
      });
    }

    if (applyButton && modalElement && window.bootstrap?.Modal) {
      applyButton.addEventListener('click', event => {
        event.preventDefault();
        renderState();
        window.bootstrap.Modal.getOrCreateInstance(modalElement).hide();
      });
    }

    if (!String(input.value || '').trim()) {
      modeInput.value = 'after';
      input.value = '20:00';
    }

    renderState();
  };

  initTimeWindowPicker();

  const formatCop = value =>
    '$' + Number(value || 0).toLocaleString('es-CO', { maximumFractionDigits: 0, minimumFractionDigits: 0 });
  const formatCopPlain = value =>
    Number(Math.max(0, Math.round(Number(value || 0)))).toLocaleString('es-CO', {
      maximumFractionDigits: 0,
      minimumFractionDigits: 0
    });
  const removeCostUrl = document.getElementById('costItemsTableBody')?.dataset.removeUrl || document.querySelector('.form-remove-cost-item')?.action || '';
  const restoreCostUrl = document.getElementById('costItemsTableBody')?.dataset.restoreUrl || document.querySelector('.form-restore-cost-item')?.action || '';
  const updateCostUrl = document.getElementById('costItemsTableBody')?.dataset.updateUrl || '';

  const updateCostSummary = financials => {
    if (!financials) return;
    const basePrice = document.getElementById('summary_base_price');
    const baseCost = document.getElementById('summary_base_cost');
    const discount = document.getElementById('summary_discount');
    const commission = document.getElementById('summary_commission');
    const profit = document.getElementById('summary_profit_amount');
    const totalCharged = document.getElementById('summary_total_charged');

    if (basePrice) basePrice.textContent = formatCop(financials.base_price);
    if (baseCost) baseCost.textContent = formatCop(financials.base_cost);
    if (discount) {
      const discountValue = Number(financials.discount_amount || 0);
      discount.textContent = discountValue > 0 ? `- ${formatCop(discountValue)}` : '$0';
      discount.classList.toggle('text-danger', discountValue > 0);
    }
    if (commission) {
      const commissionValue = Number(financials.commission_amount || 0) > 0
        ? Number(financials.commission_amount || 0)
        : Number(financials.profit_amount || 0);
      commission.textContent = formatCop(commissionValue);
    }
    if (profit) {
      const profitValue = Number(financials.profit_amount || 0);
      profit.textContent = `${profitValue < 0 ? '- ' : ''}${formatCop(Math.abs(profitValue))}`;
      profit.classList.toggle('text-danger', profitValue < 0);
      profit.classList.toggle('text-success', profitValue >= 0);
    }
    if (totalCharged) totalCharged.textContent = formatCop(financials.total_charged);

    const pricingModalBody = document.querySelector('#modalEditPricingSummary .modal-body');
    const pricingBaseCostPreview = document.getElementById('pricing_summary_base_cost_preview');
    if (pricingModalBody) pricingModalBody.dataset.pricingBaseCost = String(Number(financials.base_cost || 0));
    if (pricingBaseCostPreview) pricingBaseCostPreview.textContent = formatCop(financials.base_cost);
  };

  const parseCopInput = value => {
    if (value === null || value === undefined) return 0;
    const normalized = String(value).replace(/[^\d.,-]/g, '').replace(/\./g, '').replace(',', '.');
    const parsed = Number.parseFloat(normalized);
    return Number.isFinite(parsed) ? parsed : 0;
  };

  document.querySelectorAll('.js-cop-mask').forEach(input => {
    const applyMask = () => {
      input.value = formatCopPlain(parseCopInput(input.value));
    };

    input.addEventListener('input', applyMask);
    input.addEventListener('blur', applyMask);
  });

  const initPricingSummaryPreview = () => {
    const modalBody = document.querySelector('#modalEditPricingSummary .modal-body');
    const basePriceInput = document.getElementById('pricing_summary_base_price_input');
    const discountInput = document.getElementById('pricing_summary_discount_input');
    const baseCostPreview = document.getElementById('pricing_summary_base_cost_preview');
    const profitPreview = document.getElementById('pricing_summary_profit_preview');
    const totalPreview = document.getElementById('pricing_summary_total_preview');

    if (!modalBody || !basePriceInput || !discountInput || !profitPreview || !totalPreview) return;

    const baseCost = Number(modalBody.dataset.pricingBaseCost || 0);
    if (baseCostPreview) baseCostPreview.textContent = formatCop(baseCost);

    const renderPricingPreview = () => {
      const basePrice = Math.max(0, Math.round(parseCopInput(basePriceInput.value)));
      const discount = Math.max(0, Math.round(parseCopInput(discountInput.value)));
      const totalCharged = Math.max(0, basePrice - discount);
      const profit = totalCharged - baseCost;

      totalPreview.textContent = formatCop(totalCharged);
      profitPreview.textContent = `${profit < 0 ? '- ' : ''}${formatCop(Math.abs(profit))}`;
      profitPreview.classList.toggle('text-danger', profit < 0);
      profitPreview.classList.toggle('text-success', profit >= 0);
    };

    ['input', 'blur', 'change'].forEach(eventName => {
      basePriceInput.addEventListener(eventName, renderPricingPreview);
      discountInput.addEventListener(eventName, renderPricingPreview);
    });

    renderPricingPreview();
  };

  initPricingSummaryPreview();

  const isCostActionsVisible = () => {
    const firstActionCol = document.querySelector('.cost-actions-col');
    return !!firstActionCol && !firstActionCol.classList.contains('d-none');
  };

  const buildActiveActionCellHtml = item => {
    const csrf = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') || '';
    return `
      <button
        type="button"
        class="btn btn-sm btn-icon btn-text-secondary me-1 btn-inline-save-cost-item"
        data-source="${item.source}"
        data-index="${item.index}"
        data-name="${item.name}"
        data-quantity="${item.quantity}"
        data-unit-price="${Math.round(Number(item.unit_price || 0))}"
        title="Editar">
        <i class="icon-base ti tabler-pencil icon-18px"></i>
      </button>
      <form method="POST" action="${removeCostUrl}" class="d-inline-block text-start form-remove-cost-item">
        <input type="hidden" name="_token" value="${csrf}">
        <input type="hidden" name="_method" value="PATCH">
        <input type="hidden" name="source" value="${item.source}">
        <input type="hidden" name="index" value="${item.index}">
        <input type="hidden" name="reason" value="">
        <button type="button" class="btn btn-sm btn-icon btn-text-danger btn-show-remove-cost-confirm" title="Eliminar">
          <i class="icon-base ti tabler-x icon-18px"></i>
        </button>
        <div class="remove-cost-confirmation d-none mt-2 p-2 border rounded bg-body" style="min-width: 280px;">
          <div class="small text-body-secondary mb-2">Confirma eliminación del ítem.</div>
          <input type="text" class="form-control form-control-sm mb-2 remove-cost-reason-input" maxlength="120" placeholder="Motivo (opcional)">
          <div class="d-flex justify-content-end gap-2">
            <button type="button" class="btn btn-label-secondary btn-sm btn-cancel-remove-cost-item">Cancelar</button>
            <button type="submit" class="btn btn-danger btn-sm">Eliminar</button>
          </div>
        </div>
      </form>
    `;
  };

  const appendNewCostRow = item => {
    const tbody = document.getElementById('costItemsTableBody');
    if (!tbody || !item) return;
    const emptyRow = tbody.querySelector('tr td[colspan]');
    if (emptyRow) emptyRow.closest('tr')?.remove();
    const tr = document.createElement('tr');
    tr.dataset.source = item.source;
    tr.dataset.index = item.index;
    tr.dataset.category = item.category || '';
    tr.dataset.name = item.name || '';
    tr.dataset.unitPrice = String(Math.round(Number(item.unit_price || 0)));
    tr.dataset.quantity = String(Math.max(1, Number(item.quantity || 1)));
    tr.dataset.total = String(Math.round(Number(item.total || 0)));
    tr.innerHTML = `
      <td class="cost-col-category">${item.category || '-'}</td>
      <td class="cost-col-item">${item.name || '-'}</td>
      <td class="cost-col-unit-price">${formatCop(item.unit_price)}</td>
      <td class="cost-col-quantity">${item.quantity || 1}</td>
      <td class="cost-col-total">${formatCop(item.total)}</td>
      <td class="text-end cost-actions-col ${isCostActionsVisible() ? '' : 'd-none'}">
        ${buildActiveActionCellHtml(item)}
      </td>
    `;
    tbody.appendChild(tr);
  };

  const markRowAsDeleted = (row, reason = '') => {
    if (!row) return;
    row.classList.add('table-secondary', 'text-body-secondary');
    const itemCell = row.querySelector('.cost-col-item');
    if (itemCell) {
      const plainName = itemCell.textContent.trim();
      itemCell.innerHTML = `
        <span class="text-decoration-line-through">${plainName}</span>
        <span class="badge bg-label-secondary ms-1">Eliminado</span>
        ${reason ? `<div class="small mt-1">Motivo: ${reason}</div>` : ''}
      `;
    }
    const actionCell = row.querySelector('.cost-actions-col');
    if (actionCell) {
      const csrf = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') || '';
      actionCell.innerHTML = `
        <form method="POST" action="${restoreCostUrl}" class="d-inline-block form-restore-cost-item">
          <input type="hidden" name="_token" value="${csrf}">
          <input type="hidden" name="_method" value="PATCH">
          <input type="hidden" name="source" value="${row.dataset.source || ''}">
          <input type="hidden" name="index" value="${row.dataset.index || ''}">
          <button type="submit" class="btn btn-sm btn-icon btn-text-success" title="Revertir eliminación">
            <i class="icon-base ti tabler-arrow-back-up icon-18px"></i>
          </button>
        </form>
      `;
    }
  };

  const restoreRowAsActive = (row, item) => {
    if (!row || !item) return;
    row.classList.remove('table-secondary', 'text-body-secondary');
    row.dataset.category = item.category || row.dataset.category || '';
    row.dataset.name = item.name || row.dataset.name || '';
    row.dataset.unitPrice = String(Math.round(Number(item.unit_price || 0)));
    row.dataset.quantity = String(item.quantity || 1);
    row.dataset.total = String(Math.round(Number(item.total || 0)));

    const categoryCell = row.querySelector('.cost-col-category');
    const itemCell = row.querySelector('.cost-col-item');
    const unitCell = row.querySelector('.cost-col-unit-price');
    const qtyCell = row.querySelector('.cost-col-quantity');
    const totalCell = row.querySelector('.cost-col-total');
    const actionCell = row.querySelector('.cost-actions-col');

    if (categoryCell) categoryCell.textContent = row.dataset.category || '-';
    if (itemCell) itemCell.textContent = row.dataset.name || '-';
    if (unitCell) unitCell.textContent = formatCop(item.unit_price || 0);
    if (qtyCell) qtyCell.textContent = String(item.quantity || 1);
    if (totalCell) totalCell.textContent = formatCop(item.total || 0);
    if (actionCell) {
      actionCell.innerHTML = isCostActionsVisible() ? buildActiveActionCellHtml({
        source: row.dataset.source || '',
        index: row.dataset.index || 0,
        name: row.dataset.name || '',
        quantity: row.dataset.quantity || 1,
        unit_price: row.dataset.unitPrice || 0
      }) : '';
      actionCell.classList.toggle('d-none', !isCostActionsVisible());
    }
  };

  const setInlineInputsForRow = row => {
    if (!row || row.classList.contains('table-secondary')) return;
    const unitCell = row.querySelector('.cost-col-unit-price');
    const qtyCell = row.querySelector('.cost-col-quantity');
    const totalCell = row.querySelector('.cost-col-total');
    if (!unitCell || !qtyCell || !totalCell) return;
    if (unitCell.querySelector('input') || qtyCell.querySelector('input')) return;

    const unitValue = Math.max(0, Math.round(Number.parseFloat(row.dataset.unitPrice || parseCopInput(unitCell.textContent || '0')) || 0));
    const qtyValue = Math.max(1, Number.parseInt(row.dataset.quantity || '1', 10) || 1);

    unitCell.innerHTML = `<input type="text" class="form-control form-control-sm inline-edit-unit-price" value="${formatCopPlain(unitValue)}">`;
    qtyCell.innerHTML = `<input type="number" min="1" step="1" class="form-control form-control-sm inline-edit-quantity" value="${qtyValue}">`;
    totalCell.textContent = formatCop(unitValue * qtyValue);
  };

  const restoreDisplayForRow = row => {
    if (!row) return;
    const unitCell = row.querySelector('.cost-col-unit-price');
    const qtyCell = row.querySelector('.cost-col-quantity');
    const totalCell = row.querySelector('.cost-col-total');
    if (!unitCell || !qtyCell || !totalCell) return;

    const unitValue = Number.parseFloat(row.dataset.unitPrice || '0') || 0;
    const qtyValue = Math.max(1, Number.parseInt(row.dataset.quantity || '1', 10) || 1);
    const totalValue = Number.parseFloat(row.dataset.total || String(unitValue * qtyValue)) || (unitValue * qtyValue);

    unitCell.textContent = formatCop(unitValue);
    qtyCell.textContent = String(qtyValue);
    totalCell.textContent = formatCop(totalValue);
  };

  const setRowSaveButtonState = (row, inlineMode) => {
    if (!row) return;
    const btn = row.querySelector('.btn-inline-save-cost-item');
    const icon = btn?.querySelector('i');
    if (!btn || !icon) return;

    if (!inlineMode) {
      btn.classList.remove('d-none', 'btn-text-success');
      btn.classList.add('btn-text-secondary');
      icon.classList.remove('tabler-check');
      icon.classList.add('tabler-pencil');
      btn.title = 'Editar';
      return;
    }

    const qtyInput = row.querySelector('.inline-edit-quantity');
    const unitInput = row.querySelector('.inline-edit-unit-price');
    if (!qtyInput || !unitInput) {
      btn.classList.add('d-none');
      return;
    }

    const currentQty = Math.max(1, Number.parseInt(qtyInput.value || '1', 10) || 1);
    const currentUnit = Math.max(0, Math.round(parseCopInput(unitInput.value || '0')));
    const persistedQty = Math.max(1, Number.parseInt(row.dataset.quantity || '1', 10) || 1);
    const persistedUnit = Math.max(0, Math.round(Number.parseFloat(row.dataset.unitPrice || '0') || 0));
    const isDirty = currentQty !== persistedQty || currentUnit !== persistedUnit;

    if (isDirty) {
      btn.classList.remove('d-none', 'btn-text-secondary');
      btn.classList.add('btn-text-success');
      icon.classList.remove('tabler-pencil');
      icon.classList.add('tabler-check');
      btn.title = 'Guardar cambios';
    } else {
      btn.classList.add('d-none');
    }
  };

  const googleMapsCountry = (window.__googleMapsCountry || 'co').toLowerCase();
  const addressResolveUrl = window.__addressResolveUrl || null;
  const addressSuggestionsUrl = window.__addressSuggestionsUrl || null;
  const table = document.querySelector('.datatables-serenata-details');
  if (table) {
    new DataTable(table, {
      paging: false,
      searching: false,
      info: false,
      ordering: false,
      language: {
        emptyTable: 'Sin ítems para mostrar'
      }
    });
  }

  const serviceStatusInput = document.getElementById('status_service_status');
  const cancellationWrap = document.getElementById('statusCancellationReasonWrap');
  const cancellationInput = document.getElementById('status_cancellation_reason');
  const cededSwitchInput = document.getElementById('is_ceded');
  const cededFieldsWrap = document.getElementById('cededFieldsWrap');
  const cededPartnerInput = document.getElementById('external_partner_id');
  const cededArtistInput = document.getElementById('ceded_artist_amount');
  const cededGiftInput = document.getElementById('ceded_gift_amount');
  const cededTransportInput = document.getElementById('ceded_transport_amount');
  const cededOtherCostInput = document.getElementById('ceded_other_cost_amount');
  const cededCostBreakdownInput = document.getElementById('ceded_cost_breakdown');
  const cededTotalInput = document.getElementById('ceded_total_cost');
  const cededExcessLabelInput = document.getElementById('ceded_excess_label');
  const cededExcessAmountPreviewInput = document.getElementById('ceded_excess_amount_preview');
  const cededTotalChargedPreviewInput = document.getElementById('ceded_total_charged_preview');
  const cededArtistPreview = document.getElementById('ceded_artist_amount_preview');
  const cededGiftPreview = document.getElementById('ceded_gift_amount_preview');
  const cededTransportPreview = document.getElementById('ceded_transport_amount_preview');
  const cededOtherCostPreview = document.getElementById('ceded_other_cost_amount_preview');
  const cededTransportManualInput = document.getElementById('ceded_transport_manual');
  const cededBreakdownRows = Array.from(document.querySelectorAll('.js-ceded-breakdown-item'));
  const externalMovementPartnerInput = document.getElementById('external_movement_partner_id');
  const externalMovementDirectionInput = document.getElementById('external_movement_direction');
  const externalMovementDirectionHint = document.getElementById('external_movement_direction_hint');
  const mainTabButtons = document.querySelectorAll('.js-serenata-main-tab');
  const mainTabPanes = document.querySelectorAll('.serenata-main-pane');

  const syncCancellationField = () => {
    if (!serviceStatusInput || !cancellationWrap || !cancellationInput) return;
    const isCancelled = (serviceStatusInput.value || '').trim() === 'Cancelada';
    cancellationWrap.classList.toggle('d-none', !isCancelled);
    cancellationInput.required = isCancelled;
    if (!isCancelled) {
      cancellationInput.value = '';
    }
  };

  const parseNumberInput = input => Math.max(0, parseCopInput(input?.value || '0'));

  const syncCededFieldsVisibility = () => {
    if (!cededSwitchInput || !cededFieldsWrap) return;
    const enabled = !!cededSwitchInput.checked;
    cededFieldsWrap.classList.toggle('d-none', !enabled);
    if (cededPartnerInput) cededPartnerInput.required = enabled;
  };

  const updateCededBreakdownTotals = () => {
    if (!cededCostBreakdownInput) return;

    let artistTotal = 0;
    let giftTotal = 0;
    let otherCostTotal = 0;
    const breakdownItems = [];

    cededBreakdownRows.forEach(row => {
      const source = row.dataset.source || '';
      const index = Number.parseInt(row.dataset.index || '0', 10) || 0;
      const name = row.dataset.name || 'Ítem';
      const includedInput = row.querySelector('.js-ceded-item-included');
      const quantityInput = row.querySelector('.js-ceded-item-quantity');
      const unitPriceInput = row.querySelector('.js-ceded-item-unit-price');
      const totalLabel = row.querySelector('.js-ceded-item-total');
      const included = !!includedInput?.checked;
      const quantity = Math.max(1, Number.parseInt(quantityInput?.value || '1', 10) || 1);
      const unitPrice = Math.max(0, parseNumberInput(unitPriceInput));
      const total = included ? quantity * unitPrice : 0;

      if (quantityInput && String(quantityInput.value) !== String(quantity)) {
        quantityInput.value = String(quantity);
      }
      if (totalLabel) {
        totalLabel.textContent = formatCop(total);
      }
      row.classList.toggle('opacity-50', !included);

      breakdownItems.push({
        source,
        index,
        name,
        quantity,
        unit_price: unitPrice,
        included,
        total
      });

      if (!included) return;

      if (source === 'artist') artistTotal += total;
      if (source === 'gift') giftTotal += total;
      if (source === 'other_cost') otherCostTotal += total;
    });

    const transportManual = Math.max(0, parseNumberInput(cededTransportManualInput));
    if (transportManual > 0) {
      breakdownItems.push({
        source: 'transport',
        index: 0,
        name: 'Transporte manual',
        quantity: 1,
        unit_price: transportManual,
        included: true,
        total: transportManual
      });
    }

    if (cededArtistInput) cededArtistInput.value = String(Math.round(artistTotal));
    if (cededGiftInput) cededGiftInput.value = String(Math.round(giftTotal));
    if (cededOtherCostInput) cededOtherCostInput.value = String(Math.round(otherCostTotal));
    if (cededTransportInput) cededTransportInput.value = String(Math.round(transportManual));
    if (cededArtistPreview) cededArtistPreview.textContent = formatCop(artistTotal);
    if (cededGiftPreview) cededGiftPreview.textContent = formatCop(giftTotal);
    if (cededOtherCostPreview) cededOtherCostPreview.textContent = formatCop(otherCostTotal);
    if (cededTransportPreview) cededTransportPreview.textContent = formatCop(transportManual);
    cededCostBreakdownInput.value = JSON.stringify(breakdownItems);
  };

  const syncCededExcessPreview = () => {
    if (!cededTotalChargedPreviewInput || !cededExcessLabelInput || !cededExcessAmountPreviewInput) return;
    const totalCharged = parseCopInput(cededTotalChargedPreviewInput.value || '0');
    const costsByParts = parseNumberInput(cededArtistInput) + parseNumberInput(cededGiftInput) + parseNumberInput(cededTransportInput) + parseNumberInput(cededOtherCostInput);
    const manualTotal = parseNumberInput(cededTotalInput);
    const finalCost = manualTotal > 0 ? manualTotal : costsByParts;
    const diff = Math.round(totalCharged - finalCost);
    const absDiff = Math.abs(diff);
    if (diff > 0) {
      cededExcessLabelInput.value = 'Esperando excedente';
    } else if (diff < 0) {
      cededExcessLabelInput.value = 'Debes excedente';
    } else {
      cededExcessLabelInput.value = 'Sin excedente';
    }
    cededExcessAmountPreviewInput.value = formatCopPlain(absDiff);
  };

  const activateMainTab = paneId => {
    if (!paneId) return;
    mainTabButtons.forEach(btn => {
      btn.classList.toggle('active', btn.dataset.mainTarget === paneId);
    });
    mainTabPanes.forEach(pane => {
      const isTarget = pane.id === paneId;
      pane.classList.toggle('d-none', !isTarget);
      pane.classList.toggle('show', isTarget);
      pane.classList.toggle('active', isTarget);
    });
  };

  if (serviceStatusInput) {
    serviceStatusInput.addEventListener('change', syncCancellationField);
    syncCancellationField();
  }

  if (cededSwitchInput) {
    cededSwitchInput.addEventListener('change', syncCededFieldsVisibility);
    syncCededFieldsVisibility();
  }

  cededBreakdownRows.forEach(row => {
    row.querySelectorAll('.js-ceded-item-included, .js-ceded-item-quantity, .js-ceded-item-unit-price').forEach(input => {
      input.addEventListener('input', () => {
        updateCededBreakdownTotals();
        syncCededExcessPreview();
      });
      input.addEventListener('change', () => {
        updateCededBreakdownTotals();
        syncCededExcessPreview();
      });
    });
  });

  if (cededTransportManualInput) {
    cededTransportManualInput.addEventListener('input', () => {
      updateCededBreakdownTotals();
      syncCededExcessPreview();
    });
  }

  [cededArtistInput, cededGiftInput, cededTransportInput, cededOtherCostInput, cededTotalInput].forEach(input => {
    if (!input) return;
    input.addEventListener('input', syncCededExcessPreview);
  });
  updateCededBreakdownTotals();
  syncCededExcessPreview();

  const updateExternalMovementCopy = () => {
    if (!externalMovementPartnerInput || !externalMovementDirectionInput) return;
    const selectedOption = externalMovementPartnerInput.options[externalMovementPartnerInput.selectedIndex];
    const rawLabel = (selectedOption?.textContent || 'este externo').trim();
    const partnerName = externalMovementPartnerInput.value
      ? (rawLabel.replace(/\s+\(.+\)$/, '').trim() || 'este externo')
      : 'este externo';

    Array.from(externalMovementDirectionInput.options).forEach(option => {
      if (option.value === 'a_favor_mio') {
        option.textContent = `${partnerName} me debe`;
      } else if (option.value === 'yo_debo') {
        option.textContent = `Yo le debo a ${partnerName}`;
      }
    });

    if (externalMovementDirectionHint) {
      const currentDirection = externalMovementDirectionInput.value || 'a_favor_mio';
      externalMovementDirectionHint.textContent = currentDirection === 'yo_debo'
        ? `Usa esta opción cuando tú quedas debiéndole dinero o una serenata a ${partnerName}.`
        : `Usa esta opción cuando ${partnerName} te queda debiendo dinero o una serenata.`;
    }
  };

  if (externalMovementPartnerInput) {
    externalMovementPartnerInput.addEventListener('change', updateExternalMovementCopy);
  }
  if (externalMovementDirectionInput) {
    externalMovementDirectionInput.addEventListener('change', updateExternalMovementCopy);
  }
  updateExternalMovementCopy();

  if (mainTabButtons.length && mainTabPanes.length) {
    mainTabButtons.forEach(btn => {
      btn.addEventListener('click', () => {
        activateMainTab(btn.dataset.mainTarget || '');
      });
    });
    activateMainTab('serenata-detalles-tab');
  }

  const quickStatusForm = document.getElementById('quickStatusForm');
  const quickServiceStatus = document.getElementById('quick_service_status');
  const quickCancellationReason = document.getElementById('quick_cancellation_reason');
  const quickCancelModalEl = document.getElementById('modalQuickCancelReason');
  const quickCancelReasonInput = document.getElementById('quick_cancel_reason_input');
  const quickCancelReasonConfirmBtn = document.getElementById('quickCancelReasonConfirmBtn');
  const quickCancelReasonModalTitle = document.getElementById('quickCancelReasonModalTitle');
  const quickCancelReasonModalSubtitle = document.getElementById('quickCancelReasonModalSubtitle');
  const quickCancelReasonCurrentTextWrap = document.getElementById('quickCancelReasonCurrentTextWrap');
  const quickCancelReasonCurrentText = document.getElementById('quickCancelReasonCurrentText');
  const quickCancelModalInstance = quickCancelModalEl ? bootstrap.Modal.getOrCreateInstance(quickCancelModalEl) : null;
  let allowQuickCancelSubmit = false;
  let quickCancelMode = 'create';

  const setQuickCancelModalMode = mode => {
    quickCancelMode = mode === 'edit' ? 'edit' : 'create';
    const currentReason = (quickCancellationReason?.value || '').trim();

    if (quickCancelReasonModalTitle) {
      quickCancelReasonModalTitle.textContent = quickCancelMode === 'edit'
        ? 'Editar motivo de cancelación'
        : 'Cancelar serenata';
    }

    if (quickCancelReasonModalSubtitle) {
      quickCancelReasonModalSubtitle.textContent = quickCancelMode === 'edit'
        ? 'Actualiza el motivo registrado para esta serenata cancelada.'
        : 'Confirma por qué esta serenata queda cancelada.';
    }

    if (quickCancelReasonCurrentTextWrap) {
      quickCancelReasonCurrentTextWrap.classList.toggle('d-none', quickCancelMode !== 'edit');
    }

    if (quickCancelReasonCurrentText) {
      quickCancelReasonCurrentText.textContent = currentReason || 'Sin motivo registrado.';
    }

    if (quickCancelReasonConfirmBtn) {
      quickCancelReasonConfirmBtn.textContent = quickCancelMode === 'edit' ? 'Guardar motivo' : 'Confirmar cancelación';
    }
  };

  if (quickCancelModalEl && quickCancelReasonInput) {
    quickCancelModalEl.addEventListener('shown.bs.modal', () => {
      quickCancelReasonInput.focus();
    });

    quickCancelModalEl.addEventListener('show.bs.modal', event => {
      const trigger = event.relatedTarget;
      const requestedEditMode = trigger?.hasAttribute('data-cancel-edit');
      setQuickCancelModalMode(requestedEditMode ? 'edit' : 'create');
      quickCancelReasonInput.value = requestedEditMode ? (quickCancellationReason?.value || '') : '';
    });
  }

  if (quickCancelReasonConfirmBtn && quickCancellationReason && quickStatusForm && quickCancelModalInstance) {
    quickCancelReasonConfirmBtn.addEventListener('click', () => {
      const reason = (quickCancelReasonInput?.value || '').trim();
      if (!reason) {
        showToast('error', 'Debes escribir un motivo de cancelación.');
        return;
      }
      quickCancellationReason.value = reason;
      allowQuickCancelSubmit = true;
      if (quickCancelMode === 'edit' && quickServiceStatus) {
        quickServiceStatus.value = 'Cancelada';
      }
      quickCancelModalInstance.hide();
      quickStatusForm.requestSubmit();
    });
  }

  if (quickStatusForm && quickServiceStatus && quickCancellationReason) {
    quickStatusForm.addEventListener('submit', event => {
      const nextStatus = (quickServiceStatus.value || '').trim();
      const currentStatus = (quickStatusForm.dataset.currentStatus || '').trim();
      const currentReason = (quickCancellationReason.value || '').trim();
      if (nextStatus !== 'Cancelada') {
        allowQuickCancelSubmit = false;
        quickCancellationReason.value = '';
        return;
      }

      if (currentStatus === 'Cancelada' && currentReason) {
        allowQuickCancelSubmit = false;
        return;
      }

      if (allowQuickCancelSubmit) {
        allowQuickCancelSubmit = false;
        return;
      }

      event.preventDefault();
      setQuickCancelModalMode('create');
      if (quickCancelReasonInput) quickCancelReasonInput.value = '';
      if (quickCancelModalInstance) {
        quickCancelModalInstance.show();
      } else {
        showToast('error', 'No se pudo abrir el modal de cancelación.');
      }
      if (!quickCancelModalInstance) {
        event.preventDefault();
      }
    });
  }

  const privateNoteCollapseEl = document.getElementById('servicePrivateNoteCollapse');
  const privateNoteToggleIcon = document.getElementById('servicePrivateNoteToggleIcon');
  if (privateNoteCollapseEl && privateNoteToggleIcon) {
    privateNoteCollapseEl.addEventListener('shown.bs.collapse', () => {
      privateNoteToggleIcon.classList.remove('tabler-plus');
      privateNoteToggleIcon.classList.add('tabler-minus');
    });

    privateNoteCollapseEl.addEventListener('hidden.bs.collapse', () => {
      privateNoteToggleIcon.classList.remove('tabler-minus');
      privateNoteToggleIcon.classList.add('tabler-plus');
    });
  }

  const internalNoteCollapseEl = document.getElementById('internalNoteCollapse');
  const internalNoteToggleIcon = document.getElementById('internalNoteToggleIcon');
  if (internalNoteCollapseEl && internalNoteToggleIcon) {
    internalNoteCollapseEl.addEventListener('shown.bs.collapse', () => {
      internalNoteToggleIcon.classList.remove('tabler-plus');
      internalNoteToggleIcon.classList.add('tabler-minus');
    });

    internalNoteCollapseEl.addEventListener('hidden.bs.collapse', () => {
      internalNoteToggleIcon.classList.remove('tabler-minus');
      internalNoteToggleIcon.classList.add('tabler-plus');
    });
  }

  const toTitleCase = value =>
    (value || '')
      .toLowerCase()
      .replace(/\b([a-záéíóúñ])/g, match => match.toUpperCase())
      .replace(/\bd\.?\s*c\.?\b/gi, 'D.C.')
      .replace(/\s+/g, ' ')
      .trim();

  const applyResolvedAddressFields = fields => {
    if (!fields || typeof fields !== 'object') return;
    const neighborhoodInput = document.getElementById('edit_neighborhood');
    const localityInput = document.getElementById('edit_locality');
    const countryInput = document.getElementById('edit_service_country');
    const departmentInput = document.getElementById('edit_service_department');
    const urbanLocalityInput = document.getElementById('edit_service_locality');
    const sectorInput = document.getElementById('edit_service_sector');

    if (countryInput && fields.service_country) countryInput.value = toTitleCase(fields.service_country);
    if (departmentInput && fields.service_department) departmentInput.value = toTitleCase(fields.service_department);
    if (localityInput && fields.locality) localityInput.value = toTitleCase(fields.locality);
    if (urbanLocalityInput && fields.service_locality) urbanLocalityInput.value = toTitleCase(fields.service_locality);
    if (sectorInput && fields.service_sector) sectorInput.value = toTitleCase(fields.service_sector);
    if (neighborhoodInput && fields.neighborhood) neighborhoodInput.value = toTitleCase(fields.neighborhood);
  };

  const initEditAddressAutocomplete = async () => {
    const addressInput = document.getElementById('edit_service_address');
    const suggestionsBox = document.getElementById('editServiceAddressSuggestions');
    if (!addressInput || !suggestionsBox || !addressSuggestionsUrl) return false;
    let debounceTimer = null;

    const hideSuggestions = () => {
      suggestionsBox.classList.add('d-none');
      suggestionsBox.innerHTML = '';
    };

    const renderSuggestions = suggestions => {
      if (!Array.isArray(suggestions) || !suggestions.length) {
        hideSuggestions();
        return;
      }

      suggestionsBox.innerHTML = '';
      suggestions.forEach(suggestion => {
        const item = document.createElement('div');
        item.className = 'gm-address-suggestion-item';
        item.textContent = suggestion.description;

        item.addEventListener('click', async () => {
          addressInput.value = suggestion.description;
          hideSuggestions();

          if (!addressResolveUrl) return;
          try {
            const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') || '';
            const response = await fetch(addressResolveUrl, {
              method: 'POST',
              headers: {
                'Content-Type': 'application/json',
                Accept: 'application/json',
                'X-Requested-With': 'XMLHttpRequest',
                'X-CSRF-TOKEN': csrfToken
              },
              body: JSON.stringify({
                service_address: suggestion.description,
                address_additional: document.getElementById('edit_address_additional')?.value || '',
                service_country: document.getElementById('edit_service_country')?.value || '',
                service_department: document.getElementById('edit_service_department')?.value || '',
                neighborhood: '',
                locality: document.getElementById('edit_locality')?.value || '',
                service_locality: document.getElementById('edit_service_locality')?.value || '',
                service_sector: document.getElementById('edit_service_sector')?.value || ''
              })
            });
            const data = await response.json();
            if (!response.ok || !data?.fields) return;
            if (data.fields.service_address) addressInput.value = data.fields.service_address;
            applyResolvedAddressFields(data.fields);
          } catch (error) {
            // no-op
          }
        });

        suggestionsBox.appendChild(item);
      });

      suggestionsBox.classList.remove('d-none');
    };

    addressInput.addEventListener('input', () => {
      const query = (addressInput.value || '').trim();
      if (debounceTimer) clearTimeout(debounceTimer);
      if (query.length < 3) {
        hideSuggestions();
        return;
      }

      debounceTimer = setTimeout(async () => {
        try {
          const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') || '';
          const response = await fetch(addressSuggestionsUrl, {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json',
              Accept: 'application/json',
              'X-Requested-With': 'XMLHttpRequest',
              'X-CSRF-TOKEN': csrfToken
            },
            body: JSON.stringify({
              query,
              country: googleMapsCountry
            })
          });
          const data = await response.json();
          if (!response.ok) {
            hideSuggestions();
            return;
          }
          renderSuggestions(data.suggestions || []);
        } catch (error) {
          hideSuggestions();
        }
      }, 220);
    });

    addressInput.addEventListener('blur', () => setTimeout(hideSuggestions, 150));
    document.addEventListener('click', event => {
      if (!addressInput.closest('.position-relative')?.contains(event.target)) {
        hideSuggestions();
      }
    });

    return true;
  };

  if (addressSuggestionsUrl) {
    initEditAddressAutocomplete();
  }

  const selectedAddressOption = document.getElementById('selected_address_option');
  const selectedAddressPreview = document.getElementById('selectedAddressPreview');
  const selectedServiceAddress = document.getElementById('selected_service_address');
  const selectedAddressAdditional = document.getElementById('selected_address_additional');
  const selectedServiceCountry = document.getElementById('selected_service_country');
  const selectedServiceDepartment = document.getElementById('selected_service_department');
  const selectedNeighborhood = document.getElementById('selected_neighborhood');
  const selectedLocality = document.getElementById('selected_locality');
  const selectedServiceLocality = document.getElementById('selected_service_locality');
  const selectedServiceSector = document.getElementById('selected_service_sector');

  if (selectedAddressOption) {
    selectedAddressOption.addEventListener('change', () => {
      const option = selectedAddressOption.options[selectedAddressOption.selectedIndex];
      if (!option || !option.dataset.serviceAddress) {
        if (selectedAddressPreview) {
          selectedAddressPreview.textContent = 'Selecciona una dirección para ver el detalle.';
        }
        return;
      }

      const serviceAddress = option.dataset.serviceAddress || '';
      const addressAdditional = option.dataset.addressAdditional || '';
      const serviceCountry = option.dataset.serviceCountry || '';
      const serviceDepartment = option.dataset.serviceDepartment || '';
      const neighborhood = option.dataset.neighborhood || '';
      const locality = option.dataset.locality || '';
      const serviceLocality = option.dataset.serviceLocality || '';
      const serviceSector = option.dataset.serviceSector || '';

      if (selectedServiceAddress) selectedServiceAddress.value = serviceAddress;
      if (selectedAddressAdditional) selectedAddressAdditional.value = addressAdditional;
      if (selectedServiceCountry) selectedServiceCountry.value = serviceCountry;
      if (selectedServiceDepartment) selectedServiceDepartment.value = serviceDepartment;
      if (selectedNeighborhood) selectedNeighborhood.value = neighborhood;
      if (selectedLocality) selectedLocality.value = locality;
      if (selectedServiceLocality) selectedServiceLocality.value = serviceLocality;
      if (selectedServiceSector) selectedServiceSector.value = serviceSector;

      if (selectedAddressPreview) {
        const parts = [
          serviceAddress,
          addressAdditional,
          serviceSector ? `Sector: ${serviceSector}` : '',
          neighborhood ? `Barrio: ${neighborhood}` : '',
          serviceLocality ? `Localidad: ${serviceLocality}` : '',
          locality ? `Ciudad/Municipio: ${locality}` : '',
          serviceDepartment ? `Departamento: ${serviceDepartment}` : '',
          serviceCountry ? `País: ${serviceCountry}` : ''
        ].filter(Boolean);
        selectedAddressPreview.textContent = parts.join(' | ');
      }
    });
  }

  const btnToggleCostActions = document.getElementById('btnToggleCostActions');
  const btnToggleCostEditor = document.getElementById('btnToggleCostEditor');
  const costEditorCollapse = document.getElementById('costEditorCollapse');
  let inlineEditMode = false;
  if (btnToggleCostActions) {
    btnToggleCostActions.addEventListener('click', () => {
      const actionColumns = document.querySelectorAll('.cost-actions-col');
      const hasVisible = [...actionColumns].some(col => !col.classList.contains('d-none'));
      inlineEditMode = !hasVisible;

      actionColumns.forEach(col => col.classList.toggle('d-none', hasVisible));
      btnToggleCostActions.classList.toggle('btn-label-secondary', hasVisible);
      btnToggleCostActions.classList.toggle('btn-primary', !hasVisible);

      if (btnToggleCostEditor) {
        btnToggleCostEditor.classList.toggle('d-none', hasVisible);
      }

      if (hasVisible && costEditorCollapse && costEditorCollapse.classList.contains('show')) {
        const collapseInstance = bootstrap.Collapse.getOrCreateInstance(costEditorCollapse);
        collapseInstance.hide();
      }

      if (hasVisible) {
        document.querySelectorAll('.remove-cost-confirmation').forEach(panel => panel.classList.add('d-none'));
        document.querySelectorAll('#costItemsTableBody tr').forEach(restoreDisplayForRow);
      } else {
        document.querySelectorAll('#costItemsTableBody tr').forEach(setInlineInputsForRow);
      }
      document.querySelectorAll('#costItemsTableBody tr').forEach(row => setRowSaveButtonState(row, inlineEditMode));
    });
  }

  document.addEventListener('click', event => {
    const rowSaveBtn = event.target.closest('.btn-inline-save-cost-item');
    if (rowSaveBtn) return;

    const showConfirmBtn = event.target.closest('.btn-show-remove-cost-confirm');
    if (showConfirmBtn) {
      const form = showConfirmBtn.closest('.form-remove-cost-item');
      const confirmPanel = form?.querySelector('.remove-cost-confirmation');
      const reasonField = form?.querySelector('.remove-cost-reason-input');
      if (!form || !confirmPanel) return;
      document.querySelectorAll('.remove-cost-confirmation').forEach(panel => {
        if (panel !== confirmPanel) panel.classList.add('d-none');
      });
      confirmPanel.classList.toggle('d-none');
      if (!confirmPanel.classList.contains('d-none') && reasonField) reasonField.focus();
      return;
    }

    const cancelConfirmBtn = event.target.closest('.btn-cancel-remove-cost-item');
    if (cancelConfirmBtn) {
      const form = cancelConfirmBtn.closest('.form-remove-cost-item');
      form?.querySelector('.remove-cost-confirmation')?.classList.add('d-none');
    }
  });

  document.addEventListener('submit', async event => {
    const removeForm = event.target.closest('.form-remove-cost-item');
    if (removeForm) {
      event.preventDefault();
      const reasonInput = removeForm.querySelector('input[name="reason"]');
      const reasonField = removeForm.querySelector('.remove-cost-reason-input');
      if (reasonInput && reasonField) reasonInput.value = reasonField.value.trim();
      const formData = new FormData(removeForm);
      const row = removeForm.closest('tr');
      try {
        const response = await fetch(removeForm.action, {
          method: 'POST',
          headers: { Accept: 'application/json', 'X-Requested-With': 'XMLHttpRequest' },
          body: formData
        });
        const data = await response.json();
        if (!response.ok) {
          showToast('error', data.message || 'No se pudo eliminar el producto.');
          return;
        }
        markRowAsDeleted(row, data?.removed_item?.delete_reason || reasonInput?.value || '');
        updateCostSummary(data.financials || null);
        if (data.refresh_required) {
          window.location.reload();
          return;
        }
        showToast('success', data.message || 'Producto eliminado.');
      } catch (error) {
        showToast('error', 'Error de red al eliminar el producto.');
      }
      return;
    }

    const restoreForm = event.target.closest('.form-restore-cost-item');
    if (restoreForm) {
      event.preventDefault();
      const formData = new FormData(restoreForm);
      const row = restoreForm.closest('tr');
      try {
        const response = await fetch(restoreForm.action, {
          method: 'POST',
          headers: { Accept: 'application/json', 'X-Requested-With': 'XMLHttpRequest' },
          body: formData
        });
        const data = await response.json();
        if (!response.ok) {
          showToast('error', data.message || 'No se pudo restaurar el producto.');
          return;
        }
        restoreRowAsActive(row, data.restored_item || null);
        updateCostSummary(data.financials || null);
        if (data.refresh_required) {
          window.location.reload();
          return;
        }
        showToast('success', data.message || 'Ítem restaurado correctamente.');
      } catch (error) {
        showToast('error', 'Error de red al restaurar el producto.');
      }
      return;
    }
  });

  document.addEventListener('click', async event => {
    const rowSaveBtn = event.target.closest('.btn-inline-save-cost-item');
    if (!rowSaveBtn) return;
    if (!inlineEditMode) return;
    if (!updateCostUrl) {
      showToast('error', 'No se encontró la ruta para actualizar ítems.');
      return;
    }

    const row = rowSaveBtn.closest('tr');
    if (!row || row.classList.contains('table-secondary')) return;

    const qtyInput = row.querySelector('.inline-edit-quantity');
    const unitInput = row.querySelector('.inline-edit-unit-price');
    if (!qtyInput || !unitInput) return;

    const quantity = Math.max(1, Number.parseInt(qtyInput.value || '1', 10) || 1);
    const unitPrice = Math.max(0, Math.round(parseCopInput(unitInput.value || '0')));
    qtyInput.value = String(quantity);
    unitInput.value = formatCopPlain(unitPrice);

    const formData = new FormData();
    const csrf = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') || '';
    formData.append('_token', csrf);
    formData.append('_method', 'PATCH');
    formData.append('source', row.dataset.source || rowSaveBtn.dataset.source || '');
    formData.append('index', row.dataset.index || rowSaveBtn.dataset.index || '');
    formData.append('quantity', String(quantity));
    formData.append('unit_price', String(unitPrice));

    try {
      const response = await fetch(updateCostUrl, {
        method: 'POST',
        headers: { Accept: 'application/json', 'X-Requested-With': 'XMLHttpRequest' },
        body: formData
      });
      const data = await response.json();
      if (!response.ok) {
        showToast('error', data.message || 'No se pudo actualizar el ítem.');
        return;
      }

      const updated = data.updated_item || {};
      row.dataset.quantity = String(updated.quantity ?? quantity);
      row.dataset.unitPrice = String(Math.round(Number(updated.unit_price ?? unitPrice)));
      row.dataset.total = String(Math.round(Number(updated.total ?? (quantity * unitPrice))));
      const totalCell = row.querySelector('.cost-col-total');
      if (totalCell) totalCell.textContent = formatCop(row.dataset.total);
      setRowSaveButtonState(row, inlineEditMode);
      updateCostSummary(data.financials || null);
      if (data.refresh_required) {
        window.location.reload();
        return;
      }
      showToast('success', data.message || 'Ítem actualizado correctamente.');
    } catch (error) {
      showToast('error', 'Error de red al actualizar el ítem.');
    }
  });

  document.addEventListener('input', event => {
    const qtyInput = event.target.closest('.inline-edit-quantity');
    const unitInput = event.target.closest('.inline-edit-unit-price');
    const row = (qtyInput || unitInput)?.closest('tr');
    if (!row) return;
    const currentQtyInput = row.querySelector('.inline-edit-quantity');
    const currentUnitInput = row.querySelector('.inline-edit-unit-price');
    const totalCell = row.querySelector('.cost-col-total');
    if (!currentQtyInput || !currentUnitInput || !totalCell) return;
    const qty = Math.max(1, Number.parseInt(currentQtyInput.value || '1', 10) || 1);
    const unit = Math.max(0, Math.round(parseCopInput(currentUnitInput.value || '0')));
    totalCell.textContent = formatCop(qty * unit);
    setRowSaveButtonState(row, inlineEditMode);
  });

  document.addEventListener('blur', event => {
    const inlineUnitInput = event.target.closest('.inline-edit-unit-price');
    if (inlineUnitInput) {
      const unit = Math.max(0, Math.round(parseCopInput(inlineUnitInput.value || '0')));
      inlineUnitInput.value = formatCopPlain(unit);
    }
  }, true);

  document.querySelectorAll('.cost-pick-form').forEach(form => {
    const hiddenItemKey = form.querySelector('input[name="item_key"]');
    const unitPriceInput = form.querySelector('input[name="unit_price"]');
    const quantityInput = form.querySelector('input[name="quantity"]');
    const cards = form.querySelectorAll('.cost-pick-card');
    let isSubmitting = false;

    const getCardQty = card => {
      const qtyInput = card.querySelector('.cost-pick-qty-input');
      return Math.max(1, parseInt(qtyInput?.value || '1', 10) || 1);
    };

    const submitCardSelection = async card => {
      if (isSubmitting) return;
      const itemKey = card.dataset.itemKey || '';
      if (!itemKey || !hiddenItemKey || !unitPriceInput || !quantityInput) {
        showToast('error', 'No se pudo preparar el producto seleccionado.');
        return;
      }

      const defaultPrice = Math.max(0, Math.round(parseFloat(card.dataset.defaultPrice || '0') || 0));
      hiddenItemKey.value = itemKey;
      unitPriceInput.value = String(defaultPrice);
      quantityInput.value = String(getCardQty(card));

      isSubmitting = true;
      const previousPointerEvents = card.style.pointerEvents;
      card.style.pointerEvents = 'none';

      const formData = new FormData(form);
      try {
        const response = await fetch(form.action, {
          method: 'POST',
          headers: { Accept: 'application/json', 'X-Requested-With': 'XMLHttpRequest' },
          body: formData
        });
        const data = await response.json();
        if (!response.ok) {
          showToast('error', data.message || 'No se pudo agregar el producto.');
          return;
        }
        appendNewCostRow(data.added_item || null);
        if (inlineEditMode) {
          document.querySelectorAll('#costItemsTableBody tr').forEach(setInlineInputsForRow);
          document.querySelectorAll('#costItemsTableBody tr').forEach(row => setRowSaveButtonState(row, true));
        }
        updateCostSummary(data.financials || null);
        if (data.refresh_required) {
          window.location.reload();
          return;
        }
        showToast('success', data.message || 'Producto agregado.');
      } catch (error) {
        showToast('error', 'Error de red al agregar el producto.');
      } finally {
        isSubmitting = false;
        card.style.pointerEvents = previousPointerEvents || '';
      }
    };

    cards.forEach(card => {
      const minusBtn = card.querySelector('.cost-pick-qty-minus');
      const plusBtn = card.querySelector('.cost-pick-qty-plus');
      const qtyInput = card.querySelector('.cost-pick-qty-input');
      const addBtn = card.querySelector('.cost-pick-add-btn');

      minusBtn?.addEventListener('click', event => {
        event.preventDefault();
        event.stopPropagation();
        if (!qtyInput) return;
        const current = Math.max(1, parseInt(qtyInput.value || '1', 10) || 1);
        qtyInput.value = String(Math.max(1, current - 1));
      });

      plusBtn?.addEventListener('click', event => {
        event.preventDefault();
        event.stopPropagation();
        if (!qtyInput) return;
        const current = Math.max(1, parseInt(qtyInput.value || '1', 10) || 1);
        qtyInput.value = String(current + 1);
      });

      qtyInput?.addEventListener('click', event => event.stopPropagation());
      qtyInput?.addEventListener('input', event => {
        event.stopPropagation();
        const qty = Math.max(1, parseInt(qtyInput.value || '1', 10) || 1);
        qtyInput.value = String(qty);
      });

      addBtn?.addEventListener('click', event => {
        event.preventDefault();
        event.stopPropagation();
        submitCardSelection(card);
      });
    });

    form.addEventListener('submit', event => event.preventDefault());
  });
});
