'use strict';

document.addEventListener('DOMContentLoaded', () => {
  const wrapper = document.getElementById('plannerKanbanWrapper');
  const mariachiSelect = document.getElementById('planner_mariachi');
  const citySelect = document.getElementById('planner_city');
  const dateInput = document.getElementById('planner_date');
  const btnLoad = document.getElementById('btnPlannerLoad');
  const btnOptimize = document.getElementById('btnPlannerOptimize');
  const metaContainer = document.getElementById('plannerMeta');
  const modalElement = document.getElementById('modalSerenataViewPlanner');
  const frameElement = document.getElementById('plannerSerenataViewFrame');

  if (!wrapper || !mariachiSelect || !citySelect || !dateInput) {
    return;
  }

  const dataUrl = window.__plannerDataUrl;
  const moveUrl = window.__plannerMoveUrl;
  const optimizeUrl = window.__plannerOptimizeUrl;
  const defaults = window.__plannerDefaults || {};
  const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') || '';

  let kanbanInstance = null;
  let saveTimer = null;
  let isSaving = false;

  const notyf = typeof Notyf !== 'undefined'
    ? new Notyf({
        duration: 2800,
        dismissible: true,
        position: { x: 'right', y: 'top' }
      })
    : null;

  const toast = (type, message) => {
    if (!message) {
      return;
    }
    if (notyf) {
      notyf.open({ type, message });
      return;
    }
    if (type === 'error') {
      console.error(message);
      return;
    }
    console.log(message);
  };

  const setLoading = (button, loading) => {
    if (!button) {
      return;
    }
    button.disabled = !!loading;
    if (loading) {
      button.dataset.originalText = button.textContent;
      button.textContent = 'Procesando...';
      return;
    }
    if (button.dataset.originalText) {
      button.textContent = button.dataset.originalText;
      delete button.dataset.originalText;
    }
  };

  const normalizeBoards = boards =>
    (Array.isArray(boards) ? boards : []).map(board => ({
      id: String(board.id || ''),
      title: String(board.title || 'Sin barrio'),
      item: Array.isArray(board.item) ? board.item : []
    }));

  const selectedCityValues = () => {
    const values = Array.from(citySelect.selectedOptions || [])
      .map(option => (option.value || '').trim())
      .filter(Boolean);

    if (!values.length || values.includes('__all__')) {
      return [];
    }
    return values;
  };

  const selectedCityLabel = () => {
    const cities = selectedCityValues();
    if (!cities.length) {
      return 'Todas';
    }
    return cities.join(', ');
  };

  const currentState = () => ({
    date: (dateInput.value || '').trim(),
    cities: selectedCityValues(),
    mariachi_key: (mariachiSelect.value || '').trim(),
    mariachi_label: mariachiSelect.options[mariachiSelect.selectedIndex]?.text || ''
  });

  const renderMeta = meta => {
    if (!metaContainer) {
      return;
    }
    const count = Number(meta?.count || 0);
    const city = meta?.city || selectedCityLabel();
    const date = meta?.date || currentState().date;
    const mariachi = meta?.mariachi_label || currentState().mariachi_label;
    metaContainer.innerHTML = [
      `<span class="badge bg-label-primary">Servicios: ${count}</span>`,
      `<span class="badge bg-label-info">Ciudad: ${city || 'Todas'}</span>`,
      `<span class="badge bg-label-secondary">Fecha: ${date}</span>`,
      `<span class="badge bg-label-success">Grupo: ${mariachi}</span>`
    ].join('');
  };

  const renderEmpty = () => {
    wrapper.innerHTML = `
      <div class="card">
        <div class="card-body text-center text-body-secondary py-8">
          No hay serenatas para los filtros seleccionados.
        </div>
      </div>
    `;
  };

  const collectColumns = () => {
    return Array.from(wrapper.querySelectorAll('.kanban-board')).map(board => {
      const columnKey = (board.getAttribute('data-id') || '').trim();
      const titleEl = board.querySelector('.kanban-title-board');
      const columnLabel = (titleEl?.textContent || '').trim() || 'Sin barrio';
      const serenataIds = Array.from(board.querySelectorAll('.kanban-item[data-eid]'))
        .map(item => parseInt(item.getAttribute('data-eid') || '0', 10))
        .filter(id => Number.isInteger(id) && id > 0);

      return {
        column_key: columnKey || 'sin-barrio',
        column_label: columnLabel,
        serenata_ids: serenataIds
      };
    });
  };

  const persistOrder = async () => {
    if (isSaving || !moveUrl) {
      return;
    }
    const state = currentState();
    if (!state.date || !state.mariachi_key) {
      return;
    }

    const payload = {
      date: state.date,
      cities: state.cities,
      mariachi_key: state.mariachi_key,
      mariachi_label: state.mariachi_label,
      columns: collectColumns()
    };

    isSaving = true;
    try {
      const response = await fetch(moveUrl, {
        method: 'PATCH',
        headers: {
          'Content-Type': 'application/json',
          Accept: 'application/json',
          'X-CSRF-TOKEN': csrfToken
        },
        body: JSON.stringify(payload)
      });

      const result = await response.json().catch(() => ({}));
      if (!response.ok || !result?.success) {
        throw new Error(result?.message || 'No se pudo guardar el orden de ruta.');
      }
      toast('success', result.message || 'Ruta actualizada.');
    } catch (error) {
      toast('error', error.message || 'No se pudo guardar el orden.');
    } finally {
      isSaving = false;
    }
  };

  const schedulePersist = () => {
    if (saveTimer) {
      clearTimeout(saveTimer);
    }
    saveTimer = setTimeout(() => {
      persistOrder();
    }, 350);
  };

  const buildKanban = boards => {
    wrapper.innerHTML = '';
    if (!boards.length) {
      renderEmpty();
      return;
    }

    kanbanInstance = new jKanban({
      element: '#plannerKanbanWrapper',
      gutter: '12px',
      widthBoard: '320px',
      dragItems: true,
      dragBoards: false,
      addItemButton: false,
      boards,
      dropEl: () => {
        schedulePersist();
      }
    });

    wrapper.querySelectorAll('.kanban-item').forEach(item => {
      item.classList.add('cursor-pointer');
    });
  };

  const loadBoards = async ({ silent = false } = {}) => {
    if (!dataUrl) {
      return;
    }
    const state = currentState();
    if (!state.date) {
      toast('error', 'Selecciona una fecha.');
      return;
    }

    setLoading(btnLoad, true);
    try {
      const query = new URLSearchParams({
        date: state.date,
        mariachi_key: state.mariachi_key
      });
      state.cities.forEach(city => {
        query.append('cities[]', city);
      });
      const response = await fetch(`${dataUrl}?${query.toString()}`, {
        headers: { Accept: 'application/json' }
      });
      const result = await response.json().catch(() => ({}));
      if (!response.ok || !result?.success) {
        throw new Error(result?.message || 'No se pudo cargar el planificador.');
      }

      buildKanban(normalizeBoards(result.boards));
      renderMeta(result.meta || {});
      if (!silent) {
        toast('success', `Planificador cargado (${result.meta?.count || 0} servicios).`);
      }
    } catch (error) {
      renderEmpty();
      renderMeta({ count: 0, date: state.date, city: selectedCityLabel(), mariachi_label: state.mariachi_label });
      toast('error', error.message || 'No se pudo cargar la información.');
    } finally {
      setLoading(btnLoad, false);
    }
  };

  const optimizeRoute = async () => {
    if (!optimizeUrl) {
      return;
    }
    const state = currentState();
    if (!state.date || !state.mariachi_key) {
      toast('error', 'Completa fecha y grupo para optimizar.');
      return;
    }

    setLoading(btnOptimize, true);
    try {
      const response = await fetch(optimizeUrl, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          Accept: 'application/json',
          'X-CSRF-TOKEN': csrfToken
        },
        body: JSON.stringify({
          date: state.date,
          cities: state.cities,
          mariachi_key: state.mariachi_key,
          mariachi_label: state.mariachi_label
        })
      });
      const result = await response.json().catch(() => ({}));
      if (!response.ok || !result?.success) {
        throw new Error(result?.message || 'No se pudo optimizar la ruta.');
      }

      toast('success', result.message || 'Ruta optimizada.');
      await loadBoards({ silent: true });
    } catch (error) {
      toast('error', error.message || 'No se pudo optimizar la ruta.');
    } finally {
      setLoading(btnOptimize, false);
    }
  };

  const openSerenataView = url => {
    if (!url || !modalElement || !frameElement) {
      return;
    }
    frameElement.setAttribute('src', url);
    bootstrap.Modal.getOrCreateInstance(modalElement).show();
  };

  const hideSerenataView = () => {
    const instance = modalElement ? bootstrap.Modal.getInstance(modalElement) : null;
    if (instance) {
      instance.hide();
    }
  };

  if (typeof $ !== 'undefined' && $.fn?.select2) {
    [mariachiSelect].forEach(select => {
      $(select).wrap('<div class="position-relative"></div>').select2({
        dropdownParent: $(select).parent(),
        width: '100%',
        minimumResultsForSearch: 8
      });
    });

    $(citySelect)
      .wrap('<div class="position-relative"></div>')
      .select2({
        dropdownParent: $(citySelect).parent(),
        width: '100%',
        closeOnSelect: false,
        placeholder: 'Selecciona ciudad(es)'
      })
      .on('change', () => {
        const values = $(citySelect).val() || [];
        const hasAll = values.includes('__all__');
        if (hasAll && values.length > 1) {
          $(citySelect).val(['__all__']).trigger('change.select2');
        } else if (!hasAll && values.length === 0) {
          $(citySelect).val(['__all__']).trigger('change.select2');
        }
        loadBoards({ silent: true });
      });
  } else {
    citySelect.addEventListener('change', () => {
      const rawValues = Array.from(citySelect.selectedOptions || []).map(option => option.value);
      if (rawValues.includes('__all__') && rawValues.length > 1) {
        Array.from(citySelect.options).forEach(option => {
          option.selected = option.value === '__all__';
        });
      } else if (!rawValues.length) {
        Array.from(citySelect.options).forEach(option => {
          option.selected = option.value === '__all__';
        });
      }
      loadBoards({ silent: true });
    });
  }

  if (typeof flatpickr !== 'undefined') {
    flatpickr(dateInput, {
      allowInput: true,
      dateFormat: 'Y-m-d',
      defaultDate: defaults.date || dateInput.value || null
    });
  }

  const defaultCities = Array.isArray(defaults.cities) && defaults.cities.length ? defaults.cities : ['__all__'];
  Array.from(citySelect.options).forEach(option => {
    option.selected = defaultCities.includes(option.value);
  });
  if (typeof $ !== 'undefined' && $.fn?.select2) {
    $(citySelect).trigger('change.select2');
  }
  if (defaults.mariachiKey) {
    mariachiSelect.value = defaults.mariachiKey;
  }

  btnLoad?.addEventListener('click', () => loadBoards());
  btnOptimize?.addEventListener('click', optimizeRoute);
  mariachiSelect.addEventListener('change', () => loadBoards({ silent: true }));
  dateInput.addEventListener('change', () => loadBoards({ silent: true }));

  wrapper.addEventListener('click', event => {
    const trigger = event.target.closest('.btn-open-serenata-view, .serenata-kanban-card');
    if (!trigger) {
      return;
    }

    const button = event.target.closest('.btn-open-serenata-view');
    if (button) {
      event.preventDefault();
      event.stopPropagation();
      openSerenataView(button.getAttribute('data-view-url'));
      return;
    }

    const card = event.target.closest('.serenata-kanban-card');
    if (card) {
      openSerenataView(card.getAttribute('data-view-url'));
    }
  });

  modalElement?.addEventListener('hidden.bs.modal', () => {
    frameElement?.setAttribute('src', 'about:blank');
  });

  window.addEventListener('message', event => {
    if (event.origin !== window.location.origin) return;
    if (event.data?.type !== 'serenata-embed-close-request') return;
    if (event.data?.context && event.data.context !== 'serenata-detail') return;

    hideSerenataView();
  });

  loadBoards({ silent: true });
});
