import { EnrichedTextClass } from '@descope-ui/descope-enriched-text/class';
import { injectStyle, observeChildren, syncAttrs } from '@descope-ui/common/components-helpers';
import { createStyleMixin, draggableMixin, componentNameValidationMixin } from '../../mixins';
import { compose } from '../../helpers';
import { forwardAttrs, getComponentName } from '../../helpers/componentHelpers';
import { createBaseClass } from '../../baseClasses/createBaseClass';

export const componentName = getComponentName('alert');

class RawAlert extends createBaseClass({ componentName, baseSelector: ':host > div' }) {
  constructor() {
    super();

    this.attachShadow({ mode: 'open' }).innerHTML = `
    <div>
      <div class="icon"></div>
      <div class="content">
        <descope-enriched-text>
          <slot></slot>
        </descope-enriched-text>
      </div>
    </div>
    `;

    injectStyle(
      `
      :host {
        display: inline-flex;
      }
      :host > div {
        display: flex;
        width: 100%;
      }
      :host([empty="true"]) {
        display: none;
      }
      .icon {
        flex-shrink: 0;
      }
      .content {
        display: flex;
        flex-wrap: wrap;
        white-space: normal;
        overflow-wrap: break-word;
      }
      `,
      this
    );
  }

  init() {
    super.init?.();

    this.slotEle = this.shadowRoot.querySelector('slot');
    this.textComp = this.shadowRoot.querySelector('descope-enriched-text');

    this.slotEle.addEventListener('slotchange', this.handleSlotChange.bind(this));

    syncAttrs(this.textComp, this, { includeAttrs: ['empty'] });

    observeChildren(this, this.handleChildrenChange.bind(this));

    forwardAttrs(this, this.textComp, {
      includeAttrs: ['variant', 'full-width', 'link-target-blank'],
    });
  }

  handleChildrenChange() {
    this.textComp.textContent = this.textContent;
  }

  handleSlotChange() {
    const assignedNodes = this.slotEle.assignedNodes({ flatten: true });
    if (!assignedNodes.length) return;
    this.textComp.textContent = assignedNodes[0]?.textContent || '';
  }
}

const { icon } = {
  icon: { selector: () => '.icon' },
};

export const AlertClass = compose(
  createStyleMixin({
    mappings: {
      hostWidth: { selector: () => ':host', property: 'width' },
      hostDirection: { selector: () => ':host', property: 'direction' },
      textColor: {
        selector: EnrichedTextClass.componentName,
        property: EnrichedTextClass.cssVarList.textColor,
      },
      backgroundColor: {},
      borderColor: {},
      borderWidth: {},
      borderStyle: {},
      borderRadius: {},
      fontSize: [
        {},
        {
          selector: EnrichedTextClass.componentName,
          property: EnrichedTextClass.cssVarList.fontSize,
        },
      ],
      gap: {},
      horizontalPadding: [{ property: 'padding-top' }, { property: 'padding-bottom' }],
      verticalPadding: [{ property: 'padding-right' }, { property: 'padding-left' }],
      alignItems: {},
      justifyContent: [
        {},
        {
          selector: EnrichedTextClass.componentName,
          property: EnrichedTextClass.cssVarList.textAlign,
        },
      ],
      icon: [
        { ...icon, property: 'content' },
        { ...icon, property: 'display', fallback: 'none' },
      ],
      iconSize: [
        { ...icon, property: 'width' },
        { ...icon, property: 'height' },
      ],
    },
  }),
  createStyleMixin({ componentNameOverride: getComponentName('enriched-text') }),
  createStyleMixin({ componentNameOverride: getComponentName('text') }),
  draggableMixin,
  componentNameValidationMixin
)(RawAlert);
