import get from 'lodash/get'
import { FluidStatus, GetRelationshipsReturn, Relation } from 'models'
import { FluidState, FluidType } from '../enum/fluid.enum'
import { KonnectorUpdate } from '../enum/konnectorUpdate.enum'
import { DateTime, Interval } from 'luxon'
import { Season } from 'enum/ecogesture.enum'

export function getFluidType(type: string) {
  switch (type.toUpperCase()) {
    case 'ELECTRICITY':
      return FluidType.ELECTRICITY
    case 'WATER':
      return FluidType.WATER
    case 'GAS':
      return FluidType.GAS
    default:
      return FluidType.ELECTRICITY
  }
}
export function getKonnectorUpdateError(type: string) {
  switch (type.toUpperCase()) {
    case 'USER_ACTION_NEEDED.OAUTH_OUTDATED':
      return KonnectorUpdate.ERROR_UPDATE_OAUTH
    default:
      return KonnectorUpdate.ERROR_UPDATE
  }
}

export function isKonnectorActive(
  fluidStatus: FluidStatus[],
  fluidType: FluidType
): boolean {
  if (fluidType === FluidType.MULTIFLUID) {
    if (
      fluidStatus.filter(
        fluid =>
          fluid.status === FluidState.NOT_CONNECTED ||
          fluid.status === FluidState.ERROR_LOGIN_FAILED ||
          fluid.status === FluidState.KONNECTOR_NOT_FOUND
      ).length === 3
    ) {
      return false
    } else {
      return true
    }
  }
  if (
    fluidStatus[fluidType].status === FluidState.NOT_CONNECTED ||
    fluidStatus[fluidType].status === FluidState.KONNECTOR_NOT_FOUND
  ) {
    return false
  } else return true
}
export function formatNumberValues(
  value: number | null,
  fluidStyle?: string,
  toBeCompared = false
) {
  if (value || value === 0) {
    const localeValue = value.toLocaleString('fr-FR', {
      minimumFractionDigits: 2,
      maximumFractionDigits: 2,
    })
    const noSpaceValue = parseInt(localeValue.replace(/\s/g, ''))
    if (toBeCompared) return noSpaceValue
    if (fluidStyle && noSpaceValue >= 1000) {
      const convertedValue = (noSpaceValue / 1000).toFixed(2).replace('.', ',')
      return convertedValue
    } else return localeValue
  } else {
    return '--,--'
  }
}

/**
 * Get one relation in doc
 *
 * @param {object} doc - DocumentEntity
 * @param {string} relName - Name of the relation
 */
export function getRelationship<D>(doc: D, relName: string): Relation {
  return get(doc, `relationships.${relName}.data`, [])
}

/**
 * Get array of items in one relation in doc
 *
 * @param {object} doc - DocumentEntity
 * @param {string} relName - Name of the relation
 */
export function getRelationshipHasMany<D>(doc: D, relName: string): Relation[] {
  return get(doc, `relationships.${relName}.data`, [])
}

/**
 * Get many relations in doc
 *
 * @param {object} doc - DocumentEntity
 * @param {Array<[relName: string]: Array<Relation>>} relNameList - Array of name of the relations
 */
export function getRelationships<D>(
  doc: D,
  relNameList: Array<string>
): GetRelationshipsReturn {
  return relNameList.map(relName => ({
    [relName]: get(doc, `relationships.${relName}.data`, []),
  }))[0]
}

/**
 *
 * @param id
 * @param pathType
 */
export const importIconbyId = async (id: string, pathType: string) => {
  // Les svg doivent être au format id.svg
  let importedChallengeIcon
  try {
    importedChallengeIcon = await import(
      /* webpackMode: "eager" */ `assets/icons/visu/${pathType}/${id}.svg`
    )
  } catch (e) {}
  if (importedChallengeIcon) {
    return importedChallengeIcon.default
  }
}

/**
 * Return month string according to month index
 * @param date - DateTime
 * @returns month in french
 */
export const getPreviousMonthName = (date: DateTime) => {
  const monthNames = [
    'janiver',
    'février',
    'mars',
    'avril',
    'mai',
    'juin',
    'juillet',
    'août',
    'septembre',
    'octobre',
    'novembre',
    'décembre',
  ]
  return monthNames[date.month - 2]
}

/**
 * Return month string according to month index
 * @param date - DateTime
 * @returns month in french
 */
export const getMonthNameWithPrep = (date: DateTime) => {
  const monthNames = [
    'de janvier',
    'de février',
    'de mars',
    `d'avril`,
    'de mai',
    'de juin',
    'de juillet',
    `d'août`,
    'de septembre',
    `d'octobre`,
    'de novembre',
    'de décembre',
  ]
  return monthNames[date.month - 1]
}

/**
 * Return season according to following rules
 * - Winter is : 1/11/XXXX => 1/3/XXXX
 * - Summer is : 1/6/XXXX => 1/9/XXXX
 * @returns Season
 */
export const getSeason = (): Season => {
  const currentDate: DateTime = DateTime.local().setZone('utc', {
    keepLocalTime: true,
  })
  const currentYear: number = currentDate.year
  const winterStart: DateTime = DateTime.local(currentYear, 11, 1).setZone(
    'utc',
    {
      keepLocalTime: true,
    }
  )
  const winterEnd: DateTime = DateTime.local(currentYear + 1, 3, 1).setZone(
    'utc',
    {
      keepLocalTime: true,
    }
  )

  const summerStart: DateTime = DateTime.local(currentYear, 6, 1).setZone(
    'utc',
    {
      keepLocalTime: true,
    }
  )
  const summerEnd: DateTime = DateTime.local(currentYear, 9, 1).setZone('utc', {
    keepLocalTime: true,
  })
  const summerInterval: Interval = Interval.fromDateTimes(
    summerStart,
    summerEnd
  )
  const winterInterval: Interval = Interval.fromDateTimes(
    winterStart,
    winterEnd
  )

  if (summerInterval.contains(currentDate)) {
    return Season.SUMMER
  } else if (winterInterval.contains(currentDate)) {
    return Season.WINTER
  } else {
    return Season.NONE
  }
}