<template>
  <div class="dest-mass-quantity-container"
       :class="{ 'has-selection': hasSelection, 'apply-filter': applyFilter, 'add-all': addAll }">
    <div class="dest-mass-quantity-table-wrapper">
      <div class="dest-mass-quantity-table-header">
        <div class="dest-mass-quantity-table-header-checkbox">
          <checkbox @checkbox-changed="updateCheckBoxes" :checked="overallCheck"
                    :indeterminate="overallIndeterminate"></checkbox>
        </div>
        <div class="dest-mass-quantity-table-header-material">Material</div>
        <div class="dest-mass-quantity-table-header-supplier">Supplier</div>
        <div class="dest-mass-quantity-table-header-applier">
          <icon-button icon="check" :disabled="!someChecked" @click="updateOverallValue"></icon-button>
          <icon-button icon="x" :disabled="!someChecked" @click="dismissChecked"></icon-button>
        </div>
        <div class="dest-mass-quantity-table-header-dest"
             :key="`${dest.id}`"
             v-for="dest in destPool">
          <div>{{ toNode(dest, 6) }}</div>
          <div class="text-container" :class="{disabled: !someChecked}">
            <input class="input-field"
                   v-model="dest.overallValue"
                   autocomplete="off"
                   @blur="validateAnnualAmount($event, dest)"
                   :disabled="!someChecked"/>
          </div>
        </div>
      </div>
      <div class="dest-mass-quantity-table">
        <destination-mass-quantity-row @action="onClickAction" @update-selected="updateCheckBox" :row="row"
                                       :key="row.id"
                                       :disabled="someChecked"
                                       v-for="row in rows"></destination-mass-quantity-row>
      </div>
    </div>
  </div>
</template>

<script>

import {useDestinationEditStore} from "@/store/destinationEdit.js";
import {mapStores} from "pinia";
import Checkbox from "@/components/UI/Checkbox.vue";
import DestMassCreateRow from "@/components/layout/edit/destination/mass/DestMassCreateRow.vue";
import DestinationMassQuantityRow from "@/components/layout/edit/destination/mass/DestinationMassQuantityRow.vue";
import {usePremiseEditStore} from "@/store/premiseEdit.js";
import BulkEditRow from "@/components/layout/bulkedit/BulkEditRow.vue";
import {toRaw} from "vue";
import IconButton from "@/components/UI/IconButton.vue";
import BasicButton from "@/components/UI/BasicButton.vue";
import {parseNumberFromString} from "@/common.js";

export default {
  name: "DestinationMassQuantity",
  components: {BasicButton, IconButton, BulkEditRow, DestinationMassQuantityRow, DestMassCreateRow, Checkbox},
  props: {
    premiseIds: {
      type: Array,
      required: true
    },
    onLoadingChange: {
      type: Function,
      default: () => {
      }
    }
  },
  data() {
    return {

      destPool: null,
      overallCheck: false,
      overallIndeterminate: false,
      isCtrlPressed: false,
      isShiftPressed: false,
    }
  },
  computed: {
    ...mapStores(useDestinationEditStore, usePremiseEditStore),
    rows() {
      return this.destinationEditStore.getQuantityMatrix ?? [];
    },
    allChecked() {
      return this.rows.every(r => r.selected);
    },
    someChecked() {
      return this.rows.some(r => r.selected);
    },
    hasSelection() {
      return !this.addAll && !this.applyFilter && this.someChecked;
    },
    applyFilter() {
      return this.isCtrlPressed && this.isShiftPressed;
    },
    addAll() {
      return this.isCtrlPressed && !this.isShiftPressed;
    },
  },
  async created() {
    this.onLoadingChange(true);
    try {
      await new Promise(resolve => setTimeout(() => {
        this.buildMatrix();
        resolve();
      }, 10));
    } finally {
      this.onLoadingChange(false);
    }
  },
  mounted() {
    window.addEventListener('keydown', this.handleKeyDown);
    window.addEventListener('keyup', this.handleKeyUp);
  },
  beforeUnmount() {
    window.removeEventListener('keydown', this.handleKeyDown);
    window.removeEventListener('keyup', this.handleKeyUp);
  },
  methods: {
    /* key down/up handler */
    handleKeyDown(event) {
      if (event.key === 'Control') {
        this.isCtrlPressed = true;
      } else if (event.key === 'Shift') {
        this.isShiftPressed = true;
      }

      if (event.key === 'Escape') {
        this.fillData(this.modalType);
        this.modalType = null;
      }

    },
    handleKeyUp(event) {
      if (event.key === 'Control') {
        this.isCtrlPressed = false;
      } else if (event.key === 'Shift') {
        this.isShiftPressed = false;
      }
    },
    onClickAction(data) {

      this.rows.forEach(d => {
        d.selected = ((data.column === 'material' && d.material === data.row.material)
            || (data.column === 'supplier' && d.supplier === data.row.supplier)
            || (data.action === 'append' && d.selected));
      });

      this.updateOverallCheckBox();
    },
    validateAnnualAmount(event, dest) {
      const value = event.target.value == null ? null : parseNumberFromString(event.target.value, 0);
      const validatedValue = value == null ? null : Math.max(0, value);
      const stringified = validatedValue === null ? '' : validatedValue.toFixed();

      dest.overallValue = validatedValue;
      event.target.value = stringified;
    },
    updateOverallValue() {

      const updates = this.destPool
          .filter(d => d.overallValue !== null && d.overallValue !== '')
          .map(d => ({
            nodeId: d.id,
            value: d.overallValue
          }));

      if (updates.length > 0) {
        this.rows
            .filter(row => row.selected)
            .forEach(row => {
              updates.forEach(update => {
                const d = row.destinations.find(rd => rd.nodeId === update.nodeId);
                if (d && d.id !== null) {
                  d.annual_amount = update.value;
                }
              });
            });

        this.destPool.forEach(d => d.overallValue = null);

        this.$forceUpdate();
      }

      this.dismissChecked();
    },
    dismissChecked() {
      this.rows.forEach(row => row.selected = false);
      this.updateOverallCheckBox();
    },

    /* checkbox handling */

    updateCheckBox(data) { // data = {id: this.row.id, selected: value}
      // update global (rest is done in row)
      this.updateOverallCheckBox();
    },
    updateCheckBoxes(value) {
      this.rows?.forEach(r => r.selected = value);
      this.updateOverallCheckBox();
    },
    updateOverallCheckBox() {
      this.overallCheck = this.rows.every(r => r.selected);

      if (!this.overallCheck)
        this.overallIndeterminate = this.rows.some(r => r.selected);
    },
    toNode(node, limit = 5) {
      if (!node)
        return 'N/A';

      const name = node.name;
      const mappingId = node.external_mapping_id;
      const needsShortName = name.length > limit;
      const useMappingId = ((mappingId ?? null) !== null) && ((name ?? null) === null || needsShortName);
      const shortName = name?.substring(0, limit).concat("...") ?? 'N/A';
      return `${useMappingId ? mappingId.replace("_", " ") : (needsShortName ? shortName : name)}`;

    },
    async buildMatrix() {
      // destPool aufbauen
      const destMap = new Map();

      for (const pId of this.premiseIds) {
        const destinations = this.destinationEditStore.getByPremiseId(pId);
        if (!destinations) continue;

        for (const d of destinations) {
          const destId = d.destination_node.id;
          if (!destMap.has(destId)) {
            destMap.set(destId, {
              ...d.destination_node,
              overallValue: null,
              overallCheck: false,
              overallIndeterminate: false
            });
          }
        }
      }

      this.destPool = Array.from(destMap.values());


      const quantityMatrix = this.premiseIds
          .filter(p => p)
          .map(p => this.premiseEditStore.getById(p))
          .map(premise => {
            const destRaw = this.destinationEditStore.getByPremiseId(premise.id);

            // Map für schnelleren Lookup erstellen
            const destLookup = new Map();
            if (destRaw) {
              for (const dr of destRaw) {
                destLookup.set(dr.destination_node.id, dr);
              }
            }

            return {
              id: premise.id,
              material: premise.material.part_number,
              supplier: this.toNode(premise.supplier, 30),
              destinations: this.destPool.map(dest => {
                const match = destLookup.get(dest.id);
                return {
                  annual_amount: match?.annual_amount ?? null,
                  id: match?.id ?? null,
                  nodeId: dest.id,
                };
              }),
              selected: false
            };
          });

      this.destinationEditStore.setQuantityMatrix(quantityMatrix);
      await this.$nextTick();
    }
  }
}
</script>


<style scoped>


/* Global style für copy-mode cursor */
.dest-mass-quantity-container.has-selection :deep(.dest-mass-quantity-row__cell--copyable:hover) {
  cursor: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDEyOC41MSAxMzQuMDUiPjxkZWZzPjxzdHlsZT4uY3tmaWxsOm5vbmU7fS5jLC5ke3N0cm9rZTojMDEwMTAxO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2Utd2lkdGg6NXB4O30uZHtmaWxsOiNmZmY7fTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJhIj48cGF0aCBjbGFzcz0iYyIgZD0ibTU0Ljg5LDExMi41MWgtMi4yNGMtMS4yNCwwLTIuMjQtMS0yLjI0LTIuMjR2LTIuMjQiLz48bGluZSBjbGFzcz0iYyIgeDE9IjcwLjU3IiB5MT0iNzYuNjciIHgyPSI2My44NSIgeTI9Ijc2LjY3Ii8+PGxpbmUgY2xhc3M9ImMiIHgxPSI3MC41NyIgeTE9IjExMi41MSIgeDI9IjY2LjA5IiB5Mj0iMTEyLjUxIi8+PGxpbmUgY2xhc3M9ImMiIHgxPSI4Ni4yNSIgeTE9Ijk5LjA3IiB4Mj0iODYuMjUiIHkyPSI5Mi4zNSIvPjxsaW5lIGNsYXNzPSJjIiB4MT0iNTAuNDEiIHkxPSI5Ni44MyIgeDI9IjUwLjQxIiB5Mj0iOTIuMzUiLz48cGF0aCBjbGFzcz0iYyIgZD0ibTgxLjc3LDExMi41MWgyLjI0YzEuMjQsMCwyLjI0LTEsMi4yNC0yLjI0di0yLjI0Ii8+PHBhdGggY2xhc3M9ImMiIGQ9Im04MS43Nyw3Ni42N2gyLjI0YzEuMjQsMCwyLjI0LDEsMi4yNCwyLjI0djIuMjQiLz48cGF0aCBjbGFzcz0iYyIgZD0ibTU0Ljg5LDc2LjY3aC0yLjI0Yy0xLjI0LDAtMi4yNCwxLTIuMjQsMi4yNHYyLjI0Ii8+PHBhdGggY2xhc3M9ImMiIGQ9Im04Ni4yNSw5OS4wN2gxMS4yYzEuMjQsMCwyLjI0LTEsMi4yNC0yLjI0di0zMS4zNmMwLTEuMjQtMS0yLjI0LTIuMjQtMi4yNGgtMzEuMzZjLTEuMjQsMC0yLjI0LDEtMi4yNCwyLjI0djExLjIiLz48L2c+PGcgaWQ9ImIiPjxwYXRoIGNsYXNzPSJkIiBkPSJtNDQuMDgsNDQuMDdsMzIuOTQtOS4yYzEuNjktLjUyLDIuNjQtMi4zMSwyLjEyLTQtLjMtLjk4LTEuMDUtMS43NS0yLjAxLTIuMDlMNi43MywyLjY3Yy0xLjY3LS41Ny0zLjQ5LjMzLTQuMDYsMi0uMjMuNjYtLjIzLDEuMzgsMCwyLjA1bDI2LjExLDcwLjRjLjU4LDEuNjcsMi40LDIuNTYsNC4wNywxLjk4Ljk3LS4zMywxLjcxLTEuMTEsMi4wMS0yLjA5bDkuMjItMzIuOTRaIi8+PC9nPjwvc3ZnPg==") 12 12, pointer;
  background-color: #f8fafc;
  border-radius: 0.8rem;
}

/* Global style für filter-mode cursor */
.dest-mass-quantity-container.add-all :deep(.dest-mass-quantity-row__cell--filterable:hover) {
  cursor: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDEyOC41MSAxMzQuMDUiPjxkZWZzPjxzdHlsZT4uY3tmaWxsOm5vbmU7fS5jLC5ke3N0cm9rZTojMDEwMTAxO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2Utd2lkdGg6NXB4O30uZHtmaWxsOiNmZmY7fTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJhIj48bGluZSBjbGFzcz0iYyIgeDE9IjczLjAzIiB5MT0iNzUuNTUiIHgyPSI2Ni4zOCIgeTI9Ijc1LjU1Ii8+PGxpbmUgY2xhc3M9ImMiIHgxPSI2Ni4zOCIgeTE9IjExMi4xNiIgeDI9IjczLjAzIiB5Mj0iMTEyLjE2Ii8+PHBhdGggY2xhc3M9ImMiIGQ9Im04MS4zNSw3NS41NWg0Ljk5Yy45MiwwLDEuNjYuNzUsMS42NiwxLjY2djQuOTkiLz48bGluZSBjbGFzcz0iYyIgeDE9Ijg4LjAxIiB5MT0iOTcuMTgiIHgyPSI4OC4wMSIgeTI9IjkwLjUzIi8+PHBhdGggY2xhc3M9ImMiIGQ9Im04MS4zNSwxMTIuMTZoNC45OWMuOTIsMCwxLjY2LS43NSwxLjY2LTEuNjZ2LTQuOTkiLz48bGluZSBjbGFzcz0iYyIgeDE9IjUxLjQiIHkxPSI5MC41MyIgeDI9IjUxLjQiIHkyPSI5Ny4xOCIvPjxwYXRoIGNsYXNzPSJjIiBkPSJtNTguMDUsMTEyLjE2aC00Ljk5Yy0uOTIsMC0xLjY2LS43NS0xLjY2LTEuNjZ2LTQuOTkiLz48cGF0aCBjbGFzcz0iYyIgZD0ibTU4LjA1LDc1LjU1aC00Ljk5Yy0uOTIsMC0xLjY2Ljc1LTEuNjYsMS42NnY0Ljk5Ii8+PC9nPjxnIGlkPSJiIj48cGF0aCBjbGFzcz0iZCIgZD0ibTQ0LjA4LDQ0LjA3bDMyLjk0LTkuMmMxLjY5LS41MiwyLjY0LTIuMzEsMi4xMi00LS4zLS45OC0xLjA1LTEuNzUtMi4wMS0yLjA5TDYuNzMsMi42N2MtMS42Ny0uNTctMy40OS4zMy00LjA2LDItLjIzLjY2LS4yMywxLjM4LDAsMi4wNWwyNi4xMSw3MC40Yy41OCwxLjY3LDIuNCwyLjU2LDQuMDcsMS45OC45Ny0uMzMsMS43MS0xLjExLDIuMDEtMi4wOWw5LjIyLTMyLjk0WiIvPjwvZz48L3N2Zz4=") 12 12, pointer;
  background-color: #f8fafc;
  border-radius: 0.8rem;
}

/* Global style für filter-mode cursor */
.dest-mass-quantity-container.apply-filter :deep(.dest-mass-quantity-row__cell--filterable:hover) {
  cursor: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDEyOC41MSAxMzQuMDUiPjxkZWZzPjxzdHlsZT4uZHtzdHJva2U6IzAwMDt9LmQsLmV7ZmlsbDpub25lO30uZCwuZSwuZntzdHJva2UtbGluZWNhcDpyb3VuZDtzdHJva2UtbGluZWpvaW46cm91bmQ7c3Ryb2tlLXdpZHRoOjVweDt9LmUsLmZ7c3Ryb2tlOiMwMTAxMDE7fS5me2ZpbGw6I2ZmZjt9PC9zdHlsZT48L2RlZnM+PGcgaWQ9ImEiPjxsaW5lIGNsYXNzPSJlIiB4MT0iNzMuMDMiIHkxPSI3NS41NSIgeDI9IjY2LjM4IiB5Mj0iNzUuNTUiLz48bGluZSBjbGFzcz0iZSIgeDE9IjY2LjM4IiB5MT0iMTEyLjE2IiB4Mj0iNzMuMDMiIHkyPSIxMTIuMTYiLz48cGF0aCBjbGFzcz0iZSIgZD0ibTgxLjM1LDc1LjU1aDQuOTljLjkyLDAsMS42Ni43NSwxLjY2LDEuNjZ2NC45OSIvPjxsaW5lIGNsYXNzPSJlIiB4MT0iODguMDEiIHkxPSI5Ny4xOCIgeDI9Ijg4LjAxIiB5Mj0iOTAuNTMiLz48cGF0aCBjbGFzcz0iZSIgZD0ibTgxLjM1LDExMi4xNmg0Ljk5Yy45MiwwLDEuNjYtLjc1LDEuNjYtMS42NnYtNC45OSIvPjxsaW5lIGNsYXNzPSJlIiB4MT0iNTEuNCIgeTE9IjkwLjUzIiB4Mj0iNTEuNCIgeTI9Ijk3LjE4Ii8+PHBhdGggY2xhc3M9ImUiIGQ9Im01OC4wNSwxMTIuMTZoLTQuOTljLS45MiwwLTEuNjYtLjc1LTEuNjYtMS42NnYtNC45OSIvPjxwYXRoIGNsYXNzPSJlIiBkPSJtNTguMDUsNzUuNTVoLTQuOTljLS45MiwwLTEuNjYuNzUtMS42NiwxLjY2djQuOTkiLz48L2c+PGcgaWQ9ImIiPjxwYXRoIGNsYXNzPSJmIiBkPSJtNDQuMDgsNDQuMDdsMzIuOTQtOS4yYzEuNjktLjUyLDIuNjQtMi4zMSwyLjEyLTQtLjMtLjk4LTEuMDUtMS43NS0yLjAxLTIuMDlMNi43MywyLjY3Yy0xLjY3LS41Ny0zLjQ5LjMzLTQuMDYsMi0uMjMuNjYtLjIzLDEuMzgsMCwyLjA1bDI2LjExLDcwLjRjLjU4LDEuNjcsMi40LDIuNTYsNC4wNywxLjk4Ljk3LS4zMywxLjcxLTEuMTEsMi4wMS0yLjA5bDkuMjItMzIuOTRaIi8+PC9nPjxnIGlkPSJjIj48bGluZSBjbGFzcz0iZCIgeDE9Ijk5LjM4IiB5MT0iOTQuMTkiIHgyPSIxMjYuMDEiIHkyPSI5NC4xOSIvPjxsaW5lIGNsYXNzPSJkIiB4MT0iMTEyLjY5IiB5MT0iODAuODciIHgyPSIxMTIuNjkiIHkyPSIxMDcuNTEiLz48L2c+PC9zdmc+") 12 12, pointer;
  background-color: #f8fafc;
  border-radius: 0.8rem;
}

.text-container.disabled {
  background-color: #f3f4f6;
  cursor: not-allowed;
  border-color: #f3f4f6;
}

.text-container.disabled input {
  cursor: not-allowed;
}


.text-container:hover:not(.disabled) {
  background: #EEF4FF;
  border: 0.2rem solid #8DB3FE;
  transform: scale(1.01);

}


.input-field {
  border: none;
  outline: none;
  background: none;
  resize: none;
  font-family: inherit;
  font-size: 1.4rem;
  color: #002F54;

  max-width: 6rem;
}

.text-container {
  display: flex;
  align-items: center;
  background: white;
  border-radius: 0.4rem;
  padding: 0.6rem 1.2rem;
  /* box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);*/
  border: 0.2rem solid #E3EDFF;
  transition: all 0.1s ease;
  flex: 1 0 auto;

  max-width: 8rem;

}

.dest-mass-quantity-container {
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 0;
  overflow: hidden;
}

.dest-mass-quantity-table-wrapper {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  flex: 1;
  min-height: 0;
}

.dest-mass-quantity-table-header {
  display: flex;
  flex-direction: row;
  gap: 1.6rem;
  padding: 1.6rem 2.4rem;
  justify-content: flex-start;

  background-color: #ffffff;
  border-bottom: 1px solid rgba(107, 134, 156, 0.2);
  font-weight: 500;
  font-size: 1.4rem;
  color: #6B869C;
  text-transform: uppercase;
  letter-spacing: 0.08rem;

  flex-shrink: 0;
}

.dest-mass-quantity-table {
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
  min-height: 0;
  margin: 0;
  padding-bottom: 2.4rem;
}

.dest-mass-quantity-table-header-checkbox {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 6rem;
}


.dest-mass-quantity-table-header-material {
  width: 14rem;
  display: flex;
  align-items: center;
}

.dest-mass-quantity-table-header-supplier {
  width: 24rem;
  display: flex;
  align-items: center;
}

.dest-mass-quantity-table-header-applier {
  display: flex;
  align-items: center;
  width: 7rem;
  gap: 0.8rem;
}

.dest-mass-quantity-table-header-dest {
  display: flex;
  justify-content: flex-start;
  align-items: center;
  width: 15rem;
  gap: 0.8rem;
}

</style>