import { html, nothing } from 'lit';
import { query, property } from 'lit/decorators.js';
import FlowRdfElement, { FlowRdfFormControl } from '../../internal/flow-ui-rdf-element.mjs';
import styles from './color-mapper.styles.mjs';
import { classMap } from 'lit/directives/class-map.js';
import { ifDefined } from 'lit/directives/if-defined.js';
import { boolean } from '../../internal/boolean.mjs';
import { HasSlotController } from '../../internal/slot.mjs';
import { throttle } from '../../internal/throttle.mjs';
import { watch } from '../../internal/watch.mjs';

var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __decorateClass = (decorators, target, key, kind) => {
  var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
  for (var i = decorators.length - 1, decorator; i >= 0; i--)
    if (decorator = decorators[i])
      result = (kind ? decorator(target, key, result) : decorator(result)) || result;
  if (kind && result)
    __defProp(target, key, result);
  return result;
};
class FlowUiColorMapper extends FlowRdfElement {
  constructor() {
    super(...arguments);
    this.hasSlotController = new HasSlotController(this, "info");
    this.value = {
      mode: "fixed",
      field: void 0,
      defaultColor: "gray",
      colorStops: []
    };
    this.size = "small";
    this.defaultColorStop = false;
    this.swatches = [
      "#d7191c",
      "#ffa500",
      "#ffe909",
      "#a6d96a",
      "#1a9641",
      "#3c58fd",
      "white",
      "black"
    ];
  }
  connectedCallback() {
    super.connectedCallback();
    this.classList.add(FlowRdfFormControl.FLOW_UI_FORM_CONTROL_CLASS);
    this.defaultColorStop = boolean(this.defaultColorStop, true);
  }
  handleClassChange() {
    this.classList.add(FlowRdfFormControl.FLOW_UI_FORM_CONTROL_CLASS);
  }
  handleFixedPickerClick(event) {
    event.stopPropagation();
  }
  handleChange(event) {
    const field = this.fieldSelect.value;
    if (this.currentField && this.currentField !== field) {
      this.value.colorStops.forEach((stop) => {
        stop.value = "";
      });
    }
    this.currentField = field;
    const colorStops = this.getAllColorStops();
    const colorStopPlaceholder = this.getColorStopPlaceholder();
    const stopValues = colorStops.map((colorStop) => colorStop.value);
    this.value = {
      mode: this.modeRadioGroup.value,
      field,
      type: field ? this.options.fields[field].type : void 0,
      defaultColor: this.fixedColorPicker.value,
      colorStops: stopValues
    };
    if (event.target === colorStopPlaceholder) {
      const lastStop = colorStops[colorStops.length - 1];
      this.value.colorStops.push({
        value: colorStopPlaceholder.value.value,
        color: lastStop?.value.color ?? "#ccc",
        options: lastStop?.value.options
      });
    }
    event.stopPropagation();
    event.preventDefault();
    this.emitChange();
  }
  emitChange() {
    this.emit("flow-ui-change");
  }
  handleColorStopRemove(event) {
    const stops = this.getAllColorStops();
    const colorStopElement = event.target;
    const colorStopIndex = stops.indexOf(colorStopElement);
    if (colorStopIndex >= 0) {
      this.value.colorStops.splice(colorStopIndex, 1);
      this.requestUpdate();
      this.emit("flow-ui-change");
    }
  }
  getAllColorStops() {
    return [...this.shadowRoot.querySelectorAll("flow-ui-color-stop:not([placeholder])")];
  }
  getColorStopPlaceholder() {
    return this.shadowRoot.querySelector("flow-ui-color-stop[placeholder]");
  }
  // Color mode radio button for 'fixed' mode with associated color picker
  fixedColorTemplate() {
    return html`
      Fixed Color:
      <flow-ui-color-picker
        class="color-mode-control"
        size=${this.size}
        id="fixed-color-picker"
        format="hex"
        placement="bottom-end"
        skidding="0"
        distance="4"
        opacity
        .swatches=${this.swatches}
        .value=${this.value.defaultColor}
        @click=${this.handleFixedPickerClick}
      ></flow-ui-color-picker>
    `;
  }
  // Color mode radio button for 'data-driven' mode with associated field selector
  dataDrivenColorTemplate() {
    return html`
      Color By:
      <flow-ui-select
        id="field-select"
        class="color-mode-control"
        value=${ifDefined(this.value.field)}
        size=${this.size}
        placeholder="Data Attribute"
        inline
      >
        ${Object.keys(this.options?.fields || {}).map(
      (field) => html`
            <flow-ui-option value="${field}">${this.options.fields[field].name ?? field}</flow-ui-option>
          `
    )}
      </flow-ui-select>
      ${this.hasSlotController.test("info") ? html`
            <flow-ui-icon-button
              library="system"
              name="info-circle"
              @click=${() => this.infoDialog.show()}
            ></flow-ui-icon-button>
          ` : nothing}
    `;
  }
  // Color stops for 'data-driven' mode
  colorStopsTemplate() {
    const fieldOptions = this.options.fields[this.value.field];
    if (!fieldOptions)
      return nothing;
    return html`
      <div
        part="color-stops"
        class=${classMap({
      "color-stops": true
    })}
        @flow-ui-remove=${this.handleColorStopRemove}
      >
        ${this.value.colorStops.map(
      (value) => html`
            <flow-ui-color-stop
              .options=${fieldOptions}
              .value=${value}
              size=${this.size}
              .swatches=${this.swatches}
            ></flow-ui-color-stop>
          `
    )}
        <flow-ui-color-stop
          class="color-stop-placeholder"
          placeholder
          .options=${fieldOptions}
          .value=${{ type: "string", value: "", color: "gray" }}
          size=${this.size}
        ></flow-ui-color-stop>
      </div>
    `;
  }
  infoDialogTemplate() {
    return html`
      <flow-ui-dialog heading="Color Mapping" class="dialog-info">
        <slot name="info"></slot>
        <flow-ui-button autofocus slot="footer" variant="primary" @click=${() => this.infoDialog.hide()}>
          OK
        </flow-ui-button>
      </flow-ui-dialog>
    `;
  }
  render() {
    return html`
      <div
        part="base"
        class=${classMap({
      "color-mapper": true,
      "color-mapper--small": this.size === "small",
      "color-mapper--medium": this.size === "medium",
      "color-mapper--large": this.size === "large",
      "color-mapper--fixed": this.value.mode === "fixed",
      "color-mapper--data-driven": this.value.mode === "data-driven"
    })}
        @flow-ui-change=${this.handleChange}
      >
        <div part="mode-selector">
          <flow-ui-radio-group
            id="mode-radio-group"
            class="color-mode-radio-group"
            size=${this.size}
            value=${this.value.mode}
          >
            <flow-ui-radio value="fixed" class="color-mode-radio">${this.fixedColorTemplate()}</flow-ui-radio>
            <flow-ui-radio value="data-driven" class="color-mode-radio">
              ${this.dataDrivenColorTemplate()}
            </flow-ui-radio>
          </flow-ui-radio-group>
        </div>

        ${this.colorStopsTemplate()} ${this.hasSlotController.test("info") ? this.infoDialogTemplate() : nothing}
      </div>
    `;
  }
}
FlowUiColorMapper.styles = styles;
__decorateClass([
  query("#mode-radio-group")
], FlowUiColorMapper.prototype, "modeRadioGroup", 2);
__decorateClass([
  query("#fixed-color-picker")
], FlowUiColorMapper.prototype, "fixedColorPicker", 2);
__decorateClass([
  query("#field-select")
], FlowUiColorMapper.prototype, "fieldSelect", 2);
__decorateClass([
  query(".dialog-info")
], FlowUiColorMapper.prototype, "infoDialog", 2);
__decorateClass([
  property({ reflect: true })
], FlowUiColorMapper.prototype, "class", 2);
__decorateClass([
  property({ type: Object })
], FlowUiColorMapper.prototype, "options", 2);
__decorateClass([
  property({ type: Object })
], FlowUiColorMapper.prototype, "value", 2);
__decorateClass([
  property()
], FlowUiColorMapper.prototype, "size", 2);
__decorateClass([
  property({ type: Boolean })
], FlowUiColorMapper.prototype, "defaultColorStop", 2);
__decorateClass([
  property()
], FlowUiColorMapper.prototype, "swatches", 2);
__decorateClass([
  watch("class")
], FlowUiColorMapper.prototype, "handleClassChange", 1);
__decorateClass([
  throttle(100)
], FlowUiColorMapper.prototype, "emitChange", 1);

export { FlowUiColorMapper as default };
