import { InspectorControls, PanelColorSettings, useBlockProps } from '@wordpress/block-editor';
import {
  Disabled,
  __experimentalToolsPanel as ToolsPanel,
  __experimentalToolsPanelItem as ToolsPanelItem,
  __experimentalToggleGroupControl as ToggleGroupControl,
  __experimentalToggleGroupControlOption as ToggleGroupControlOption,
} from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { useSelect, useDispatch } from '@wordpress/data';
import { useEffect, useRef } from '@wordpress/element';
import ServerSideRender from '@wordpress/server-side-render';

export default function Edit({ attributes, setAttributes, clientId }) {
  const blockProps = useBlockProps({ className: 'mepr-rl-account-menu' });

  const {
    layout,
    menuBackgroundColor,
    buttonBackgroundColor,
    buttonHoverBgColor,
    buttonTextColor,
    buttonHoverTextColor,
  } = attributes;

  const parentClientId = useSelect((select) => {
    const parents = select('core/block-editor').getBlockParents(clientId);
    return parents.length ? parents[parents.length - 1] : null;
  }, [clientId]);

  const { updateBlockAttributes } = useDispatch('core/block-editor');
  const navContainerRef = useRef(null);

  const onLayoutChange = (value) => {
    setAttributes({ layout: value });
    if (parentClientId) {
      updateBlockAttributes(parentClientId, { layout: value });
    }
  };

  // CSS custom properties declared on #mepr-account-nav in the stylesheet
  // always beat inherited values from a parent div — so we must set them
  // directly on the element. A MutationObserver re-applies after every SSR
  // re-render (e.g. layout changes) so the chosen colors are never lost.
  useEffect(() => {
    const container = navContainerRef.current;
    if (!container) return;

    const applyColorVars = () => {
      const nav = container.querySelector('#mepr-account-nav');
      if (!nav) return;
      // Each color is mirrored to the canonical shell variable (consumed by
      // shell.css) and the Account-specific variable (kept as a customizer
      // hook scoped to `.mepr-rl-account`).
      const colorMap = {
        menuBg: {
          value: menuBackgroundColor,
          vars: ['--mepr-rl-shell-menu-bg', '--mepr-account-menu-bg'],
        },
        buttonBg: {
          value: buttonBackgroundColor,
          vars: ['--mepr-rl-shell-button-bg', '--mepr-account-button-bg'],
        },
        buttonHoverBg: {
          value: buttonHoverBgColor,
          vars: ['--mepr-rl-shell-button-hover-bg', '--mepr-account-button-hover-bg'],
        },
        buttonText: {
          value: buttonTextColor,
          vars: ['--mepr-rl-shell-button-text', '--mepr-account-button-text'],
        },
        buttonHoverText: {
          value: buttonHoverTextColor,
          vars: ['--mepr-rl-shell-button-hover-text', '--mepr-account-button-hover-text'],
        },
      };
      Object.values(colorMap).forEach(({ value, vars }) => {
        vars.forEach((prop) => {
          if (value) {
            nav.style.setProperty(prop, value);
          } else {
            nav.style.removeProperty(prop);
          }
        });
      });

      // Paint the background directly on the nav so account.css's hardcoded #mepr-account-nav blue can't win in the SSR preview (which lacks the .mepr-rl-account ancestor the var rules need).
      if (menuBackgroundColor) {
        nav.style.background = menuBackgroundColor;
      } else {
        nav.style.removeProperty('background');
      }

      // Vertical: the wrapper is the full-height sidebar column, so extend the colour to it; horizontal: the wrapper spans below the bar, so only the nav carries the colour.
      const wrapper = container.closest('.mepr-rl-account-menu');
      if (wrapper) {
        if (menuBackgroundColor && layout === 'vertical') {
          wrapper.style.background = menuBackgroundColor;
        } else {
          wrapper.style.removeProperty('background');
        }
      }
    };

    applyColorVars();

    const observer = new MutationObserver(applyColorVars);
    observer.observe(container, { childList: true, subtree: true });

    return () => observer.disconnect();
  }, [layout, menuBackgroundColor, buttonBackgroundColor, buttonHoverBgColor, buttonTextColor, buttonHoverTextColor]);

  // Pass only layout to SSR — structure needs PHP, colors are applied client-side above.
  const ssrAttributes = {
    layout,
    menuBackgroundColor: '',
    buttonBackgroundColor: '',
    buttonHoverBgColor: '',
    buttonTextColor: '',
    buttonHoverTextColor: '',
  };

  return (
    <div {...blockProps}>
      <InspectorControls>
        <ToolsPanel
          label={__('Layout', 'memberpress')}
          resetAll={() => onLayoutChange('vertical')}
        >
          <ToolsPanelItem
            label={__('Layout', 'memberpress')}
            hasValue={() => layout !== 'vertical'}
            onDeselect={() => onLayoutChange('vertical')}
            isShownByDefault
          >
            <ToggleGroupControl
              label={__('Layout', 'memberpress')}
              value={layout}
              onChange={onLayoutChange}
              isBlock
              __nextHasNoMarginBottom
              hideLabelFromVision
            >
              <ToggleGroupControlOption
                value="vertical"
                label={__('Vertical', 'memberpress')}
              />
              <ToggleGroupControlOption
                value="horizontal"
                label={__('Horizontal', 'memberpress')}
              />
            </ToggleGroupControl>
          </ToolsPanelItem>
        </ToolsPanel>
        <PanelColorSettings
          title={__('Colors', 'memberpress')}
          initialOpen={true}
          colorSettings={[
            {
              value: menuBackgroundColor,
              onChange: (value) => setAttributes({ menuBackgroundColor: value }),
              label: __('Menu Background', 'memberpress'),
            },
            {
              value: buttonBackgroundColor,
              onChange: (value) => setAttributes({ buttonBackgroundColor: value }),
              label: __('Active Background', 'memberpress'),
            },
            {
              value: buttonHoverBgColor,
              onChange: (value) => setAttributes({ buttonHoverBgColor: value }),
              label: __('Hover Background', 'memberpress'),
            },
            {
              value: buttonTextColor,
              onChange: (value) => setAttributes({ buttonTextColor: value }),
              label: __('Text', 'memberpress'),
            },
            {
              value: buttonHoverTextColor,
              onChange: (value) => setAttributes({ buttonHoverTextColor: value }),
              label: __('Hover Text', 'memberpress'),
            },
          ]}
        />
      </InspectorControls>

      <Disabled>
        <div ref={navContainerRef}>
          <ServerSideRender
            block="memberpress/readylaunch-account-menu"
            attributes={ssrAttributes}
          />
        </div>
      </Disabled>
    </div>
  );
}
