import { GamaPropModel } from '@win2win/shared';
import { groupBy, isArray, isNil, max, orderBy, toPairs } from 'lodash';
import { FieldProps, FieldTypes } from 'src/components/common/FieldsProps.model';

export class ProductPropsMapper {
  summaryGroups: GamaPropModel[][];
  detailGroups: GamaPropModel[][];

  constructor(props: GamaPropModel[] | null, private getLabelFn?: (code: string, rawValue: string | string[]) => string) {
    if (!props) {
      this.summaryGroups = [];
      this.detailGroups = [];
      return;
    }
    const fields = (props || []) as GamaPropModel[];
    this.summaryGroups = this.groupFields(fields.filter((field) => field.visibility?.summary || false));
    this.detailGroups = this.groupFields(fields.filter((field) => field.visibility?.detail || false));
  }

  toFields(layoutType: 'detail' | 'summary'): FieldProps[][] {
    const groups = layoutType === 'detail' ? this.detailGroups : this.summaryGroups;
    return groups.map((group) => {
      return group.map((field) => ({
        label: field.label,
        value: this.getFieldValue(field),
        type: field.controlType === 'checkbox' ? FieldTypes.INDICATOR : FieldTypes.TEXT,
        format: this.getLabelFn ? (value: any) => this.getLabelFn!(field.code, value) : undefined,
      }));
    });
  }

  private groupFields(fields: (GamaPropModel & { group?: number })[]) {
    let maxGroup = max(fields.map((field) => field.group)) || 0;
    const fieldsWithGroup = orderBy(fields, 'group').map((field) => {
      let group = field.group;
      if (isNil(group)) {
        maxGroup++;
        group = maxGroup;
      }
      return {
        ...field,
        group,
      };
    });
    return toPairs(groupBy(fieldsWithGroup, 'group')).map(([_, fields]) => fields);
  }

  private getFieldValue(field: GamaPropModel) {
    if (field.controlType === 'checkbox') {
      return { state: field.value == 'si' ? 1 : 0, labels: ['No', 'Sí'] };
    }
    if (field.controlType === 'select' && field.multiple) {
      return isArray(field.value) ? field.value.join(', ') : field.value || '';
    } else {
      let value = field.value || '';
      if (!value) return '';
      if (field.suffix) {
        value = `${value} ${field.suffix}`;
      }
      return value;
    }
  }
}
