<script>
import Loading from '@shell/components/Loading';
import ResourceTable from '@shell/components/ResourceTable';
import Masthead from '@shell/components/ResourceList/Masthead';

import { allHash } from '@shell/utils/promise';
import { STATE, AGE, NAME } from '@shell/config/table-headers';
import { mapPref, GROUP_RESOURCES } from '@shell/store/prefs';
import { NODE } from '@shell/config/types';

import { PRODUCT_NAME as HARVESTER_PRODUCT } from '../config/harvester';
import { CLUSTER_NETWORK } from '../config/query-params';
import { HCI } from '../types';

export default {
  name: 'ListHarvesterVLANConfigs',

  components: {
    ResourceTable,
    Loading,
    Masthead,
  },

  async fetch() {
    const inStore = this.$store.getters['currentProduct'].inStore;

    await allHash({
      configs:         this.$store.dispatch(`${ inStore }/findAll`, { type: HCI.VLAN_CONFIG }),
      clusterNetworks: this.$store.dispatch(`${ inStore }/findAll`, { type: HCI.CLUSTER_NETWORK }),
      vlanStatuses:    this.$store.dispatch(`${ inStore }/findAll`, { type: HCI.VLAN_STATUS }),
      nodes:           this.$store.dispatch(`${ inStore }/findAll`, { type: NODE })
    });
  },

  data() {
    return { HCI };
  },

  computed: {
    groupPreference: mapPref(GROUP_RESOURCES),

    headers() {
      return [
        STATE,
        {
          ...NAME,
          width: 300,
        },
        {
          name:     'type',
          labelKey: 'tableHeaders.type',
          value:    'typeDisplay',
          getValue: (row) => row.typeDisplay,
          sort:     ['typeDisplay'],
        },
        AGE,
      ];
    },

    rows() {
      const inStore = this.$store.getters['currentProduct'].inStore;

      const configs = this.$store.getters[`${ inStore }/all`](HCI.VLAN_CONFIG);

      return configs;
    },

    vlanConfigSchema() {
      const inStore = this.$store.getters['currentProduct'].inStore;

      return this.$store.getters[`${ inStore }/schemaFor`](HCI.VLAN_CONFIG);
    },

    clusterNetworkSchema() {
      const inStore = this.$store.getters['currentProduct'].inStore;

      return this.$store.getters[`${ inStore }/schemaFor`](HCI.CLUSTER_NETWORK);
    },

    isClusterNetworkCreatable() {
      return (this.clusterNetworkSchema?.collectionMethods || []).includes('POST');
    },

    createClusterNetworkLocation() {
      const location = {
        name:   `${ HARVESTER_PRODUCT }-c-cluster-resource-create`,
        params: {
          product:  HARVESTER_PRODUCT,
          resource: HCI.CLUSTER_NETWORK,
        },
      };

      return location;
    },

    clusterNetworkWithoutConfigs() {
      const inStore = this.$store.getters['currentProduct'].inStore;

      const clusterNetworks = this.$store.getters[`${ inStore }/all`](HCI.CLUSTER_NETWORK);

      const out = clusterNetworks.map((network) => {
        const hasChild = !!this.rows.find((config) => config?.spec?.clusterNetwork === network.id);

        return {
          ...network,
          hasChild
        };
      });

      return out;
    },

    rowsWithFakeClusterNetworks() {
      const fakeRows = this.clusterNetworkWithoutConfigs.map((network) => {
        return {
          groupByLabel:          network.id,
          isFake:                true,
          mainRowKey:            network.id,
          nameDisplay:           network.id,
          groupByClusterNetwork: network.id,
          availableActions:      []
        };
      });

      return [...this.rows, ...fakeRows];
    },
  },

  methods: {
    showClusterNetworkActionButton(group) {
      const inStore = this.$store.getters['currentProduct'].inStore;
      const clusterNetwork = group.key;

      const resource = this.$store.getters[`${ inStore }/byId`](HCI.CLUSTER_NETWORK, clusterNetwork);

      return !!resource;
    },

    showClusterNetworkAction(event, group) {
      const inStore = this.$store.getters['currentProduct'].inStore;
      const clusterNetwork = group.key;

      const resource = this.$store.getters[`${ inStore }/byId`](HCI.CLUSTER_NETWORK, clusterNetwork);

      this.$store.commit(`action-menu/show`, {
        resources: [resource],
        elem:      event.target
      });
    },

    createVlanConfigLocation(group) {
      const clusterNetwork = group.key;

      const location = {
        name:   `${ HARVESTER_PRODUCT }-c-cluster-resource-create`,
        params: {
          product:  HARVESTER_PRODUCT,
          resource: HCI.VLAN_CONFIG,
        },
      };

      location.query = { [CLUSTER_NETWORK]: clusterNetwork };

      return location;
    },

    slotName(clusterNetwork) {
      return `main-row:${ clusterNetwork }`;
    },

    groupLabel(group) {
      const row = group.rows[0];

      if (row.isFake) {
        return `${ this.t('harvester.network.clusterNetwork.label') }: ${ row.nameDisplay }`;
      }

      return `${ this.t('harvester.network.clusterNetwork.label') }: ${ group.key }`;
    },
  },
};
</script>

<template>
  <div>
    <Loading v-if="$fetchState.pending" />
    <div v-else>
      <Masthead
        :schema="clusterNetworkSchema"
        :type-display="t('harvester.clusterNetwork.title')"
        :resource="HCI.CLUSTER_NETWORK"
        :create-location="createClusterNetworkLocation"
        :create-button-label="t('harvester.clusterNetwork.create.button.label')"
      />
      <ResourceTable
        :rows="rowsWithFakeClusterNetworks"
        :headers="headers"
        :groupable="true"
        :schema="vlanConfigSchema"
        group-by="groupByClusterNetwork"
      >
        <template #header-middle>
          <div />
        </template>
        <template #group-by="{group}">
          <div class="group-bar">
            <div class="group-tab">
              <span>
                {{ groupLabel(group) }}
              </span>
            </div>

            <div class="right">
              <router-link
                v-if="isClusterNetworkCreatable && group.key !== 'mgmt'"
                class="btn btn-sm role-secondary mr-5"
                :to="createVlanConfigLocation(group)"
              >
                {{ t('harvester.vlanConfig.createNetworkConfig') }}
              </router-link>
              <button
                type="button"
                class="btn btn-sm role-multi-action actions mr-10"
                :class="{invisible: !showClusterNetworkActionButton(group)}"
                @click="showClusterNetworkAction($event, group)"
              >
                <i class="icon icon-actions" />
              </button>
            </div>
          </div>
        </template>
        <template
          v-for="clusterNetwork in clusterNetworkWithoutConfigs"
          v-slot:[slotName(clusterNetwork.id)]
        >
          <tr
            v-show="!clusterNetwork.hasChild"
            :key="clusterNetwork.id"
            class="main-row"
          >
            <td
              class="empty text-center"
              colspan="12"
            >
              {{ clusterNetwork.id === 'mgmt' ? t('harvester.clusterNetwork.mgmt') : t('harvester.clusterNetwork.clusterNetwork') }}
            </td>
          </tr>
        </template>
      </ResourceTable>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.group-bar {
  display: flex;
  flex-direction: row;
  justify-content: space-between;

  .right {
    margin-top: 5px;
    margin-bottom: 3px;
  }

  .group-tab {
    &, &::after {
        height: 50px;
    }

    &::after {
        right: -20px;
    }

    SPAN {
      color: var(--body-text) !important;
    }
  }
}
</style>

<style lang="scss">
  .col-link-detail {
    // Avoid 'Create Network Config' button to overlap the namespace tab when resize table to min length
    min-width: 200px;
  }
</style>

<style lang="scss">
  .group-bar .right {
    display: flex;
    margin-left: 50px;
    a {
      height: 30px;
    }
  }
