<template>
  <div class="edit-calculation-container" :class="{ 'has-selection': hasSelection }">
    <div class="header-container">
      <h2 class="page-header">Mass edit calculation</h2>
      <div class="header-controls">
        <basic-button :show-icon="false"
                      :disabled="premiseEditStore.selectedLoading"
                      variant="secondary"
                      @click="closeMassEdit"
        >Close
        </basic-button>
        <basic-button :show-icon="true"
                      :disabled="premiseEditStore.selectedLoading"
                      icon="Calculator" variant="primary"
                      @click="startCalculation"
        >Calculate & close
        </basic-button>

      </div>
    </div>

    <transition name="list-edit-container" tag="div">
      <transition-group name="list-edit" mode="out-in" class="edit-calculation-list-container" tag="div">

        <div class="edit-calculation-list-header" key="header">
          <div>
            <checkbox @checkbox-changed="updateCheckBoxes" :checked="overallCheck"></checkbox>
          </div>
          <div>Material</div>
          <div>Price</div>
          <div>Packaging</div>
          <div>Supplier</div>
          <div>Destinations & routes</div>
          <div>Actions</div>
        </div>


        <div v-if="showLoading" class="spinner-container" key="spinner">
          <spinner class="space-around"></spinner>
        </div>

        <div v-else-if="showEmpty" class="empty-container" key="empty">
          <span class="space-around">No Calculations found.</span>
        </div>

        <bulk-edit-row v-else class="edit-calculation-list-item" v-for="premise of this.premiseEditStore.getPremisses"
                       :key="premise.id" :id="premise.id" :premise="premise" @action="onClickAction"
                       @remove="updateUrl">
        </bulk-edit-row>


      </transition-group>
    </transition>

    <mass-edit-dialog v-if="showData" :show="showMultiselectAction" @action="multiselectAction"
                      :select-count="selectCount"></mass-edit-dialog>


    <modal :z-index="2000" :state="showEditModal">
      <div class="modal-content-container">
        <component
            :is="componentType"
            v-model:partNumber="componentProps.partNumber"
            v-model:hsCode="componentProps.hsCode"
            v-model:tariffRate="componentProps.tariffRate"
            v-model:tariffUnlocked="componentProps.tariffUnlocked"
            v-model:description="componentProps.description"
            v-model:price="componentProps.price"
            v-model:overSeaShare="componentProps.overSeaShare"
            v-model:includeFcaFee="componentProps.includeFcaFee"
            v-model:length="componentProps.length"
            v-model:width="componentProps.width"
            v-model:height="componentProps.height"
            v-model:weight="componentProps.weight"
            v-model:weightUnit="componentProps.weightUnit"
            v-model:dimensionUnit="componentProps.dimensionUnit"
            v-model:unitCount="componentProps.unitCount"
            v-model:mixable="componentProps.mixable"
            v-model:stackable="componentProps.stackable"
            v-model:hideDescription="componentProps.hideDescription"
            :countryId=null
            :responsive="false"
            @close="closeEditModalAction('cancel')"

        >
        </component>
        <div class="modal-content-footer" >
          <basic-button v-if="!modalCloseOnly" :show-icon="false" @click="closeEditModalAction('accept')">OK</basic-button>
          <basic-button variant="secondary" :show-icon="false" @click="closeEditModalAction('cancel')"> {{ modalCloseOnly ? "Close" : "Cancel" }}
          </basic-button>
        </div>
      </div>
    </modal>

  </div>
</template>

<script>

import {UrlSafeBase64} from "@/common.js";
import {mapStores} from "pinia";
import {usePremiseEditStore} from "@/store/premiseEdit.js";
import BasicButton from "@/components/UI/BasicButton.vue";
import BulkEditRow from "@/components/layout/bulkedit/BulkEditRow.vue";
import Checkbox from "@/components/UI/Checkbox.vue";
import CalculationListItem from "@/components/layout/calculation/CalculationListItem.vue";
import Spinner from "@/components/UI/Spinner.vue";
import ListEdit from "@/components/UI/ListEdit.vue";
import MassEditDialog from "@/components/UI/MassEditDialog.vue";
import Modal from "@/components/UI/Modal.vue";
import PriceEdit from "@/components/layout/edit/PriceEdit.vue";
import MaterialEdit from "@/components/layout/edit/MaterialEdit.vue";
import PackagingEdit from "@/components/layout/edit/PackagingEdit.vue";
import DestinationListView from "@/components/layout/edit/DestinationListView.vue";
import logger from "@/logger.js";
import {useNotificationStore} from "@/store/notification.js";


const COMPONENT_TYPES = {
  price: PriceEdit,
  material: MaterialEdit,
  packaging: PackagingEdit,
  destinations: DestinationListView,
}

export default {
  name: "MassEdit",
  components: {
    Modal,
    MassEditDialog,
    ListEdit,
    Spinner,
    CalculationListItem,
    Checkbox,
    BulkEditRow,
    BasicButton
  },
  computed: {
    ...mapStores(usePremiseEditStore, useNotificationStore),
    hasSelection() {
      if (this.premiseEditStore.isLoading || this.premiseEditStore.selectedLoading) {
        return false;
      }
      return this.premiseEditStore.getSelectedPremissesIds?.length > 0;
    },
    selectCount() {
      return this.selectedPremisses?.length ?? 0;
    },
    selectedPremisses() {
      return this.premiseEditStore.getSelectedPremisses;
    },
    showEmpty() {
      return this.premiseEditStore.showEmpty;
    },
    showLoading() {
      return this.premiseEditStore.isLoading;
    },
    showData() {
      return this.premiseEditStore.showData;
    },
    overallCheck() {
      return this.premiseEditStore.isLoading ? false : this.premiseEditStore.getPremisses?.every(p => p.selected === true) ?? false;
    },
    showMultiselectAction() {
      return this.selectCount > 0;
    },
    modalCloseOnly() {
      return this.modalType === 'material' && !this.componentProps.tariffUnlocked;
    },
    showEditModal() {
      return ((this.modalType ?? null) !== null);
    },
    componentProps() {
      return this.componentData?.props ?? null;
    },
    componentType() {
      return this.modalType ? COMPONENT_TYPES[this.modalType] : null;
    },
    componentData() {
      return this.modalType ? this.componentsData[this.modalType] : null;
    },
    showProcessingModal() {
      return this.premiseEditStore.showProcessingModal || this.showCalculationModal;
    },
    shownProcessingMessage() {
      return this.processingMessage;
    }
  },
  watch: {
    showProcessingModal(newState, _) {
      if(newState) {
        this.notificationStore.setSpinner(this.shownProcessingMessage);
      }
      else {
        this.notificationStore.clearSpinner();
      }
    }
  },
  created() {
    this.bulkQuery = this.$route.params.ids;
    this.ids = new UrlSafeBase64().decodeIds(this.$route.params.ids);
    this.premiseEditStore.loadPremissesForced(this.ids);
  },

  data() {
    return {
      ids: [],
      bulkQuery: null,
      modalType: null,
      componentsData: {
        price: {props: {price: 0, overSeaShare: 0, includeFcaFee: false}},
        material: {props: {partNumber: "", hsCode: null, tariffRate: null, tariffUnlocked: false, description: "", hideDescription: false}},
        packaging: {
          props: {
            length: 0,
            width: 0,
            height: 0,
            weight: 0,
            weightUnit: "KG",
            dimensionUnit: "MM",
            unitCount: 1,
            mixable: true,
            stackable: true
          }
        },
        destinations: {props: {}},
      },
      editIds: null,
      dataSourceId: null,
      processingMessage: "Please wait. Calculating ...",
      showCalculationModal: false,
    }
  },
  methods: {
    updateUrl(id) {

      const idx = this.ids.findIndex(curId => curId === id);

      if (idx > -1) {
        this.ids.splice(idx, 1);

        this.$router.replace({
          name: "bulk",
          params: {
            ids: new UrlSafeBase64().encodeIds(this.ids)
          }
        });
      }
    },
    async startCalculation() {
      this.showCalculationModal = true;
      const error = await this.premiseEditStore.startCalculation();

      if (error === null) {
        this.closeMassEdit()
      }
      this.showCalculationModal = false;
    },
    closeMassEdit() {
      this.$router.push({name: "calculation-list"});
    },
    updateCheckBoxes(value) {
      this.premiseEditStore.setAll(value);
    },
    multiselectAction(action) {
      this.openModal(action, this.selectedPremisses.map(p => p.id));
    },
    onClickAction(data) {
      const massEdit = 0 !== this.selectCount
      this.openModal(data.action, massEdit ? this.premiseEditStore.getSelectedPremissesIds : [data.id], data.id, massEdit);
    },
    openModal(type, ids, dataSource = -1, massEdit = true) {

      if (type !== 'destinations')
        this.fillData(type, dataSource, massEdit)
      else {
        this.premiseEditStore.prepareDestinations(dataSource, ids, massEdit, true);
      }

      this.dataSourceId = dataSource !== -1 ? dataSource : null;
      this.editIds = ids;
      this.modalType = type;

      logger.info("open modal", massEdit, this.modalType, this.editIds, this.dataSourceId)

    },
    async closeEditModalAction(action) {
      if (this.modalType === "destinations") {
        if (action === "accept") {
          await this.premiseEditStore.executeDestinationsMassEdit();
        } else {
          this.premiseEditStore.cancelMassEdit();
        }
      } else if (action === "accept") {
        const props = this.componentsData[this.modalType].props;

        switch (this.modalType) {
          case "price":
            await this.premiseEditStore.batchUpdatePrice(this.editIds, props);
            break;
          case "material":
            await this.premiseEditStore.batchUpdateMaterial(this.editIds, props);
            break;
          case "packaging":
            await this.premiseEditStore.batchUpdatePackaging(this.editIds, props);
            break;
        }
      }

      // Clear data
      this.fillData(this.modalType);
      this.modalType = null;
    },
    fillData(type, id = -1, hideDescription = false) {

      if (id === -1) {
        // clear
        this.componentsData = {
          price: {props: {price: null, overSeaShare: null, includeFcaFee: null}},
          material: {
            props: {
              partNumber: "",
              hsCode: null,
              tariffRate: null,
              tariffUnlocked: false,
              description: null,
              hideDescription: hideDescription
            }
          },
          packaging: {
            props: {
              length: null,
              width: null,
              height: null,
              weight: null,
              weightUnit: "KG",
              dimensionUnit: "MM",
              unitCount: null,
              mixable: true,
              stackable: true
            }
          },
          destinations: {props: {}},
        };
      } else {
        const premise = this.premiseEditStore.getById(id);

        if (type === "price") {
          this.componentsData.price.props = {
            price: premise.material_cost,
            overSeaShare: premise.oversea_share,
            includeFcaFee: premise.is_fca_enabled
          }
        } else if (type === "material") {

          this.componentsData.material.props = {
            partNumber: premise.material.part_number,
            hsCode: premise.hs_code,
            tariffRate: premise.tariff_rate ?? null,
            tariffUnlocked: premise.tariff_unlocked,
            description: premise.material.name ?? "",
            hideDescription: hideDescription
          }

        } else if (type === "packaging") {
          this.componentsData.packaging.props = {
            length: premise.handling_unit.length,
            width: premise.handling_unit.width,
            height: premise.handling_unit.height,
            weight: premise.handling_unit.weight,
            weightUnit: premise.handling_unit.weight_unit ?? "KG",
            dimensionUnit: premise.handling_unit.dimension_unit ?? "MM",
            unitCount: premise.handling_unit.content_unit_count,
            mixable: premise.is_mixable ?? true,
            stackable: premise.is_stackable ?? true
          }
        }
      }
    }
  }
}
</script>
<style scoped>

/* Global style für copy-mode cursor */
.edit-calculation-container.has-selection :deep(.copyable-cell:hover) {
  cursor: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyOCIgaGVpZ2h0PSIyOCIgdmlld0JveD0iMCAwIDI1NiAyNTYiPgogIDxyZWN0IHg9Ijg0IiB5PSIzMiIgd2lkdGg9IjEzNiIgaGVpZ2h0PSIxMzYiIGZpbGw9IndoaXRlIiBzdHJva2U9IiMwMDAwMDAiIHN0cm9rZS13aWR0aD0iOCIgcng9IjQiLz4KICA8cmVjdCB4PSIzNiIgeT0iODQiIHdpZHRoPSIxMzYiIGhlaWdodD0iMTM2IiBmaWxsPSJ3aGl0ZSIgc3Ryb2tlPSIjMDAwMDAwIiBzdHJva2Utd2lkdGg9IjgiIHJ4PSI0Ii8+Cjwvc3ZnPg==") 12 12, pointer;
  background-color: #f8fafc;
  border-radius: 0.8rem;
}


.space-around {
  margin: 3rem;
}


.modal-content-container {
  display: flex;
  flex-direction: column;
  gap: 1.6rem;
  margin-top: 1.6rem;
  min-width: 50rem;
}

.modal-content-footer {
  display: flex;
  justify-content: flex-end;
  gap: 1.6rem;
}

/* Container Animation */

.list-edit-enter-from {
  opacity: 0;
  transform: translateY(-20px);
  max-height: 0;
}

.list-edit-leave-to {
  opacity: 0;
  transform: translateY(-20px);
  max-height: 0;
}

.list-edit-enter-active,
.list-edit-leave-active {
  transition: all 0.4s ease;
  overflow: hidden;
}


.spinner-container {
  display: flex;
  justify-content: center;
  align-items: center;
}

.empty-container {
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 1.6rem;
}

.edit-calculation-list-container {
  background: white;
  border-radius: 1.2rem;
  box-shadow: 0 0.4rem 0.6rem -0.1rem rgba(0, 0, 0, 0.1);
  overflow: hidden;
  margin-top: 3rem;
  margin-bottom: 3rem;

}


.edit-calculation-list-header {
  display: grid;
  grid-template-columns: 6rem 1fr 1fr 1.5fr 1.5fr 1.5fr 10rem;
  gap: 1.6rem;
  padding: 2.4rem;
  background-color: #ffffff;
  border-bottom: 0.1rem solid rgba(107, 134, 156, 0.2);
  font-weight: 500;
  font-size: 1.4rem;
  color: #6B869C;
  text-transform: uppercase;
  letter-spacing: 0.08rem;
}

.edit-calculation-container {
  display: flex;
  flex-direction: column;
}

.header-container {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1.6rem;
}

.header-controls {
  display: flex;
  gap: 1.6rem;
}
</style>