// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
{
  class nsZenWorkspaceCreation extends MozXULElement {
    #wasInCollapsedMode = false;

    promiseInitialized = new Promise((resolve) => {
      this.resolveInitialized = resolve;
    });

    #hiddenElements = [];

    static get elementsToDisable() {
      return [
        'cmd_zenOpenWorkspacePanel',
        'cmd_zenOpenWorkspaceCreation',
        'cmd_zenOpenFolderCreation',
        'cmd_zenToggleSidebar',
        'cmd_newNavigatorTab',
        'cmd_newNavigatorTabNoEvent',
      ];
    }

    static get markup() {
      return `
        <vbox class="zen-workspace-creation" flex="1">
          <form>
            <vbox>
              <html:h1 data-l10n-id="zen-workspace-creation-header" class="zen-workspace-creation-title" />
              <html:div>
                <label data-l10n-id="zen-workspace-creation-label" class="zen-workspace-creation-label" />
              </html:div>
            </vbox>
            <vbox class="zen-workspace-creation-form">
              <hbox class="zen-workspace-creation-name-wrapper">
                <toolbarbutton class="zen-workspace-creation-icon-label" />
                <html:input
                  class="zen-workspace-creation-name"
                  type="text"
                  data-l10n-id="zen-workspace-creation-name" />
              </hbox>
              <hbox class="zen-workspace-creation-profile-wrapper">
                <label class="zen-workspace-creation-profile-label" data-l10n-id="zen-workspace-creation-profile" />
                <button class="zen-workspace-creation-profile" />
              </hbox>
              <button
                class="zen-workspace-creation-edit-theme-button"
                data-l10n-id="zen-workspaces-change-theme"
                command="cmd_zenOpenZenThemePicker" />
              <menupopup class="zen-workspace-creation-profiles-popup" />
            </vbox>
            <vbox class="zen-workspace-creation-buttons">
              <html:div>
                <button class="zen-workspace-creation-create-button footer-button primary"
                  data-l10n-id="zen-panel-ui-workspaces-create" disabled="true" />
              </html:div>
              <button class="zen-workspace-creation-cancel-button footer-button"
                data-l10n-id="zen-general-cancel-label" />
            </vbox>
          </form>
        </vbox>
      `;
    }

    get workspaceId() {
      return this.getAttribute('workspace-id');
    }

    get previousWorkspaceId() {
      return this.getAttribute('previous-workspace-id');
    }

    get elementsToAnimate() {
      return [
        this.querySelector('.zen-workspace-creation-title'),
        this.querySelector('.zen-workspace-creation-label').parentElement,
        this.querySelector('.zen-workspace-creation-name-wrapper'),
        this.querySelector('.zen-workspace-creation-profile-wrapper'),
        this.querySelector('.zen-workspace-creation-edit-theme-button'),
        this.createButton.parentNode,
        this.cancelButton,
      ];
    }

    connectedCallback() {
      if (this.delayConnectedCallback()) {
        // If we are not ready yet, or if we have already connected, we
        // don't need to do anything.
        return;
      }

      this.appendChild(this.constructor.fragment);
      this.initializeAttributeInheritance();

      this.inputName = this.querySelector('.zen-workspace-creation-name');
      this.inputIcon = this.querySelector('.zen-workspace-creation-icon-label');
      this.inputProfile = this.querySelector('.zen-workspace-creation-profile');
      this.createButton = this.querySelector('.zen-workspace-creation-create-button');
      this.cancelButton = this.querySelector('.zen-workspace-creation-cancel-button');

      for (const element of this.elementsToAnimate) {
        element.style.opacity = 0;
      }

      this.#wasInCollapsedMode =
        document.documentElement.getAttribute('zen-sidebar-expanded') !== 'true';

      gNavToolbox.setAttribute('zen-sidebar-expanded', 'true');
      document.documentElement.setAttribute('zen-sidebar-expanded', 'true');

      window.docShell.treeOwner
        .QueryInterface(Ci.nsIInterfaceRequestor)
        .getInterface(Ci.nsIAppWindow)
        .rollupAllPopups();

      this.handleZenWorkspacesChangeBind = this.handleZenWorkspacesChange.bind(this);

      for (const element of this.parentElement.children) {
        if (element !== this) {
          element.hidden = true;
          this.#hiddenElements.push(element);
        }
      }

      for (const element of nsZenWorkspaceCreation.elementsToDisable) {
        const el = document.getElementById(element);
        if (el) {
          el.setAttribute('disabled', 'true');
        }
      }

      this.createButton.addEventListener('command', this.onCreateButtonCommand.bind(this));
      this.cancelButton.addEventListener('command', this.onCancelButtonCommand.bind(this));

      this.inputName.addEventListener('input', () => {
        this.createButton.disabled = !this.inputName.value.trim();
      });

      this.inputIcon.addEventListener('command', this.onIconCommand.bind(this));

      this.profilesPopup = this.querySelector('.zen-workspace-creation-profiles-popup');

      if (gZenWorkspaces.shouldShowContainers) {
        this.inputProfile.addEventListener('command', this.onProfileCommand.bind(this));
        this.profilesPopup.addEventListener('popupshown', this.onProfilePopupShown.bind(this));
        this.profilesPopup.addEventListener('command', this.onProfilePopupCommand.bind(this));

        this.currentProfile = {
          id: 0,
          name: 'Default',
        };
      } else {
        this.inputProfile.parentNode.hidden = true;
      }

      document.getElementById('zen-sidebar-splitter').style.pointerEvents = 'none';

      gZenUIManager.motion
        .animate(
          [gBrowser.tabContainer, gURLBar.textbox],
          {
            opacity: [1, 0],
          },
          {
            duration: 0.3,
            type: 'spring',
            bounce: 0,
          }
        )
        .then(() => {
          gBrowser.tabContainer.style.visibility = 'collapse';
          if (gZenVerticalTabsManager._hasSetSingleToolbar) {
            document.getElementById('nav-bar').style.visibility = 'collapse';
          }
          this.style.visibility = 'visible';
          gZenCompactModeManager.getAndApplySidebarWidth();
          this.resolveInitialized();
          gZenUIManager.motion
            .animate(
              this.elementsToAnimate,
              {
                y: [20, 0],
                opacity: [0, 1],
                filter: ['blur(2px)', 'blur(0)'],
              },
              {
                duration: 0.6,
                type: 'spring',
                bounce: 0,
                delay: gZenUIManager.motion.stagger(0.05, { startDelay: 0.2 }),
              }
            )
            .then(() => {
              this.inputName.focus();
              gZenWorkspaces.workspaceElement(this.workspaceId).hidden = false;
            });
        });
    }

    async onCreateButtonCommand() {
      const workspace = await gZenWorkspaces.getActiveWorkspace();
      workspace.name = this.inputName.value.trim();
      workspace.icon = this.inputIcon.image || this.inputIcon.label || undefined;
      workspace.containerTabId = this.currentProfile;
      await gZenWorkspaces.saveWorkspace(workspace);

      await this.#cleanup();

      await gZenWorkspaces._organizeWorkspaceStripLocations(workspace, true);
      await gZenWorkspaces.updateTabsContainers();

      gBrowser.tabContainer._invalidateCachedTabs();
    }

    async onCancelButtonCommand() {
      await gZenWorkspaces.changeWorkspaceWithID(this.previousWorkspaceId);
    }

    onIconCommand(event) {
      gZenEmojiPicker
        .open(event.target)
        .then(async (emoji) => {
          const isSvg = emoji && emoji.endsWith('.svg');
          if (isSvg) {
            this.inputIcon.label = '';
            this.inputIcon.image = emoji;
            this.inputIcon.setAttribute('has-svg-icon', 'true');
          } else {
            this.inputIcon.image = '';
            this.inputIcon.label = emoji || '';
            this.inputIcon.removeAttribute('has-svg-icon');
          }
        })
        .catch((error) => {
          console.warn('Error changing workspace icon:', error);
        });
    }

    set currentProfile(profile) {
      this.inputProfile.label = profile.name;
      this._profileId = profile.id;
    }

    get currentProfile() {
      return this._profileId;
    }

    onProfileCommand(event) {
      this.profilesPopup.openPopup(event.target, 'after_start');
    }

    onProfilePopupShown(event) {
      return window.createUserContextMenu(event, {
        isContextMenu: true,
        showDefaultTab: true,
      });
    }

    onProfilePopupCommand(event) {
      let userContextId = parseInt(event.target.getAttribute('data-usercontextid'));
      if (isNaN(userContextId)) {
        return;
      }
      this.currentProfile = {
        id: userContextId,
        name: event.target.label,
      };
    }

    finishSetup() {
      gZenWorkspaces.addChangeListeners(this.handleZenWorkspacesChangeBind, { once: true });
    }

    async handleZenWorkspacesChange() {
      await gZenWorkspaces.removeWorkspace(this.workspaceId);
      await this.#cleanup();
    }

    async #cleanup() {
      await gZenUIManager.motion.animate(
        this.elementsToAnimate.reverse(),
        {
          y: [0, 20],
          opacity: [1, 0],
          filter: ['blur(0)', 'blur(2px)'],
        },
        {
          duration: 0.4,
          type: 'spring',
          bounce: 0,
          delay: gZenUIManager.motion.stagger(0.05),
        }
      );

      document.getElementById('zen-sidebar-splitter').style.pointerEvents = '';

      gZenWorkspaces.removeChangeListeners(this.handleZenWorkspacesChangeBind);
      for (const element of this.constructor.elementsToDisable) {
        const el = document.getElementById(element);
        if (el) {
          el.removeAttribute('disabled');
        }
      }

      if (this.#wasInCollapsedMode) {
        gNavToolbox.removeAttribute('zen-sidebar-expanded');
        document.documentElement.removeAttribute('zen-sidebar-expanded');
      }

      document.documentElement.removeAttribute('zen-creating-workspace');

      gBrowser.tabContainer.style.visibility = '';
      gBrowser.tabContainer.style.opacity = 0;
      if (gZenVerticalTabsManager._hasSetSingleToolbar) {
        document.getElementById('nav-bar').style.visibility = '';
        gURLBar.textbox.style.opacity = 0;
      }

      this.remove();
      gZenUIManager.updateTabsToolbar();

      const workspace = await gZenWorkspaces.getActiveWorkspace();
      await gZenWorkspaces._organizeWorkspaceStripLocations(workspace, true);
      await gZenWorkspaces.updateTabsContainers();

      await gZenUIManager.motion.animate(
        [gBrowser.tabContainer, gURLBar.textbox],
        {
          opacity: [0, 1],
        },
        {
          duration: 0.3,
          type: 'spring',
          bounce: 0,
        }
      );

      gBrowser.tabContainer.style.opacity = '';
      if (gZenVerticalTabsManager._hasSetSingleToolbar) {
        gURLBar.textbox.style.opacity = '';
      }

      for (const element of this.#hiddenElements) {
        element.hidden = false;
      }

      this.#hiddenElements = [];
    }
  }

  customElements.define('zen-workspace-creation', nsZenWorkspaceCreation);
}
