import {
  CITY_TO_ID_MAP,
  EXTRA_FIELD_NAME,
  EXTRA_FIELD_TYPE,
} from 'src/constants/events';

import { type LokaliseTFunction } from './i18n';
import { getFullName } from './userUtils';

export const getUserSide = segmentationData => {
  const foundElem = segmentationData.find(
    elem => CITY_TO_ID_MAP[elem.item.name],
  );
  return foundElem ? CITY_TO_ID_MAP[foundElem.item.name] : null;
};

const getValueByKey = (obj, key) => {
  switch (key) {
    case 'name':
      return obj.Name.toLowerCase();
    case 'eventDate':
    case 'registrationStart':
      return new Date(obj[key]);
    case 'availability':
      return obj.Availability;
    default:
      return obj.name.toLowerCase();
  }
};

export const sortEventsArray = (events, orderBy, order) => {
  return [...events].sort((a, b) => {
    let valueA = getValueByKey(a, orderBy);
    let valueB = getValueByKey(b, orderBy);

    if (valueA < valueB) {
      return order === 'ASC' ? -1 : 1;
    }
    if (valueA > valueB) {
      return order === 'ASC' ? 1 : -1;
    }
    return 0;
  });
};

export const filterByDate = (events, startDate, endDate) => {
  return events.filter(event => {
    const eventDate = new Date(event.EventDate);
    if (startDate && endDate) {
      return eventDate >= new Date(startDate) && eventDate <= new Date(endDate);
    }
    if (startDate) return eventDate >= new Date(startDate);
    if (endDate) return eventDate <= new Date(endDate);
    return true;
  });
};

export const filterByCapacity = (events, min, max) => {
  return events.filter(event => {
    if (min && max)
      return event.Availability >= min && event.Availability <= max;
    if (min) return event.Availability >= min;
    if (max) return event.Availability <= max;
    return true;
  });
};

export const hasTshirt = data =>
  data?.some(
    item =>
      item.FieldType === EXTRA_FIELD_TYPE.RULE &&
      (item.FieldName === EXTRA_FIELD_NAME.TEAM_SIZE ||
        item.FieldName === EXTRA_FIELD_NAME.GUEST_SIZE),
  );

export const hasRelativeInfo = data =>
  data?.some(
    item =>
      item.FieldType === EXTRA_FIELD_TYPE.RULE &&
      item.FieldName === EXTRA_FIELD_NAME.RELATIVES,
  );

export const hasTeamInfo = data =>
  data?.some(
    item =>
      item.FieldType === EXTRA_FIELD_TYPE.TABLE &&
      item.FieldName === EXTRA_FIELD_NAME.TEAM,
  );

export const validateRelativesInfo = (selectedRelatives, isTshirt) => {
  const hasAllSizesSelected = selectedRelatives.every(
    relative => relative.TshirtSize !== null,
  );

  if (!hasAllSizesSelected && isTshirt) {
    return 'RELATIVES_TSHIRTS_VALIDATION';
  }

  return null;
};

export const validateTeamInfo = (selectedUsers, isTshirt) => {
  const hasAllSizesSelected = selectedUsers.every(
    user => user.TshirtSize !== null,
  );

  if (!hasAllSizesSelected && isTshirt) {
    return 'TEAM_TSHIRTS_VALIDATION';
  }

  return null;
};

export const processExtraFields = (data: any, statusCode) => {
  const extraFieldsValues = {
    extrafields: [],
  };

  Object.entries(data)
    .filter(([key]) => key !== 'guestsNumber')
    .forEach(([key, value]) => {
      const field = `{ "EventExtraFieldId": ${key}, "Value": "${value}" }`;
      extraFieldsValues.extrafields.push(field);
    });

  return statusCode ? '' : JSON.stringify(extraFieldsValues);
};

export const processArray = (arr: any[]) =>
  arr.map(item => JSON.stringify(item));

export const userExistsInSelected = (employeeId, selectedUsers) =>
  selectedUsers.some(user => user.EmployeeNumber === employeeId);

export const getUserToAdd = ({
  FirstName,
  LastName,
  PersonIdExternal,
  Age,
}) => ({
  EmployeeName: `${FirstName} ${LastName}`,
  EmployeeNumber: PersonIdExternal,
  Age,
  TshirtSize: null,
  TshirtSizeDisplay: null,
});

export const updateTshirtSizeInList = (
  list,
  personData,
  sizeValue,
  dropdown,
) => {
  const displayValue = dropdown.find(
    option => option.FieldsCatalogueId === sizeValue,
  )?.FieldOption;

  const updatedList = [...list];
  const personIndex = updatedList.findIndex(
    person =>
      person.FirstName === personData.FirstName &&
      person.LastName === personData.LastName &&
      person.Age === personData.Age,
  );

  if (personIndex !== -1) {
    updatedList[personIndex].TshirtSize = sizeValue;
    updatedList[personIndex].TshirtSizeDisplay = displayValue;
  }

  return updatedList;
};

export const getDefaultValues = formExtraFields => {
  const baseDefaults = {
    guestsNumber: '',
  };

  if (!formExtraFields?.data?.StatusCode) {
    const extraFields = formExtraFields?.data?.reduce((acc, field) => {
      acc[field.EventExtraFieldId] = '';
      return acc;
    }, {});

    return { ...baseDefaults, ...extraFields };
  }

  return baseDefaults;
};

export const formatOrganizersText = (
  organizers: { firstName: string; lastName: string }[],
  totalCount: number,
  t: LokaliseTFunction,
): string => {
  if (!organizers.length || totalCount === 0) return '';

  const firstOrganizerName = getFullName(organizers[0]);

  if (totalCount === 1) {
    return firstOrganizerName;
  }

  if (totalCount === 2) {
    const secondOrganizerName = getFullName(organizers[1]);
    return `${firstOrganizerName} ${t('and')} ${secondOrganizerName}`;
  }

  const secondOrganizerName = getFullName(organizers[1]);
  const remainingCount = totalCount - 2;
  return `${firstOrganizerName}, ${secondOrganizerName} ${t('and')} ${t('more_collaborators', { count: remainingCount })}`;
};
