(() => {
  let duplicateSource = null;

  function canDuplicateWalks() {
    return !!window.PYRK_CAN_CREATE_WALKS;
  }

  function byId(id) {
    return document.getElementById(id);
  }

  function timeValue(value) {
    return value ? String(value).slice(0, 5) : '';
  }

  function displayDate(value) {
    if (!value) return '—';
    const match = String(value).match(/^(\d{4})-(\d{2})-(\d{2})/);
    return match ? `${match[3]}/${match[2]}/${match[1]}` : String(value);
  }

  function localIsoDate(date) {
    return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
  }

  function suggestedDuplicateDate(sourceDate) {
    const sourceMatch = String(sourceDate || '').match(/^(\d{4})-(\d{2})-(\d{2})/);
    const source = sourceMatch
      ? new Date(Number(sourceMatch[1]), Number(sourceMatch[2]) - 1, Number(sourceMatch[3]))
      : new Date();
    source.setHours(12, 0, 0, 0);
    source.setDate(source.getDate() + 7);

    const earliest = new Date();
    earliest.setHours(12, 0, 0, 0);
    earliest.setDate(earliest.getDate() + 1);
    while (source < earliest) source.setDate(source.getDate() + 7);
    return localIsoDate(source);
  }

  function suggestedDuplicateTitle(title) {
    const clean = String(title || 'Walk').trim() || 'Walk';
    return `${clean} - Copy`;
  }

  function sourceTeamCount(walk) {
    return (String(walk?.manager_names || '').trim() ? 1 : 0)
      + (String(walk?.head_walker_names || '').trim() ? 1 : 0)
      + Number(walk?.assigned_walker_count || 0);
  }

  function sourceInviteCount(walk) {
    return Number(walk?.invited_member_count || 0) + Number(walk?.invited_group_count || 0);
  }

  function setMessage(message = '', type = '') {
    const box = byId('walkDuplicateMsg');
    if (!box) return;
    box.textContent = message;
    box.className = `notice${type ? ` ${type}` : ''}`;
    box.hidden = !message;
  }

  function closeDuplicateModal() {
    if (window.Pyrk && typeof Pyrk.closeModal === 'function') {
      Pyrk.closeModal('walkDuplicateModal');
    } else {
      const modal = byId('walkDuplicateModal');
      if (modal) modal.hidden = true;
      document.body.classList.remove('modal-open');
    }
    duplicateSource = null;
    setMessage();
  }

  function openDuplicateModal() {
    if (window.Pyrk && typeof Pyrk.openModal === 'function') {
      Pyrk.openModal('walkDuplicateModal');
    } else {
      const modal = byId('walkDuplicateModal');
      if (modal) modal.hidden = false;
      document.body.classList.add('modal-open');
    }
  }

  window.duplicateWalk = function duplicateWalk(id) {
    if (!canDuplicateWalks()) {
      alert('You do not have permission to duplicate walks.');
      return;
    }

    const source = (typeof allWalks !== 'undefined' && Array.isArray(allWalks))
      ? allWalks.find(item => Number(item.id) === Number(id))
      : null;
    if (!source) {
      alert('Walk not found. Refresh the page and try again.');
      return;
    }

    duplicateSource = source;
    const teamCount = sourceTeamCount(source);
    const inviteCount = sourceInviteCount(source);

    byId('walkDuplicateSourceId').value = String(source.id);
    byId('walkDuplicateSourceName').textContent = source.title || 'Walk';
    byId('walkDuplicateSourceMeta').textContent = `${source.route_name || 'Route'} · ${displayDate(source.walk_date)} ${timeValue(source.start_time)} · ${Number(source.total_km || 0).toFixed(1)} KM`;
    byId('walkDuplicateName').value = suggestedDuplicateTitle(source.title);
    byId('walkDuplicateDate').value = suggestedDuplicateDate(source.walk_date);
    byId('walkDuplicateStartTime').value = timeValue(source.start_time);
    byId('walkDuplicateFinishTime').value = timeValue(source.expected_finish_time);
    byId('walkDuplicateStatus').value = 'draft';
    byId('walkDuplicateCopyDeadlines').checked = true;

    const teamCheckbox = byId('walkDuplicateCopyTeam');
    teamCheckbox.disabled = teamCount === 0;
    teamCheckbox.checked = teamCount > 0;
    byId('walkDuplicateTeamHint').textContent = teamCount > 0
      ? `${teamCount} assigned team member${teamCount === 1 ? '' : 's'} will be copied.`
      : 'No team is assigned to the source walk.';

    const inviteCheckbox = byId('walkDuplicateCopyInvitations');
    inviteCheckbox.disabled = inviteCount === 0;
    inviteCheckbox.checked = false;
    byId('walkDuplicateInviteHint').textContent = inviteCount > 0
      ? `${inviteCount} invitation record${inviteCount === 1 ? '' : 's'} available. No email will be sent.`
      : 'The source walk has no invitation list.';

    setMessage();
    openDuplicateModal();
    window.setTimeout(() => {
      const name = byId('walkDuplicateName');
      name?.focus();
      name?.select();
    }, 50);
  };

  const form = byId('walkDuplicateForm');
  form?.addEventListener('submit', async event => {
    event.preventDefault();
    if (!canDuplicateWalks()) return;

    const sourceId = Number(byId('walkDuplicateSourceId')?.value || 0);
    const title = String(byId('walkDuplicateName')?.value || '').trim();
    const walkDate = String(byId('walkDuplicateDate')?.value || '').trim();
    const startTime = String(byId('walkDuplicateStartTime')?.value || '').trim();
    const finishTime = String(byId('walkDuplicateFinishTime')?.value || '').trim();
    const status = String(byId('walkDuplicateStatus')?.value || 'draft');
    const submit = byId('confirmWalkDuplicateBtn');

    if (!sourceId || !duplicateSource) {
      setMessage('The source walk is missing. Close this window and try again.', 'bad');
      return;
    }
    if (!title) {
      setMessage('Enter a title for the duplicated walk.', 'bad');
      byId('walkDuplicateName')?.focus();
      return;
    }
    if (!walkDate || !startTime || !finishTime) {
      setMessage('Choose the new date, start time, and expected finish time.', 'bad');
      return;
    }
    if (startTime >= finishTime) {
      setMessage('Start time must be before expected finish time.', 'bad');
      return;
    }

    if (submit) {
      submit.disabled = true;
      submit.dataset.originalText = submit.textContent;
      submit.textContent = 'Duplicating…';
    }
    setMessage('Creating a fresh walk and copying the selected setup…');

    try {
      const response = await Pyrk.post('walks.php', {
        action: 'duplicate',
        source_walk_id: sourceId,
        title,
        walk_date: walkDate,
        start_time: startTime,
        expected_finish_time: finishTime,
        status,
        copy_deadlines: byId('walkDuplicateCopyDeadlines')?.checked ? 1 : 0,
        copy_team: byId('walkDuplicateCopyTeam')?.checked ? 1 : 0,
        copy_invitations: byId('walkDuplicateCopyInvitations')?.checked ? 1 : 0
      });

      if (!response.ok) {
        setMessage(response.message || 'Could not duplicate walk.', 'bad');
        return;
      }

      const newWalkId = Number(response.data?.walk_id || 0);
      closeDuplicateModal();
      if (!newWalkId) {
        alert(response.message || 'Walk duplicated.');
        return;
      }

      // Always return to the upcoming page because finished/archived pages do not
      // contain the edit form. The new walk opens immediately for review.
      window.location.href = `walks.php?edit_walk=${newWalkId}&duplicated=1`;
    } catch (error) {
      setMessage(error?.message || 'Could not duplicate walk.', 'bad');
    } finally {
      if (submit) {
        submit.disabled = false;
        submit.textContent = submit.dataset.originalText || 'Duplicate & review';
        delete submit.dataset.originalText;
      }
    }
  });

  byId('closeWalkDuplicateBtn')?.addEventListener('click', closeDuplicateModal);
  byId('cancelWalkDuplicateBtn')?.addEventListener('click', closeDuplicateModal);
  byId('walkDuplicateModal')?.addEventListener('click', event => {
    if (event.target === byId('walkDuplicateModal')) closeDuplicateModal();
  });

  document.addEventListener('keydown', event => {
    const modal = byId('walkDuplicateModal');
    if (event.key === 'Escape' && modal && !modal.hidden) closeDuplicateModal();
  });

  async function openDuplicatedWalkForReview() {
    const params = new URLSearchParams(window.location.search);
    const walkId = Number(params.get('edit_walk') || 0);
    if (!walkId || !byId('walkForm') || typeof window.editWalk !== 'function') return;

    // Wait until the route picker and creation data started by admin_walks.js are ready.
    for (let attempt = 0; attempt < 30; attempt += 1) {
      const routesReady = typeof walkRoutes !== 'undefined' && Array.isArray(walkRoutes) && walkRoutes.length > 0;
      if (routesReady) break;
      await new Promise(resolve => window.setTimeout(resolve, 100));
    }

    await window.editWalk(walkId);
    if (params.get('duplicated') === '1' && window.Pyrk && typeof Pyrk.toast === 'function') {
      Pyrk.toast('walkMsg', { ok: true, message: 'Walk duplicated safely. Review the draft, adjust anything needed, then save it.' });
    }
    params.delete('edit_walk');
    params.delete('duplicated');
    const query = params.toString();
    window.history.replaceState({}, '', `${window.location.pathname}${query ? `?${query}` : ''}${window.location.hash || ''}`);
  }

  window.addEventListener('load', () => {
    window.setTimeout(openDuplicatedWalkForReview, 120);
  });
})();
