<template>
  <div v-if="!loading">
    <div v-for="(fieldset, index) in row_custom_field" :key="index">
      <h2>{{fieldset.node.field_set_name}}</h2>
      <div class="row">
        <div v-for="column in 2" :key="column" class="col-sm-6">
          <div v-for="(fieldset_field, index_field) in filterColumn(fieldset.node.field_set.edges, column-1)" :key="index_field" class="row">
            <label v-if="fieldset_field.node.field_type !== 'boolean'" class="col-form-label col-sm-3 text-capitalize">
              {{fieldset_field.node.field_name}}
              <em v-if="fieldset_field.mandatory_flag" class="text-danger">*</em>
            </label>
            <div v-if="fieldsModel[fieldset_field.node.identifier]" class="col-sm-9" :class="{'offset-3': fieldset_field.node.field_type == 'boolean'}">
              <div v-if="fieldset_field.node.field_type == 'boolean'" class="form-check form-switch">
                <input :id="'custom_field_'+fieldset_field.node.identifier"
                       v-model="fieldsModel[fieldset_field.node.identifier].value"
                       :checked="fieldsModel[fieldset_field.node.identifier].value"
                       type="checkbox"
                       class="form-check-input"
                       :value="true">
                <label class="form-check-label" :for="'custom_field_'+fieldset_field.node.identifier">{{fieldset_field.node.field_name}}</label>
              </div>
              <VeeField v-else-if="fieldset_field.node.field_type == 'picklist'" v-slot="{ field, value, errorMessage, handleInput}" v-model="fieldsModel[fieldset_field.node.identifier].value" :name="'custom_field_'+fieldset_field.node.identifier" :label="fieldset_field.node.field_name" :rules="{required: fieldset_field.node.mandatory_flag}">
                <SmartSelect
                  v-tooltip:top="errorMessage"
                  v-bind="field"
                  :model-value="value"
                  :class="{'is-invalid':errorMessage}"
                  :options="picklistValues(fieldset_field.node.picklist_source)"
                  id-index="0"
                  description-index="0"
                  @update:modelValue="handleInput($event);"/>
              </VeeField>
              <VeeField v-else v-slot="{ field, errorMessage}" v-model="fieldsModel[fieldset_field.node.identifier].value" :name="'custom_field_'+fieldset_field.node.identifier" :label="fieldset_field.node.field_name" :rules="getRule(fieldset_field)">
                <input
                  v-tooltip:top="errorMessage"
                  :type="(fieldset_field.node.field_type=='date' ? 'date' : 'input')"
                  class="form-control form-control-sm"
                  v-bind="field"
                  :class="{'is-invalid':errorMessage}"
                  @update:modelValue="$emit('update:modelValue', fieldDataRow)">
              </VeeField>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
  <div v-else-if="loading" class="dot-flashing" role="status" />
</template>

<script>

import { Field as VeeField } from 'vee-validate'
import { ref } from 'vue'
import gql from 'graphql-tag'
import { useQuery, useResult } from '@vue/apollo-composable'

import SmartSelect from '@/components/SmartSelect'

export default {
  props: {
    module: {
      type: String,
      required: true
    },
    refId: {
      type: String,
      required: false,
      default: null
    },
    modelValue:{
      type: Object,
      required:false,
      default: null
    }
  },
  setup: function(props, {emit}){

    // return fieldset_field where column is a specific position
    const filterColumn = (data, pos) => (data.filter(function(fieldset_field){
      return fieldset_field.node.column_no == pos
    }))

    // query to get the custom fields definition
    const queryField = gql`query get_CustomFieldList( $module: String! ) {
      fieldset_set (filters: [{and_filters: [{field: "module", qs: $module}]}]) {
        edges {
          node {
            id
            module
            field_set_name
            system_flag
            position
            collapsed
            field_set {
              edges {
                node {
                  id
                  field_name
                  field_type
                  mandatory_flag
                  field_length
                  column_no
                  row_no
                  active_flag
                  default_value
                  db_column
                  decimals
                  picklist_source
                  relation_module
                  internal_desc
                  identifier
                  module
                  regex
                }
              }
            }
          }
        }
      }
    }`

    const { result, loading, onResult } = useQuery( queryField, () => ({ module: props.module + (props.refId != null ? props.refId : '') }), () => ({ fetchPolicy: 'no-cache' }) )
    const row_custom_field = useResult( result, {}, data => data.fieldset_set.edges )
    const fieldsModel = ref({})

    let fieldDataRow = props.modelValue
    if(!fieldDataRow){
      fieldDataRow = {field_data_value_set: []}
      emit('update:modelValue', fieldDataRow)
    }




    onResult(queryResult => {
      // set the values based on the row we receive
      if(fieldDataRow && fieldDataRow.field_data_value_set != null && Array.isArray(fieldDataRow.field_data_value_set)){
        fieldDataRow.field_data_value_set.forEach(function(item){
          fieldsModel.value[item.field.identifier] = item
        })
      }

      // initialize the missing values based on the custom fieldset_field definition
      queryResult.data.fieldset_set.edges.forEach(function(fieldset){
        fieldset.node.field_set.edges.forEach(function(fieldset_field){
          if(fieldsModel.value[fieldset_field.node.identifier] == undefined){
            const data = {value: fieldDataRow && fieldDataRow.id ? null : fieldset_field.node.default_value, field: {id: fieldset_field.node.id, identifier: fieldset_field.node.identifier}}
            fieldDataRow.field_data_value_set.push(data)
            fieldsModel.value[fieldset_field.node.identifier] = data
          }
        })
      })
    })

    return { row_custom_field, loading, filterColumn, fieldsModel }
  },
  methods:{
    picklistValues: function(data){
      const output = []

      data.split(',').forEach(function(item){
        output.push([item])
      })

      return output
    },
    getRule: function(field){
      const rule = {
        required: field.node.mandatory_flag,
        email: field.node.field_type == 'email'
      }

      if(['currency', 'numeric', 'percentage'].includes(field.node.field_type)){
        rule['decimals'] = field.node.decimals
        rule['max_value'] = '9'.repeat(field.node.field_length) + (field.node.decimals > 0 ? '.'+'9'.repeat(field.node.decimals) : '')
        rule['min_value'] = rule['max_value'] * -1
      }

      if(['string'].includes(field.node.field_type)){
        rule['max'] = field.node.field_length
      }

      return rule
    }

  },
  components: {VeeField, SmartSelect},
  emits: ['update:modelValue']
}
</script>
