(function() {
  function ticketTemplateContainer(element) {
    return element && element.closest('.ux-toolkit-ticket-template-insert');
  }

  function descriptionField() {
    return document.getElementById('issue_description');
  }

  function selectedTemplateOption(select) {
    if (!select || select.selectedIndex < 0) {
      return null;
    }

    return select.options[select.selectedIndex];
  }

  function fieldValue(id) {
    var field = document.getElementById(id);
    return field ? field.value || '' : '';
  }

  function selectHasBlankValue(id) {
    var field = document.getElementById(id);
    if (!field || field.disabled) {
      return false;
    }

    return !field.value;
  }

  function appendWarning(warnings, enabled, message) {
    if (enabled) {
      warnings.push(message);
    }
  }

  function issueQualityCheckEnabled(container, key) {
    return container.getAttribute(key) === '1';
  }

  function issueQualityWarnings(container) {
    var minSubjectLength = parseInt(container.getAttribute('data-min-subject-length'), 10) || 8;
    var minDescriptionLength = parseInt(container.getAttribute('data-min-description-length'), 10) || 30;
    var subject = fieldValue('issue_subject').trim();
    var description = fieldValue('issue_description').trim();
    var warnings = [];

    appendWarning(
      warnings,
      issueQualityCheckEnabled(container, 'data-check-subject-short') && subject.length < minSubjectLength,
      container.getAttribute('data-message-subject-short')
    );

    appendWarning(
      warnings,
      issueQualityCheckEnabled(container, 'data-check-description-empty') && description.length === 0,
      container.getAttribute('data-message-description-empty')
    );

    appendWarning(
      warnings,
      issueQualityCheckEnabled(container, 'data-check-description-short') && description.length > 0 && description.length < minDescriptionLength,
      container.getAttribute('data-message-description-short')
    );

    appendWarning(
      warnings,
      issueQualityCheckEnabled(container, 'data-check-assignee-missing') && selectHasBlankValue('issue_assigned_to_id'),
      container.getAttribute('data-message-assignee-missing')
    );

    appendWarning(
      warnings,
      issueQualityCheckEnabled(container, 'data-check-priority-missing') && selectHasBlankValue('issue_priority_id'),
      container.getAttribute('data-message-priority-missing')
    );

    return warnings;
  }

  function updateIssueQualityCheck() {
    var containers = document.querySelectorAll('.ux-toolkit-issue-quality-check');

    containers.forEach(function(container) {
      var warnings = issueQualityWarnings(container);
      var heading = container.querySelector('strong');
      var list = container.querySelector('ul');

      if (!heading || !list) {
        return;
      }

      if (warnings.length === 0) {
        container.style.display = 'none';
        list.innerHTML = '';
        return;
      }

      heading.textContent = container.getAttribute('data-message-heading');
      list.innerHTML = '';

      warnings.forEach(function(message) {
        if (!message) {
          return;
        }

        var item = document.createElement('li');
        item.textContent = message;
        list.appendChild(item);
      });

      container.style.display = '';
    });
  }

  function insertText(textarea, templateText, confirmationText) {
    var currentText = textarea.value || '';
    var normalizedTemplate = templateText.replace(/\r\n/g, '\n');

    if (!currentText.trim()) {
      textarea.value = normalizedTemplate;
      return true;
    }

    if (!window.confirm(confirmationText)) {
      return false;
    }

    textarea.value = currentText.replace(/\s*$/, '') + "\n\n" + normalizedTemplate;
    return true;
  }

  function appendText(textarea, text) {
    var currentText = textarea.value || '';
    var normalizedText = text.replace(/\r\n/g, '\n');

    if (!currentText.trim()) {
      textarea.value = normalizedText;
      return;
    }

    textarea.value = currentText.replace(/\s*$/, '') + "\n\n" + normalizedText;
  }

  function initializeSettingsUsability() {
    var root = document.querySelector('[data-ux-toolkit-settings-root]');
    if (!root) {
      return;
    }

    var form = root.closest('form');
    var nativeSubmit = form && Array.prototype.find.call(form.children, function(element) {
      return element.matches('input[type="submit"], button[type="submit"]');
    });
    var unsavedIndicator = null;
    var search = root.querySelector('[data-ux-toolkit-settings-search]');
    var featureList = root.querySelector('[data-ux-toolkit-settings-feature-list]');
    var emptySearch = root.querySelector('.ux-toolkit-settings-search-empty');
    var dependencyMap = {
      settings_enable_assign_to_me_and_start_button: ['settings_assign_to_me_and_start_status_id'],
      settings_enable_quick_status_actions: ['settings_quick_status_action_status_ids'],
      settings_enable_issue_quality_check: [
        'settings_issue_quality_check_subject_short',
        'settings_issue_quality_check_description_empty',
        'settings_issue_quality_check_description_short',
        'settings_issue_quality_check_assignee_missing',
        'settings_issue_quality_check_priority_missing',
        'settings_issue_quality_min_subject_length',
        'settings_issue_quality_min_description_length'
      ],
      settings_enable_sla_light: [
        'settings_sla_light_first_response_hours',
        'settings_sla_light_resolution_hours',
        'settings_sla_light_pause_status_ids'
      ],
      settings_enable_issue_reminder_emails: [
        'settings_issue_reminder_send_time',
        'settings_issue_reminder_time_zone',
        'settings_issue_reminder_days_before_due'
      ],
      settings_enable_repository_refresh_scheduler: [
        'settings_repository_refresh_default_interval_minutes',
        'settings_repository_refresh_max_per_run',
        'settings_repository_refresh_max_runtime_seconds',
        'settings_repository_refresh_failure_backoff'
      ],
      settings_enable_attachment_trash: [
        'settings_attachment_trash_retention_days',
        'settings_attachment_trash_cleanup_limit'
      ],
      settings_attachment_preview_enabled: [
        'settings_attachment_preview_images',
        'settings_attachment_preview_pdfs',
        'settings_attachment_preview_gallery',
        'settings_attachment_preview_download'
      ],
      settings_modern_ui_enabled: [
        'settings_modern_ui_base',
        'settings_modern_ui_header',
        'settings_modern_ui_navigation',
        'settings_modern_ui_issue_list',
        'settings_modern_ui_issue_detail',
        'settings_modern_ui_forms',
        'settings_modern_ui_filters',
        'settings_modern_ui_project_overview',
        'settings_modern_ui_roadmap',
        'settings_modern_ui_activity',
        'settings_modern_ui_wiki',
        'settings_modern_ui_repository',
        'settings_modern_ui_login',
        'settings_modern_ui_admin',
        'settings_modern_ui_density',
        'settings_modern_ui_color_preset'
      ]
    };

    function setDependentState(controllerId, targetIds) {
      var controller = document.getElementById(controllerId);
      if (!controller) {
        return;
      }

      targetIds.forEach(function(targetId) {
        var target = document.getElementById(targetId);
        if (!target) {
          return;
        }

        var row = target.closest('p') || target.parentElement;
        row.classList.toggle('ux-toolkit-setting-dependent-disabled', !controller.checked);
        row.setAttribute('aria-disabled', controller.checked ? 'false' : 'true');
        target.tabIndex = controller.checked ? 0 : -1;
      });

      if (controllerId === 'settings_enable_issue_reminder_emails') {
        document.querySelectorAll('input[type="checkbox"][name="settings[issue_reminder_weekdays][]"]').forEach(function(target) {
          var row = target.closest('label');
          row.classList.toggle('ux-toolkit-setting-dependent-disabled', !controller.checked);
          target.tabIndex = controller.checked ? 0 : -1;
        });
      }
    }

    function selectedValues(id) {
      var field = document.getElementById(id);
      if (!field) {
        return [];
      }

      return Array.prototype.filter.call(field.options || [], function(option) {
        return option.selected && option.value;
      });
    }

    function configurationIncomplete(controller) {
      if (!controller.checked) {
        return false;
      }

      if (controller.id === 'settings_enable_assign_to_me_and_start_button') {
        return !fieldValue('settings_assign_to_me_and_start_status_id');
      }
      if (controller.id === 'settings_enable_quick_status_actions') {
        return selectedValues('settings_quick_status_action_status_ids').length === 0;
      }
      if (controller.id === 'settings_enable_issue_reminder_emails') {
        return document.querySelectorAll('input[name="settings[issue_reminder_weekdays][]"]:checked').length === 0;
      }
      if (controller.id === 'settings_attachment_preview_enabled') {
        var images = document.getElementById('settings_attachment_preview_images');
        var pdfs = document.getElementById('settings_attachment_preview_pdfs');
        return images && pdfs && !images.checked && !pdfs.checked;
      }

      return false;
    }

    function updateConfigurationWarning(controller) {
      var row = controller.closest('p') || controller.parentElement;
      var warning = row.querySelector('.ux-toolkit-setting-warning');
      var incomplete = configurationIncomplete(controller);

      if (incomplete && !warning) {
        warning = document.createElement('span');
        warning.className = 'ux-toolkit-setting-warning icon icon-warning';
        warning.textContent = root.getAttribute('data-config-warning');
        row.appendChild(warning);
      } else if (!incomplete && warning) {
        warning.remove();
      }
    }

    function updateDependencies() {
      Object.keys(dependencyMap).forEach(function(controllerId) {
        setDependentState(controllerId, dependencyMap[controllerId]);
        var controller = document.getElementById(controllerId);
        if (controller) {
          updateConfigurationWarning(controller);
        }
      });
    }

    if (search && featureList) {
      search.addEventListener('input', function() {
        var query = search.value.trim().toLowerCase();
        var visibleCount = 0;

        featureList.querySelectorAll('.ux-toolkit-settings-feature').forEach(function(item) {
          var matches = !query || item.getAttribute('data-settings-search-text').indexOf(query) !== -1;
          item.hidden = !matches;
          if (matches) {
            visibleCount += 1;
          }
        });

        if (emptySearch) {
          emptySearch.hidden = visibleCount !== 0;
        }
      });
    }

    if (form && nativeSubmit) {
      unsavedIndicator = document.createElement('span');
      unsavedIndicator.className = 'ux-toolkit-settings-unsaved-indicator icon icon-warning';
      unsavedIndicator.textContent = root.getAttribute('data-unsaved-label');
      unsavedIndicator.hidden = true;
      nativeSubmit.insertAdjacentElement('afterend', unsavedIndicator);

      var initialState = new window.URLSearchParams(new window.FormData(form)).toString();
      var updateDirtyState = function() {
        var dirty = new window.URLSearchParams(new window.FormData(form)).toString() !== initialState;
        unsavedIndicator.hidden = !dirty;
      };

      form.addEventListener('input', updateDirtyState);
      form.addEventListener('change', function() {
        updateDependencies();
        updateDirtyState();
      });
      form.addEventListener('submit', function() { unsavedIndicator.hidden = true; });
      root.addEventListener('click', function() { window.setTimeout(updateDirtyState, 0); });
    }

    updateDependencies();
  }

  function initializeDashboard() {
    var dashboard = document.querySelector('[data-ux-toolkit-dashboard]');
    if (dashboard) {
      dashboard.querySelectorAll('[data-dashboard-block]').forEach(function(block) {
        var key = 'redmine_ux_toolkit_dashboard_block_' + block.getAttribute('data-dashboard-block');
        if (window.localStorage.getItem(key) === 'closed') {
          block.removeAttribute('open');
        }
        block.addEventListener('toggle', function() {
          window.localStorage.setItem(key, block.open ? 'open' : 'closed');
        });
      });
    }

    var order = document.querySelector('[data-ux-toolkit-dashboard-order]');
    if (order) {
      order.addEventListener('click', function(event) {
        var button = event.target.closest('[data-dashboard-move]');
        if (!button) {
          return;
        }

        var item = button.closest('[data-dashboard-order-item]');
        var direction = button.getAttribute('data-dashboard-move');
        var sibling = direction === 'up' ? item.previousElementSibling : item.nextElementSibling;
        if (!sibling) {
          return;
        }

        if (direction === 'up') {
          order.insertBefore(item, sibling);
        } else {
          order.insertBefore(sibling, item);
        }
        item.querySelector('input[type="checkbox"]').focus();
      });
    }
  }

  function initializeChecklistControls() {
    document.querySelectorAll('.ux-toolkit-checklist-controls').forEach(function(details) {
      details.addEventListener('toggle', function() {
        if (details.open) {
          var newItem = details.querySelector('.ux-toolkit-checklist-new-item input[type="text"]');
          if (newItem) {
            newItem.focus();
          }
        }
      });
    });

    document.addEventListener('click', function(event) {
      var cancel = event.target.closest('[data-ux-toolkit-checklist-edit-cancel]');
      if (cancel) {
        var details = cancel.closest('details');
        if (details) {
          details.removeAttribute('open');
        }
      }
    });
  }

  function initializeTemplatePreviews() {
    document.querySelectorAll('.ux-toolkit-ticket-template-insert select').forEach(function(select) {
      if (select.getAttribute('data-ux-toolkit-preview-initialized') === '1') {
        return;
      }

      var container = select.closest('.ux-toolkit-ticket-template-insert');
      var preview = container && container.querySelector('[data-ux-toolkit-ticket-template-preview]');
      if (!preview) {
        return;
      }

      var update = function() {
        var option = selectedTemplateOption(select);
        var subject = option && option.getAttribute('data-subject-template') || '';
        var description = option && option.getAttribute('data-template-text') || '';
        var hasTemplate = !!(option && option.value);
        preview.querySelector('[data-template-preview-empty]').hidden = hasTemplate;
        preview.querySelector('[data-template-preview-content]').hidden = !hasTemplate;
        preview.querySelector('[data-template-preview-subject]').textContent = subject;
        preview.querySelector('[data-template-preview-description]').textContent = description;
      };
      select.setAttribute('data-ux-toolkit-preview-initialized', '1');
      select.addEventListener('change', update);
      update();
    });

    document.querySelectorAll('.ux-toolkit-checklist-template-insert select').forEach(function(select) {
      if (select.getAttribute('data-ux-toolkit-preview-initialized') === '1') {
        return;
      }

      var preview = select.closest('form').querySelector('[data-ux-toolkit-checklist-template-preview]');
      var list = preview && preview.querySelector('ol');
      if (!preview || !list) {
        return;
      }

      var update = function() {
        var option = selectedTemplateOption(select);
        var items = [];
        try {
          items = JSON.parse(option && option.getAttribute('data-template-items') || '[]');
        } catch (_error) {
          items = [];
        }
        list.innerHTML = '';
        items.forEach(function(subject) {
          var item = document.createElement('li');
          item.textContent = subject;
          list.appendChild(item);
        });
        preview.hidden = items.length === 0;
      };
      select.setAttribute('data-ux-toolkit-preview-initialized', '1');
      select.addEventListener('change', update);
      update();
    });
  }

  document.addEventListener('click', function(event) {
    var button = event.target.closest('.ux-toolkit-ticket-template-insert-button');
    if (!button) {
      return;
    }

    event.preventDefault();

    var container = ticketTemplateContainer(button);
    var select = container && container.querySelector('select');
    var textarea = descriptionField();
    var selectedOption = selectedTemplateOption(select);

    if (!selectedOption || !selectedOption.value) {
      window.alert(container.getAttribute('data-empty-template-message'));
      return;
    }

    var templateText = selectedOption.getAttribute('data-template-text') || '';
    if (!templateText) {
      window.alert(container.getAttribute('data-empty-template-description-message'));
      return;
    }

    if (textarea && insertText(textarea, templateText, container.getAttribute('data-append-confirmation'))) {
      textarea.focus();
    }
  });

  document.addEventListener('click', function(event) {
    var button = event.target.closest('.ux-toolkit-text-snippet-insert-button');
    if (!button) {
      return;
    }

    event.preventDefault();

    var container = button.closest('.ux-toolkit-text-snippet-insert');
    var select = container && container.querySelector('select');
    var selectedOption = selectedTemplateOption(select);
    var textarea = document.getElementById('issue_notes');

    if (!selectedOption || !selectedOption.value) {
      window.alert(container.getAttribute('data-empty-snippet-message'));
      return;
    }

    if (textarea) {
      appendText(textarea, selectedOption.getAttribute('data-snippet-text') || '');
      textarea.focus();
    }
  });

  document.addEventListener('input', function(event) {
    if (event.target && event.target.closest('#issue-form')) {
      updateIssueQualityCheck();
    }
  });

  document.addEventListener('change', function(event) {
    if (event.target && event.target.closest('#issue-form')) {
      updateIssueQualityCheck();
    }
  });

  document.addEventListener('DOMContentLoaded', function() {
    updateIssueQualityCheck();
    initializeSettingsUsability();
    initializeDashboard();
    initializeChecklistControls();
    initializeTemplatePreviews();
  });

  if (window.jQuery) {
    window.jQuery(document).ajaxComplete(function() {
      updateIssueQualityCheck();
      initializeTemplatePreviews();
    });
  }
}());
