<template>
  <ExampleStory>
    <TfTable
      :key="propsModel.tableData"
      v-bind="{
        ...propsModel,
        pageLimit: Number(propsModel.pageLimit),
        pageSelected: Number(propsModel.pageSelected),
        customSort: propsModel.customSort ? customSort : null,
        truncatedPageRange: Number(propsModel.truncatedPageRange),
        tableData: propsModel.tableData === 'Empty table'
          ? []
          : [...table.data],
        tableMeta,
      }"
      @changeFilter="onEmit('changeFilter', $event)"
      @changeSortCriteria="onEmit('changeSortCriteria', $event)"
      @pageSelected="onEmit('pageSelected', $event)"
    >
      <TfTableParentRow
        v-if="slotsModel.parentRow"
        slot="parentRow"
        slot-scope="{ isExpanded, columns, rowData }"
        :row-data="rowData"
      >
        <TfTableTd>
          This is a slot that will take the entire row with the following scoped data to the row.
        </TfTableTd>
        <TfTableTd :colspan="1">
          <h3>rowData data</h3>
          <pre><code>{{ rowData }}</code></pre>
        </TfTableTd>
        <TfTableTd :colspan="1">
          <h3>columns data</h3>
          <pre><code>{{ columns }}</code></pre>
        </TfTableTd>
        <TfTableTd>
          <h3>isExpanded data</h3>
          <pre><code>{{ isExpanded }}</code></pre>
        </TfTableTd>
      </TfTableParentRow>
      <template
        v-if="slotsModel.empty"
        #empty
      >
        {{ slotsModel.emptyExample }}
      </template>
      <template
        v-if="slotsModel.emptyCell"
        #emptyCell
      >
        {{ slotsModel.emptyCellExample }}
      </template>
      <div
        v-if="slotsModel.header"
        slot="header"
        class="header-example"
      >
        <h3>Header example</h3>
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Perspiciatis blanditiis, iste quis cumque non vitae voluptas eos exercitationem illo adipisci libero odio esse amet, molestias quos aliquid temporibus eius atque.</p>
      </div>
      <template
        v-if="slotsModel.title"
        #title
      >
        {{ slotsModel.titleExample }}
      </template>
      <TfButton
        v-if="slotsModel.ctaHeader"
        slot="ctaHeader"
        type="primary"
        icon="plus"
        size="text-icon"
      >
        Add new project
      </TfButton>
      <template
        v-if="slotsModel.footer"
        #footer
      >
        {{ slotsModel.footerExample }}
      </template>
      <template
        v-if="slotsModel.error"
        #error
      >
        {{ slotsModel.errorExample }}
      </template>
    </TfTable>
    <template #controls>
      <div>
        <h3>slots:</h3>
        <TfFormBuilder
          v-model="slotsModel"
          v-bind="{
            formItems: slotsFormItems,
            isLoaded: true,
          }"
        />
      </div>
      <div>
        <ElForm label-position="top">
          <h3>Props/Customization</h3>
          <TfFormBuilder
            v-model="propsModel"
            v-bind="{
              formItems: propsFormItems,
              isLoaded: true,
            }"
          />
        </ElForm>
      </div>
      <div>
        <h3>@emits:</h3>
        <div
          v-for="({ name, payload }, index) in emits"
          :key="index"
          class="emit"
        >
          <h4>name: {{ name }}</h4>
          <pre>{{ payload }}</pre>
        </div>
      </div>
    </template>
  </ExampleStory>
</template>

<script>
  import ExampleStory from '@/views/examples/Layouts/Story';
  import { table3 as table } from './data';

  export default {
    name: 'ExampleTableStories',
    components: { ExampleStory },
    data: () => ({
      table,
      emits: [],
      slotsModel: {},
      propsModel: {
        pageSelected: 1,
      },
    }),
    computed: {
      /**
       * Creates the framework for the props form items and if the associated switch is on/off.
       *
       * @returns {Array}
       */
      propsFormItems() {
        return [
          [
            {
              defaultValue: 'With children',
              props: {
                label: 'tableData (prop)',
                placeholder: 'Select table data',
                prop: 'tableData',
                options: [
                  {
                    label: 'Empty table',
                    value: 'Empty table',
                  },
                  {
                    label: 'With children',
                    value: 'With children',
                  },
                ],
                optionKey: 'value',
                optionLabel: 'label',
                type: 'select',
              },
            },
          ],
          [
            {
              defaultValue: true,
              props: {
                label: 'Sort name',
                prop: 'name',
                type: 'switch',
              },
              width: '25%',
            },
            {
              defaultValue: true,
              props: {
                label: 'Sort carrier',
                prop: 'soldCarrier',
                type: 'switch',
              },
              width: '25%',
            },
            {
              defaultValue: false,
              props: {
                label: 'Sort editor',
                prop: 'lastEditor',
                type: 'switch',
              },
              width: '25%',
            },
          ],
          [
            {
              defaultValue: true,
              props: {
                label: 'Targeted sort status (New Policy Sold -> Renewed -> Policy Audit)',
                prop: 'status',
                type: 'switch',
              },
            },
          ],
          [
            {
              defaultValue: false,
              props: {
                label: 'Use Custom Sort (sorts alphabetically starting at the second letter)',
                prop: 'customSort',
                type: 'switch',
              },
            },
          ],
          [
            {
              defaultValue: false,
              props: {
                label: 'pagination',
                prop: 'pagination',
                type: 'switch',
              },
            },
            {
              defaultValue: false,
              props: {
                label: 'showPageResults',
                prop: 'showPageResults',
                type: 'switch',
              },
            },
          ],
          [
            {
              defaultValue: 0,
              props: {
                label: 'truncatedPageRange',
                prop: 'truncatedPageRange',
                type: 'number',
              },
            },
            {
              defaultValue: 50,
              props: {
                disabled: !this.propsModel.pagination,
                label: 'pageLimit',
                min: 1,
                prop: 'pageLimit',
                type: 'number',
              },
            },
          ],
        ];
      },
      /**
       * Creates the framework for the slots form item and if the associated switch is on/off.
       *
       * @returns {Array}
       */
      slotsFormItems() {
        return [
          [
            {
              defaultValue: false,
              props: {
                label: '#error',
                prop: 'error',
                type: 'switch',
              },
              width: '20%',
            },
            {
              defaultValue: 'Lorem ipsum, dolor sit amet consectetur adipisicing, elit. Fugiat ut rem repudiandae recusandae nisi, quam ipsa libero, officiis quod error, tempora temporibus quia sequi? Quam repellendus beatae vel, quibusdam facere.',
              props: {
                disabled: !this.slotsModel.error,
                label: 'Value',
                prop: 'errorExample',
                type: 'text',
              },
            },
          ],
          [
            {
              defaultValue: false,
              props: {
                label: '#empty',
                prop: 'empty',
                type: 'switch',
              },
              width: '20%',
            },
            {
              defaultValue: 'Lorem ipsum, dolor sit amet consectetur adipisicing, elit. Fugiat ut rem repudiandae recusandae nisi, quam ipsa libero, officiis quod error, tempora temporibus quia sequi? Quam repellendus beatae vel, quibusdam facere.',
              props: {
                disabled: !this.slotsModel.empty,
                label: 'Value',
                prop: 'emptyExample',
                type: 'text',
              },
            },
          ],
          [
            {
              defaultValue: false,
              props: {
                label: '#emptyCell',
                prop: 'emptyCell',
                type: 'switch',
              },
              width: '20%',
            },
            {
              defaultValue: '???',
              props: {
                disabled: !this.slotsModel.emptyCell,
                label: 'Value',
                prop: 'emptyCellExample',
                type: 'text',
              },
            },
          ],
          [
            {
              defaultValue: false,
              props: {
                label: '#header',
                prop: 'header',
                type: 'switch',
              },
              width: '20%',
            },
          ],
          [
            {
              defaultValue: false,
              props: {
                label: '#title',
                prop: 'title',
                type: 'switch',
              },
              width: '20%',
            },
            {
              defaultValue: 'Example title',
              props: {
                disabled: !this.slotsModel.title,
                label: 'Value',
                prop: 'titleExample',
                type: 'text',
              },
            },
          ],
          [
            {
              defaultValue: false,
              props: {
                label: '#ctaHeader',
                prop: 'ctaHeader',
                type: 'switch',
              },
            },
          ],
          [
            {
              defaultValue: false,
              props: {
                label: '#footer',
                prop: 'footer',
                type: 'switch',
              },
              width: '20%',
            },
            {
              defaultValue: 'Example footer',
              props: {
                disabled: !this.slotsModel.footer,
                label: 'Value',
                prop: 'footerExample',
                type: 'text',
              },
            },
          ],
          [
            {
              defaultValue: false,
              props: {
                label: '#parentRow',
                prop: 'parentRow',
                type: 'switch',
              },
              width: '20%',
            },
          ],
        ];
      },
      /**
       * Creates the tableMeta based on the table data and strips out the sorting.
       *
       * @returns {object}
       */
      tableMeta() {
        return {
          childColumns: this.table.meta.childColumns,
          columns: this.table.meta.columns.map((column) => ({
            ...column,
            format: null,
            sortable: column.prop === 'status' && this.propsModel.status
              ? 'orderStatus'
              : this.propsModel[column.prop],
          })),
        };
      },
    },
    watch: {
      'propsModel.pageLimit': {
        /**
         * Reset the page selected when changing the page limit prop.
         */
        handler() {
          this.propsModel.pageSelected = 1;
        },
      },
    },
    created() {
      this.slotsFormItems.forEach((formItems) => {
        formItems.forEach(({ defaultValue, props }) => {
          this.$set(this.slotsModel, [props.prop], defaultValue);
        });
      });

      this.propsFormItems.forEach((formItems) => {
        formItems.forEach(({ defaultValue, props }) => {
          this.$set(this.propsModel, [props.prop], defaultValue);
        });
      });
    },
    methods: {
      /**
       * Updates the `payloads.emitted` object to the latest payload for display only purposes.
       *
       * @param {string} name
       * @param {object} payload
       */
      onEmit(name, payload) {
        this.emits.unshift({ name, payload });

        if (name === 'pageSelected') {
          this.propsModel.pageSelected = payload;
        }
      },
      /**
       * Custom sort function that sorts alphabetically starting at the second character.
       * This is used to demonstrate the customSort prop.
       * Sorts numbers regularly.
       *
       * @param {Array} data - The data to sort.
       * @param {string} prop - The property to sort by.
       * @param {string} order - The order to sort in.
       * @returns {Array} A new array of the sorted data.
       */
      customSort(data, prop, order) {
        return data.sort((a, b) => {
          const aValue = a[prop];
          const bValue = b[prop];

          if (typeof aValue === 'number' && typeof bValue === 'number') {
            return order === 'asc'
              ? aValue - bValue
              : bValue - aValue;
          }

          if (typeof aValue === 'string' && typeof bValue === 'string') {
            const newA = aValue.slice(1).toLowerCase();
            const newB = bValue.slice(1).toLowerCase();

            if (newA < newB) {
              return order === 'asc'
                ? -1
                : 1;
            }

            if (newA > newB) {
              return order === 'asc'
                ? 1
                : -1;
            }
          }

          return 0;
        });
      },
    },
  };
</script>

<style lang="scss" scoped>
  @import 'src/assets/styles/variables';

  .emit {
    padding: 10px 0;
    border-bottom: 1px solid $tf-extra-light-gray-1;
  }

  .el-checkbox + .el-checkbox {
    margin-left: 0;
  }

  .header-example {
    display: block;
  }
</style>
