import { deserializeWithContext, isSerializedFunction } from '@win2win/shared';
import { isNil, last } from 'lodash';
import { QTableColumn } from 'quasar';
import { ColumnsConfig } from 'src/layouts/w2w-toolbar/W2WToolbarConfig';
import { LayoutView } from 'src/models';
import { computed, ComputedRef, ref, watch } from 'vue';
import { contextFunctions } from '../../helpers';
import { DynamicTableCustomConfig, DynamicTableViewsRefs } from '../../models';
import { useContextParams } from './useContextParams';

export function useColumns(refs: ComputedRef<DynamicTableViewsRefs>) {
  const counters = computed(() => (refs.value.customConfig?.layout?.hideStats ? null : refs.value.layout.states || {})?.['items'] || []);
  const { isVisible, contextParams } = useContextParams();

  const getDefaultCounterColor = (item: { COLOR?: string; VALUE?: number | string }) => {
    if (item?.COLOR) {
      return item?.COLOR;
    }
    if (isNil(item?.VALUE)) {
      return 'grey';
    }
    return counters.value.find((counter) => counter.value == item.VALUE)?.color || 'grey';
  };

  const getDefaultCounterLabel = (item: { NAME?: string; VALUE?: number | string }) => {
    if (item?.NAME) {
      return item?.NAME;
    }
    if (isNil(item?.VALUE)) {
      return 'Sin definir';
    }
    return counters.value.find((counter) => counter.value == item.VALUE)?.label || 'Sin definir';
  };

  const availableColumns = computed(() => {
    const layout = refs.value.layout as LayoutView;
    const customConfig = refs.value.customConfig as DynamicTableCustomConfig | undefined;
    const allColumnsNames = layout.columns?.filter((col) => isVisible(col.visibilityFn)).map((col) => col.name) || [];
    const availableColumnsNames = customConfig?.columns?.availableColumns?.length ? customConfig.columns.availableColumns : allColumnsNames;
    return layout.columns?.filter((col) => availableColumnsNames.includes(col.name)) || [];
  });

  const rowActions = computed(() =>
    (refs.value.layout.rowActions || []).map((action) => {
      const visibleFn = action.visibility ? deserializeWithContext(action.visibility, contextParams.value) : () => true;
      const disabledFn = action.disabled ? deserializeWithContext(action.disabled, contextParams.value) : () => false;
      return {
        ...action,
        visibleFn,
        disabledFn,
      };
    })
  );

  const columns = computed(() => availableColumns.value.map((col) => ({ ...col, field: isSerializedFunction(col.field) ? deserializeWithContext(col.field, contextFunctions) : col.field })));
  const visibleColumns = ref<string[]>([]);
  const indicatorColumns = computed(() => columns.value.filter((col) => col.type === 'indicator'));
  const linkColumns = computed(() => columns.value.filter((col) => col.type === 'link'));
  const columnsConfig = computed<ColumnsConfig>(() => ({ editable: true, columns: columns.value }));

  watch(
    columns,
    (value) => {
      visibleColumns.value = value.map((col) => col.name);
    },
    { immediate: true }
  );

  const lastColumnFixed = computed(() => {
    return last(columns.value)?.name === 'ACTIONS' && visibleColumns.value.includes('ACTIONS');
  });

  return {
    columns: columns as ComputedRef<QTableColumn[]>,
    visibleColumns,
    indicatorColumns,
    linkColumns,
    getDefaultCounterColor,
    getDefaultCounterLabel,
    columnsConfig,
    rowActions,
    lastColumnFixed,
  };
}
