const STORAGE_KEY = 'plyr_captions_size';
const DEFAULT_SIZE = 'normal';
const SIZE_OPTIONS = [
  { value: 'small', label: 'Pequeno', fontSize: '0.88rem' },
  { value: 'normal', label: 'Normal', fontSize: '1.02rem' },
  { value: 'large', label: 'Grande', fontSize: '1.18rem' },
  { value: 'xlarge', label: 'Muy grande', fontSize: '1.32rem' }
];

const getStoredCaptionSize = () => {
  try {
    const value = window.localStorage.getItem(STORAGE_KEY);
    return SIZE_OPTIONS.some(option => option.value === value) ? value : DEFAULT_SIZE;
  } catch (error) {
    return DEFAULT_SIZE;
  }
};

const saveCaptionSize = value => {
  try {
    window.localStorage.setItem(STORAGE_KEY, value);
  } catch (error) {
    // Ignore storage failures silently
  }
};

const getOptionByValue = value => SIZE_OPTIONS.find(option => option.value === value) || SIZE_OPTIONS[1];

const applyCaptionSize = (player, value) => {
  if (!player?.elements?.container) return getOptionByValue(DEFAULT_SIZE);

  const option = getOptionByValue(value);
  player.elements.container.style.setProperty('--plyr-captions-font-size', option.fontSize);
  player.elements.container.dataset.plyrCaptionsSize = option.value;
  saveCaptionSize(option.value);

  return option;
};

const createElement = (tag, attributes = {}, text = '') => {
  const element = document.createElement(tag);
  Object.entries(attributes).forEach(([key, value]) => {
    if (value === null || value === undefined || value === false) {
      return;
    }

    if (value === true) {
      element.setAttribute(key, '');
      return;
    }

    element.setAttribute(key, value);
  });

  if (text) {
    element.textContent = text;
  }

  return element;
};

const bindMenuItemShortcuts = menuItem => {
  menuItem.addEventListener('keydown', event => {
    const list = menuItem.parentElement;
    if (!list) return;

    const items = Array.from(list.querySelectorAll('[role="menuitemradio"]'));
    const currentIndex = items.indexOf(menuItem);
    if (currentIndex < 0) return;

    if (['ArrowDown', 'ArrowRight'].includes(event.key)) {
      event.preventDefault();
      items[(currentIndex + 1) % items.length]?.focus();
    }

    if (['ArrowUp', 'ArrowLeft'].includes(event.key)) {
      event.preventDefault();
      items[(currentIndex - 1 + items.length) % items.length]?.focus();
    }
  });
};

const updateMenuLabel = (menuButton, label) => {
  const valueNode = menuButton?.querySelector('.plyr__menu__value');
  if (valueNode) {
    valueNode.textContent = label;
  }
};

const setupCaptionSizePanel = player => {
  if (!player?.elements?.settings?.popup || !player.elements.settings.panels?.home) {
    return;
  }

  const popup = player.elements.settings.popup;
  const homePanel = player.elements.settings.panels.home;
  const homeMenu = homePanel.querySelector('[role="menu"]');
  const inner = popup.querySelector('div');
  const existingPanel = player.elements.container.querySelector(`#plyr-settings-${player.id}-caption-size`);

  if (!homeMenu || !inner || existingPanel) {
    return;
  }

  const currentOption = applyCaptionSize(player, getStoredCaptionSize());

  const menuButton = createElement('button', {
    type: 'button',
    class: 'plyr__control plyr__control--forward',
    role: 'menuitem',
    'aria-haspopup': 'true'
  });
  const menuLabel = createElement('span');
  menuLabel.appendChild(document.createTextNode('Tamano subtitulos'));
  const menuValue = createElement('span', { class: 'plyr__menu__value' }, currentOption.label);
  menuLabel.appendChild(menuValue);
  menuButton.appendChild(menuLabel);
  homeMenu.appendChild(menuButton);

  const panel = createElement('div', {
    id: `plyr-settings-${player.id}-caption-size`,
    hidden: true
  });

  const backButton = createElement('button', {
    type: 'button',
    class: 'plyr__control plyr__control--back'
  });
  backButton.appendChild(createElement('span', { 'aria-hidden': 'true' }, 'Tamano subtitulos'));
  backButton.appendChild(createElement('span', { class: 'plyr__sr-only' }, 'Go back to previous menu'));
  panel.appendChild(backButton);

  const list = createElement('div', { role: 'menu' });
  panel.appendChild(list);
  inner.appendChild(panel);

  const showHomePanel = focusFirst => {
    if (typeof player.elements.settings.popup.hidden !== 'undefined') {
      Array.from(inner.children).forEach(node => {
        node.hidden = node !== homePanel;
      });
    }

    if (focusFirst) {
      homeMenu.querySelector('button')?.focus();
    }
  };

  const showPanel = () => {
    Array.from(inner.children).forEach(node => {
      node.hidden = node !== panel;
    });
    list.querySelector('[aria-checked="true"]')?.focus();
  };

  menuButton.addEventListener('click', event => {
    event.preventDefault();
    event.stopPropagation();
    showPanel();
  });

  backButton.addEventListener('click', event => {
    event.preventDefault();
    event.stopPropagation();
    showHomePanel(true);
  });

  panel.addEventListener('keydown', event => {
    if (event.key !== 'ArrowLeft') return;
    event.preventDefault();
    event.stopPropagation();
    showHomePanel(true);
  });

  SIZE_OPTIONS.forEach(option => {
    const item = createElement('button', {
      type: 'button',
      role: 'menuitemradio',
      class: 'plyr__control',
      'aria-checked': option.value === currentOption.value ? 'true' : 'false',
      value: option.value
    });
    item.appendChild(createElement('span', {}, option.label));

    item.addEventListener('click', event => {
      event.preventDefault();
      event.stopPropagation();

      Array.from(list.querySelectorAll('[role="menuitemradio"]')).forEach(node => {
        node.setAttribute('aria-checked', 'false');
      });
      item.setAttribute('aria-checked', 'true');

      const selected = applyCaptionSize(player, option.value);
      updateMenuLabel(menuButton, selected.label);
      showHomePanel(false);
    });

    item.addEventListener('keyup', event => {
      if (event.key !== ' ') return;
      event.preventDefault();
      item.click();
    });

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

export const setupPlyrCaptionSizeMenu = player => {
  if (!player || typeof player !== 'object' || !player.elements?.container) {
    return;
  }

  applyCaptionSize(player, getStoredCaptionSize());

  if (player.elements?.settings?.popup) {
    setupCaptionSizePanel(player);
    return;
  }

  if (typeof player.once === 'function') {
    player.once('ready', () => {
      applyCaptionSize(player, getStoredCaptionSize());
      setupCaptionSizePanel(player);
    });
  }
};
