<template>
  <div class="tab-content-wrapper">
    <div>
      <BsBox title="" boxType="info" :closable="true" class="blue-info-box">
        <div>
          <p class="blue-box-text">Analyze your matches and modify their status in the “match” row.</p>
          <p class="blue-box-text">
            To have a general view of all the data, go to the
            <a @click="goToTab(1)" class="tab-link" style="text-decoration: underline;">"Full table"</a> menu tab.
          </p>
        </div>
      </BsBox>
    </div>
  </div>

  <div class="buttons-alignment">
    <div class="q-gutter-sm q-pa-sm">
      <BsButton class="bs-secondary-button bs-font-medium-3-normal" unelevated dense @click="previousId">
        <BsIcon name="chevron-left" /> Previous
      </BsButton>
    </div>
    <div class="star-class">
      <img src="@/assets/images/star.png" alt="Star Icon" />
    </div>
    <div class="bs-font-medium-3-normal">
      {{ id.primary_id_name === "primary_id" ? id.primary_id_name : id.primary_id_name.replace(/^primary_/, '') }}
    </div>
    <div class="q-pa-sm" :style="{ 'max-width': '300px' }">
      <BsSelect v-model="selected_id" :all-options="options.id_list" label="" />
    </div>
    <div class="bs-font-medium-3-normal">{{ selected_id_occurences }} items</div>
    <div class="q-gutter-sm q-pa-sm">
      <BsButton class="bs-secondary-button bs-font-medium-3-normal" unelevated dense @click="nextId">
        Next
        <BsIcon name="chevron-right" />
      </BsButton>
    </div>
  </div>
  <div style="padding-left: 24px;padding-right: 16px;">
    <div class="bs-table-top-container bs-table-name bordered">
      Focus Table
    </div>
    <div class="table-box-wrapper">
      <div class="q-pa-sm headless-table" 
        :style="{ width: '30%', height: `${Math.max((rows_primary.length + extra_cols_secondary.length +3) * 41 + 10, 100)}px` }">
        <BsGrid title="Primary dataset" :rows="rows_primary" :columns="columns_primary" :row-selection="selection" :enable-cell-text-selection="true">
          <template #searchBoxLegend>
            <div class="search-box-legend">
              <i class="dku-icon-star-fill-16" style="margin-right: 7px;"></i> <b style="font-size: 16px" font-style: normal>Primary dataset</b>
            </div>
          </template>
        </BsGrid>
      </div>
      <div></div>
      <div class="q-pa-sm headless-table" 
        :style="{ width: '70%', height: `${Math.max((rows_secondary.length + extra_cols_secondary.length +3) * 41 + 10, 100)}px` }" 
        v-if="showGrid">        
        <BsGrid title="Secondary dataset" :rows="rows_secondary" :columns="columns_secondary" :row-selection="selection">
          <template #searchBoxLegend>
            <div class="search-box-legend">
              <b style="font-size: 16px" font-style: normal>Secondary dataset</b>
            </div>
          </template>
        </BsGrid>
      </div>
    </div>
  </div>
</template>

<script>
import image from "@/assets/images/bs-logo.png";
import DropDownComponent from './DropDownComponent.vue';
import { API } from "@/Api";

// Pinia
import { mapState, mapActions } from 'pinia';
import { useTableStore } from '../stores/tableStore';

/**
 * Displays a detailed, side-by-side view of a single primary record.
 * Fully driven by the Pinia store for all data and state.
 */
export default {
  props: ['render'],
  components: {
    DropDownComponent
  },
  name: "FirstTabContent",
  data: function () {
    return {
      // Local state for UI and grid structure
      image: image,
      rows_primary: [],
      columns_secondary: [],
      rows_secondary: [],
      selection: "single",
      showGrid: true,
      columns_primary: [
        {
          headerName: "col_name",
          field: "col_name",
          align: 'left',
          sortable: true,
          cellDataType: "text",
          minWidth: 200,
          cellClass: params => {
            if (this.extra_cols_primary.includes(params.value)) { return 'border-right'; }
            return params.rowIndex % 2 === 0 ? 'even-row' : 'odd-row';
          }
        },
        {
          headerName: "col_value",
          field: "col_value",
          align: "center",
          sortable: true,
          cellDataType: "text",
          minWidth: 215,
          cellClass: params => {
            if (this.extra_cols_primary.includes(params.data.col_name)) { return ''; }
            return params.rowIndex > 0 ? 'highlighted-cell' : '';
          }
        }
      ],
    };
  },

  emits: ['navigate-to-tab'],

  computed: {
    // Map all state from the store.
    ...mapState(useTableStore, {
      fullTable: 'fullTableData',
      id_occurrences_data: 'idOccurrencesData',
      _idList: 'idList',
      _primaryIdName: 'primaryIdName',
      _secondaryIdName: 'secondaryIdName',
      primary_table_keys: 'primaryTableKeys',
      secondary_table_keys: 'secondaryTableKeys',
      extra_cols_primary: 'extraColsPrimary',
      extra_cols_secondary: 'extraColsSecondary',
      _selected_id_from_store: 'selected_id'
    }),

    // Re-create nested data structures for the template.
    options() {
      return { id_list: this._idList };
    },
    id() {
      return { primary_id_name: this._primaryIdName };
    },
    secondary_id() {
      return { secondary_id_name: this._secondaryIdName };
    },

    /** v-model for selected_id, synced with the store. */
    selected_id: {
      get() {
        return this._selected_id_from_store;
      },
      set(value) {
        this.setSelectedId(value); 
      }
    },

    /** Updates automatically when selected_id changes. */
    selected_id_occurences() {
      if (!this.selected_id || !this.id_occurrences_data) {
        return 0;
      }
      return this.id_occurrences_data[String(this.selected_id)] || 0;
    }
  },

  methods: {
    // Map actions from the store.
    ...mapActions(useTableStore, [
      'updateCell',
      'setSelectedId',
      'nextId',
      'previousId'
    ]),

    /** Emits event to parent to switch tabs. */
    goToTab(index) {
      this.$emit('navigate-to-tab', index);
    },

    /**
     * Filters and transforms store data for the two grids.
     * This is the core rendering logic for this tab.
     */
    processDataForSelectedId() {
      if (!this.selected_id || !this.fullTable || Object.keys(this.fullTable).length === 0) {
        console.warn("Selected ID is missing or full dataset is not loaded.");
        return;
      }
      
      try {
        // --- Step 1: Filter ---
        const primaryIdColName = this.id.primary_id_name;
        const idColumnObject = this.fullTable[primaryIdColName];

        if (!idColumnObject || typeof idColumnObject !== 'object') {
            console.error(`Primary ID column '${primaryIdColName}' not found or is not an object in the dataset.`);
            this.rows_primary = [];
            this.rows_secondary = [];
            return;
        }

        const matchingIndices = [];
        for (const index in idColumnObject) {
            if (Object.prototype.hasOwnProperty.call(idColumnObject, index)) {
                if (String(idColumnObject[index]) === String(this.selected_id)) {
                    matchingIndices.push(index);
                }
            }
        }

        if (matchingIndices.length === 0) {
            console.warn(`No data found for selected ID: ${this.selected_id}`);
            this.rows_primary = [];
            this.rows_secondary = [];
            return;
        }
        
        // --- Step 2: Create subset ---
        const filtered_subset = {};
        for (const key in this.fullTable) {
            if (Object.prototype.hasOwnProperty.call(this.fullTable, key)) {
                const originalColumn = this.fullTable[key];
                filtered_subset[key] = matchingIndices.map(index => originalColumn[index]);
            }
        }
        
        // --- Step 3: Format Primary Table ---
        const filteredResult = Object.fromEntries(
          Object.entries(filtered_subset)
            .filter(([key]) => this.primary_table_keys.includes(key) || this.extra_cols_primary.includes(key.replace(/^primary_/, '')))
            .map(([key, value]) => {
              const formattedKey = key === "primary_id" ? key : key.replace(/^primary_/, '');
              return [formattedKey, value[0]];
            })
        );

        this.rows_primary = Object.entries(filteredResult).map(([key, value]) => ({
          col_name: key,
          col_value: value,
        }));

        // --- Step 4: Generate Secondary Columns ---
        this.columns_secondary = [{
          headerName: "col_name",
          field: "col_name",
          align: "left",
          sortable: true,
          cellDataType: "text",
          minWidth: 200,
          cellClass: params => {
            const rowCount = params.api.getDisplayedRowCount();
            const isLastThreeRows = params.rowIndex >= rowCount - 3;
            if (this.extra_cols_secondary.includes(params.value) || isLastThreeRows) { return 'border-right'; }
            return params.rowIndex % 2 === 0 ? 'even-row' : 'odd-row';
          }
        },
        {
          headerName: "col_value",
          field: "col_value",
          align: "center",
          sortable: true,
          cellDataType: "text",
          minWidth: 215,
          cellClass: params => {
            const primaryColumnValue = this.rows_primary.find(row => row.col_name === params.data.col_name)?.col_value;
            if (this.primary_table_keys.includes(params.data.col_name) && params.value === primaryColumnValue) { return 'highlighted-cell'; }
            return '';
          },
          onCellValueChanged: async (event) => {
            const { newValue, oldValue, node, colDef, data } = event;
            const rowCount = event.api.getDisplayedRowCount();
            const isSecondLastRow = node.rowIndex === rowCount - 2;
            const celltype = isSecondLastRow ? "dropdown" : "comment";
            const primary_id = this.selected_id;
            const fieldName = colDef.field;
            data[fieldName] = newValue;
            event.api.refreshCells({ rowNodes: [node], columns: [fieldName] });

            const secondary_id = this.rows_secondary[0][colDef.field];

            const payload = { oldvalue: oldValue, newvalue: newValue, celltype, primary_id, secondary_id };
            try {
              // Optimistic update: update the store immediately.
              this.updateCell({
                primaryId: primary_id,
                primaryIdColumn: this.id.primary_id_name,
                secondaryId: secondary_id,
                secondaryIdColumn: this.secondary_id.secondary_id_name,
                field: data.col_name,
                newValue: newValue,
              });

              // Send API call in the background.
              await API.postCellValueChange(payload);

            } catch (error) {
              console.error("Error posting cell value change:", error);
            }
          },
          cellEditorSelector: params => {
            const rowCount = params.api.getDisplayedRowCount();
            if (params.rowIndex === rowCount - 2) { // 'Match' row
              return {
                component: 'agRichSelectCellEditor',
                params: { values: ["Pending", "Approved", "Rejected"] }
              };
            }
            return null;
          },
          cellRendererSelector: params => {
            const rowCount = params.api.getDisplayedRowCount();
            if (params.rowIndex === rowCount - 2) {
              return { component: 'DropDownComponent' };
            }
            return null;
          },
          editable: params => {
            const rowCount = params.api.getDisplayedRowCount();
            return params.node.rowIndex >= rowCount - 2; // 'Match' & 'Comments'
          },
          cellRenderer: params => {
            const isLastRow = params.node.rowIndex === params.api.getDisplayedRowCount() - 1;
            if (isLastRow && (params.value === undefined || params.value === null)) {
              return `<span style="color: #929292;">Add comment</span>`;
            }
            return params.getValue();
          }
        }];

        const numValues = filtered_subset[Object.keys(filtered_subset)[0]].length;
        
        if (numValues > 1) {
          for (let i = 1; i < numValues; i++) {
            this.columns_secondary.push({
              ...this.columns_secondary[1],
              headerName: `col_value${i + 1}`,
              field: `col_value${i + 1}`,
            });
          }
        }

        // --- Step 5: Format Secondary Rows ---
        const filteredResult_secondary = Object.fromEntries(
          Object.entries(filtered_subset)
            .filter(([key]) => this.secondary_table_keys.includes(key) || this.extra_cols_secondary.includes(key.replace(/^secondary_/, '')))
        );

        const tempRows = [];
        const colNames = Object.keys(filteredResult_secondary);
        const colData = Object.values(filteredResult_secondary);

        for (let i = 0; i < colNames.length; i++) {
          const key = colNames[i];
          const values = colData[i];
          const row = { col_name: (key !== "secondary_id" ? key.replace(/^secondary_/, '') : key) };
          for (let j = 0; j < numValues; j++) {
            row[`col_value${j === 0 ? '' : j + 1}`] = values[j];
          }
          tempRows.push(row);
        }

        this.rows_secondary = tempRows;

        // --- Step 6: Force re-render ---
        this.showGrid = false;
        this.$nextTick(() => {
          this.showGrid = true;
        });

      } catch (error) {
        console.error("Error processing data for selected ID:", error);
      }
    },
  },
  watch: {
    /** Handles the INITIAL load once metadata is ready. */
    primary_table_keys(newKeys) {
        if (newKeys && newKeys.length > 0 && this.fullTable && Object.keys(this.fullTable).length > 0 && this.selected_id) {
            this.processDataForSelectedId();
        }
    },
    
    /** Handles a user changing the ID in the dropdown. */
    selected_id(newId) {
        if (newId && this.primary_table_keys && this.primary_table_keys.length > 0 && this.fullTable && Object.keys(this.fullTable).length > 0) {
            this.processDataForSelectedId();
        }
    },

    /** Handles SUBSEQUENT updates (e.g., after updateCell). */
    fullTable(newTableData) {
      // Guard clause prevents race condition on initial load
      if (this.primary_table_keys && this.primary_table_keys.length > 0 && this.selected_id) {
          this.processDataForSelectedId();
      }
    }
  },
};
</script>


<style scoped>
.tab-content-wrapper {
  padding-left: 20px;
  padding-top: 20px;
}

.buttons-alignment {
  display: flex;
  justify-content: center;
  align-items: center;
  align-self: stretch;
}

.star-class {
  display: flex;
  align-items: center;
  margin-right: 7px;
  margin-left: 5px;
}

.table-box-wrapper {
  display: flex;
  justify-content: flex-start;
  gap: 10px;
  width: 100%;
  padding: 0;
  height: fit-content;
  box-sizing: border-box;
  border: 0px solid #ddd;
}
</style>

<style>
/* Hiding default headers and controls of the BsGrid for a custom look */
.headless-table .ag-header-container,
.headless-table .bs-search-box-input .q-field__control,
.headless-table .q-ag-header-viewport,
.headless-table .ag-paging-panel,
.headless-table .bs-grid .bs-grid-title,
.headless-table .ag-header {
  display: none !important;
}

.headless-table {
  margin-top: 0px;
  padding: 0;
}

.bordered {
  border-width: 1px 1px 1px 1px;
  height: 51px;
}

/* Custom cell styling */
.highlighted-cell {
  background-color: #d6f0d6; /* Green highlight for matching values */
}

.even-row {
  background-color: #e6f1fa;
  border-right: 1px solid #929292 !important;
}

.odd-row {
  background-color: #eeedee;
  border-right: 1px solid #929292 !important;
}

.border-right {
  border-right: 1px solid #929292 !important;
}

.blue-info-box {
  padding: 10px 10px 1px 10px;
}

.blue-box-text {
  margin: 0 0 5px !important;
}

.q-pa-sm .bs-font-medium-2-normal {
  font-size: 16px
}
</style>