<template>
  <div class="configurable-table">
    <h2>{{ title }}</h2>
    <p>{{ description }}</p>

    <!-- Table Header -->
    <div class="table-row table-header" :class="{ 'multi-column': typeComponents.length > 1 }" :style="gridTemplateStyle">
      <div class="column-header" v-if="allowSort" @click="toggleSort" style="cursor: pointer;">
        {{ mergedConfig.columnTitle }}
        <span v-if="sortByName">{{ sortDirection === 'asc' ? '▲' : '▼'  }}</span>
      </div>
      <div v-for="(component, index) in typeComponents" :key="'header-'+index" class="column-header">
        {{ index === 0 ? mergedConfig.columnValue1 : mergedConfig.columnValue2 }}
      </div>
    </div>

    <!-- Table Rows -->
    <div
      v-for="entry in sortedValues"
      :key="entry.id"
      class="table-row"
      :class="{
        'multi-column': typeComponents.length > 1,
        'print-row': printMode
      }"
      :style="gridTemplateStyle"
    >
      <div class="item-details">
        <p>{{ entry.item.title }}</p>
      </div>

      <!-- Dynamic Components -->
      <template v-for="(component, index) in typeComponents">
        <div :key="'component-'+entry.id+'-'+index" :class="`${component}-input`">
          <!-- Yes-No Input Type -->
          <template v-if="component === 'yes-no'">
            <template v-if="printMode">
              <span>{{ getValueForIndex(entry, index) === true ? mergedConfig.labelYes : (getValueForIndex(entry, index) === false ? mergedConfig.labelNo : '') }}</span>
            </template>
            <template v-else>
              <div class="yes-no-options">
                <label>
                  <input
                    type="radio"
                    :name="'yesNo-' + entry.id + '-' + index" 
                    :value="true"
                    :checked="getValueForIndex(entry, index) === true"
                    @change="updateValueForIndex(entry.id, true, index)"
                  />
                  {{ mergedConfig.labelYes }}
                </label>
                <label>
                  <input
                    type="radio"
                    :name="'yesNo-' + entry.id + '-' + index"
                    :value="false"
                    :checked="getValueForIndex(entry, index) === false"
                    @change="updateValueForIndex(entry.id, false, index)"
                  />
                  {{ mergedConfig.labelNo }}
                </label>
              </div>
            </template>
          </template>

          <!-- Numeric Input Type -->
          <template v-if="component === 'numeric'">
            <template v-if="printMode">
              <span class="numeric-print">{{ getValueForIndex(entry, index) }}</span>
            </template>
            <input
              v-else
              type="number"
              class="form-control numeric-input"
              :placeholder="index === 0 ? mergedConfig.placeholder1 : mergedConfig.placeholder2"
              :value="getValueForIndex(entry, index)"
              @input="updateValueForIndex(entry.id, $event.target.value ? Number($event.target.value) : null, index)"
            />
          </template>

          <!-- Date Input Type -->
          <template v-if="component === 'date'">
            <template v-if="printMode">
              <span>{{ getValueForIndex(entry, index) }}</span>
            </template>
            <input
              v-else
              type="date"
              class="form-control"
              :placeholder="index === 0 ? mergedConfig.placeholder1 : mergedConfig.placeholder2"
              :value="getValueForIndex(entry, index)"
              @input="updateValueForIndex(entry.id, $event.target.value, index)"
            />
          </template>

          <!-- Text Input Type -->
          <template v-if="component === 'text' || component === 'textarea'">
            <template v-if="printMode">
              <span>{{ getValueForIndex(entry, index) }}</span>
            </template>
            <template v-else>
              <input
                v-if="component === 'text'"
                type="text"
                class="form-control"
                :placeholder="index === 0 ? mergedConfig.placeholder1 : mergedConfig.placeholder2"
                :value="getValueForIndex(entry, index)"
                @input="updateValueForIndex(entry.id, $event.target.value, index)"
              />
              <textarea
                v-else
                class="form-control"
                :placeholder="index === 0 ? mergedConfig.placeholder1 : mergedConfig.placeholder2"
                :value="getValueForIndex(entry, index)"
                @input="updateValueForIndex(entry.id, $event.target.value, index)"
              ></textarea>
            </template>
          </template>

          <!-- Attachments Input Type -->
          <template v-if="component === 'attachment'">
            <Attachment
              :value="getValueForIndex(entry, index) || []"
              :disabled="printMode"
              :caption="mergedConfig.attachmentCaption"
              :max-attachments="mergedConfig.maxAttachments"
              :max-size="mergedConfig.maxAttachmentsSize"
              :allowed-extensions="mergedConfig.allowedAttachmentsExtensions"
              :image-size="mergedConfig.attachmentImageSize"
              :upload-text="mergedConfig.attachmentUploadText"
              :img-resize="mergedConfig.attachmentImgResize"
              :show-file-names="mergedConfig.attachmentShowFileNames"
              @input="updateValueForIndex(entry.id, $event, index)"
            />
          </template>
        </div>
      </template>
    </div>

    <!-- Total Row -->
    <TableSelection
      v-if="showTotalRow && typeComponents.includes('numeric') && displaySummaryAverage"
      label="Media"
      :typeComponents="typeComponents"
      :gridTemplateStyle="gridTemplateStyle"
      :localValues="localValues"
      :getTotalForIndex="getTotalForIndex"
    />

   <TableSelection
      v-if="showTotalRow && typeComponents.includes('numeric') && displaySummaryCount"
      label="Numarul"
      :typeComponents="typeComponents"
      :gridTemplateStyle="gridTemplateStyle"
      :localValues="localValues"
      :getTotalForIndex="getTotalForIndex">
   </TableSelection>

  <TableSelection
     v-if="showTotalRow && typeComponents.includes('numeric')"
     label="Total"
     :typeComponents="typeComponents"
     :gridTemplateStyle="gridTemplateStyle"
     :localValues="localValues"
    :getTotalForIndex="getTotalForIndex"
  />
  </div>
</template>
<script>
import Attachment from '../files/Attachment.vue';
import TableSelection from './TableSelection.vue';

export default {
  components: {
    Attachment, TableSelection
  },
  props: {
    title: {
      type: String,
      default: '',
    },
    description: {
      type: String,
      default: '',
    },
    type: {
      type: String,
      required: true,
      validator: (value) => {
        // Support base types and combinations (separated by hyphen)
        const baseTypes = ['yes-no', 'numeric', 'text', 'textarea', 'date', 'attachment'];
        if (baseTypes.includes(value)) return true;
        
        // Check if it's a valid combination (e.g., 'numeric-text')
        const parts = value.split('-');
        if (parts.length > 1) {
          // Handle special case for 'yes-no' (counts as one component)
          if (value.includes('yes-no')) {
            const otherParts = parts.filter(p => p !== 'yes' && p !== 'no');
            // Allow 'yes-no' plus one other component at most
            return otherParts.length <= 1 && otherParts.every(part => 
              baseTypes.some(type => type === part || type.includes(part))
            );
          }
          
          // For other combinations, limit to 2 components max
          return parts.length <= 2 && parts.every(part => baseTypes.includes(part));
        }
        
        return false;
      },
    },
    value: {
      type: Array,
      required: true,
      default: () => [],
    },
    config: {
      type: Object,
      default: () => ({}),
    },
    defaultValue1: {
      type: [Boolean, Number, String, Array],
      default: null,
    },
    defaultValue2: {
      type: [Boolean, Number, String, Array],
      default: null,
    },
    showTotalRow: {
      type: Boolean,
      default: true,
    },
    printMode: {
      type: Boolean,
      default: false
    },
    displaySummaryAverage: {
      type: Boolean,
      default: false
    },
    displaySummaryCount: {
      type: Boolean,
      default: false
    },
    allowSort: {
      type: Boolean,
      default: false
    },
  },
  data() {
    return {
      localValues: [],
      sortDirection: 'asc',
      sortByName: false
    };
  },
  mounted() {
    if(this.allowSort){
      this.toggleSort();
      this.sortByName = true;
    }
  },
  computed: {
    typeComponents() {
      // Handle special case for 'yes-no'
      if (this.type === 'yes-no') return ['yes-no'];
      
      // For combined types, split into components (max 2)
      if (this.type.includes('-')) {
        if (this.type.includes('yes-no')) {
          const parts = this.type.split('-');
          const otherParts = parts.filter(p => p !== 'yes' && p !== 'no');
          // 'yes-no' counts as one component
          return ['yes-no', ...otherParts.slice(0, 1)];
        }
        
        // For other combinations, limit to 2 components
        return this.type.split('-').slice(0, 2);
      }
      
      return [this.type];
    },
    mergedConfig() {
      // Create default configuration
      const defaultConfig = {
        // Column titles - one for each column (max 2)
        columnTitle: 'Denumire',
        columnValue1: this.getDefaultColumnValue(this.typeComponents[0]),
        columnValue2: this.typeComponents.length > 1 ? this.getDefaultColumnValue(this.typeComponents[1]) : '',
        
        // Placeholders for each component type (max 2)
        placeholder1: this.getDefaultPlaceholderForType(this.typeComponents[0]),
        placeholder2: this.typeComponents.length > 1 ? this.getDefaultPlaceholderForType(this.typeComponents[1]) : '',
        
        // Yes-No options
        labelYes: 'Da',
        labelNo: 'Nu',
        
        // Attachment settings
        attachmentUploadText: 'Încărcați fișierul',
      };
      
      // Override with user-provided config
      return { ...defaultConfig, ...this.config };
    },
    gridTemplateStyle() {
      const columns = this.typeComponents.length;
      return {
        'grid-template-columns': `3fr ${Array(columns).fill('2fr').join(' ')}`
      };
    },
    sortedValues() {
      if(!this.sortByName) return this.localValues;

      return[...this.localValues].sort((a,b) =>{
        const aName=a.item.title.toLowerCase();
        const bName=b.item.title.toLowerCase();

        if(this.sortDirection === 'asc'){
          return aName.localeCompare(bName);
        }
        else{
          return bName.localeCompare(aName);
        }
      });
    },
  },
  watch: {
    value: {
      deep: true,
      immediate: true,
      handler(newValue) {
        if (JSON.stringify(this.localValues) !== JSON.stringify(newValue)) {
          this.localValues = this.initializeValues(newValue);
        }
      },
    },
  },
  methods: {
    getDefaultPlaceholderForType(type) {
      switch (type) {
        case 'numeric':
          return this.config.placeholderNumeric || 'Valoare';
        case 'date':
          return this.config.placeholderDate || 'Selectați data';
        case 'text':
          return this.config.placeholderText || 'Introduceți textul';
        case 'textarea':
          return this.config.placeholderTextarea || 'Introduceți textul';
        case 'attachment':
          return '';
        case 'yes-no':
          return '';
        default:
          return '';
      }
    },
    getDefaultColumnValue(type) {
      switch (type) {
        case 'yes-no':
          return 'Aprobat';
        case 'numeric':
          return 'Valoare';
        case 'date':
          return 'Data';
        case 'text':
        case 'textarea':
          return 'Text';
        case 'attachment':
          return 'Atașamente';
        default:
          return 'Valoare';
      }
    },
    initializeValues(inputValues) {
      // Initialize values for all component types (max 2)
      const initializedValues = inputValues.map((entry) => {
        const result = { ...entry };
        
        // Initialize primary value if needed
        if (result.value === undefined) {
          result.value = this.getDefaultValueForType(this.typeComponents[0], this.defaultValue1);
        }
        
        // Initialize second value if needed (only if we have 2 components)
        if (this.typeComponents.length > 1 && result.value2 === undefined) {
          result.value2 = this.getDefaultValueForType(this.typeComponents[1], this.defaultValue2);
        }
        
        return result;
      });

      if (JSON.stringify(inputValues) !== JSON.stringify(initializedValues)) {
        this.$emit('input', initializedValues);
      }   

      return initializedValues;
    },
    getDefaultValueForType(type, defaultVal) {
      // Use the provided default value or fall back to null/empty
      const valueToUse = defaultVal !== null ? defaultVal : null;
      
      switch (type) {
        case 'yes-no':
          if (valueToUse !== null && typeof valueToUse === 'boolean') return valueToUse;
          return null;
        case 'numeric':
          // Convert string to number if needed
          if (valueToUse !== null) {
            return typeof valueToUse === 'number' ? valueToUse : 
              (typeof valueToUse === 'string' ? Number(valueToUse) : null);
          }
          return null;
        case 'text':
        case 'textarea':
          return valueToUse !== null && typeof valueToUse === 'string' ? valueToUse : '';
        case 'date':
          return valueToUse !== null && typeof valueToUse === 'string' ? valueToUse : '';
        case 'attachment':
          return valueToUse !== null && Array.isArray(valueToUse) ? valueToUse : [];
        default:
          return valueToUse;
      }
    },
    getValueForIndex(entry, index) {
      // Only support up to 2 values (index 0 and 1)
      if (index === 0) return entry.value;
      if (index === 1) return entry.value2;
      return null;
    },
    updateValueForIndex(id, newValue, index) {
      const updatedValues = this.localValues.map((entry) => {
        if (entry.id !== id) return entry;
        
        const result = { ...entry };
        // Only update value or value2 (max 2 columns)
        if (index === 0) {
          result.value = newValue;
        } else if (index === 1) {
          result.value2 = newValue;
        }
        return result;
      });

      this.localValues = updatedValues;
      this.$emit('input', updatedValues);
    },
    getTotalForIndex(index) {
      // Only calculate totals for value or value2 (max 2 columns)
      const valueProp = index === 0 ? 'value' : 'value2';
      const total = this.localValues.reduce((sum, entry) => {
        return sum + (typeof entry[valueProp] === 'number' ? entry[valueProp] : 0);
      }, 0);
      
      // Format the total if a formatter is provided
      const formattedTotal = this.mergedConfig.numericFormat && typeof this.mergedConfig.numericFormat === 'function' 
        ? this.mergedConfig.numericFormat(total)
        : total;
      
      // Only emit total for the first column
      if (index === 0) {
        this.$emit('total', total);
      }
      
      return formattedTotal;
    },
    toggleSort(){
      if(!this.sortByName){
        this.sortByName = true;
        this.sortDirection = 'asc';
      }
      else{
        this.sortDirection = this.sortDirection === 'asc' ? 'desc' : 'asc' ; 
      }
    },
  },
};
</script>

<style scoped>
.configurable-table {
  width: 100%;
}

.table-row {
  display: grid;
  grid-template-columns: 3fr 2fr;
  align-items: center;
  margin: 4px 0;
  gap: 15px;
}

.column-header {
  font-weight: bold;
}

.table-header {
  font-weight: bold;
  border-bottom: none;
  margin-bottom: 4px;
}

.item-details {
  margin: 0 8px 0 0;
  padding: 0;

  p {
    margin: 0;
    padding: 0;
  }
}

.yes-no-options {
  display: flex;
  gap: 15px;
  margin: 0;
  padding: 0;

  label {
    margin: 0;
    display: flex;
    align-items: center;
    gap: 4px;
  }
}

.budget-input input {
  width: 100%;
  height: 90%;
  max-width: 100px;
  margin: 1px;
  text-align: right;
}

.numeric-input {
  text-align: right;
  max-width: 200px;
}

.numeric-input input {
  text-align: right;
  appearance: textfield;
  max-width: 200px;
}

.numeric-input input::-webkit-inner-spin-button,
.numeric-input input::-webkit-outer-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

.total-row {
  font-weight: bold;
  margin-top: 10px;
}

.total-value {
  display: block;
  text-align: right;
  padding-right: 12px;
}

.budget-input input::-webkit-inner-spin-button,
.budget-input input::-webkit-outer-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

.date-input input {
  width: 100%;
  max-width: 150px;
  height: 90%;
  margin: 1px;
}

.text-input input,
.text-input textarea {
  width: 100%;
  min-width: 100px;
  margin: 0;
  padding: 4px 8px;
}

.print-row:nth-child(even) {
  background-color: #f8f8f8;
}

@media print {
  .configurable-table {
    break-inside: avoid;
  }
  
  .table-row {
    break-inside: avoid;
    padding: 4px 0;
  }
}

.numeric-print {
  display: block;
  text-align: right;
  padding-right: 12px;
}

.attachment-input {
  width: 100%;
  display: flex;
  align-items: center;

  :deep(.form-group.micro-attachment) {
    margin-bottom: 0;
  }
}

</style>