import React from 'react'
import Fuse from 'fuse.js'
import {MdThumbDown, MdEmail, MdClear, MdGroup} from 'react-icons/lib/md'
import InstantJob from 'components/instant_job'
import {Blacklist, Whitelist} from 'components/popovers/blacklist'
import request from 'common/request'
import store from 'common/store'
import moment from 'common/moment'
import {color} from 'common/constants'
import {
  make_memoized, array_from_set, empty_object, map_hash, create_hash, human_plural,
} from 'common/utilities'
import {alert_info, alert_success, show_popover, dismiss_popover} from 'actions/display'
import {update_users, update_user, set_current_recipient} from 'actions/users'

export const new_users_fuse = () => {
  let fuses = ["first_name", "last_name", "email"].map((field) => new Fuse([], {
    keys: [field],
    include: ["score"],
    id: "id",
    threshold: 0.2,
  }))
  return {
    set: (users) => {
      fuses.forEach((fuse) => fuse.set(users))
    },
    search: (query) => {
      let querys = query.split(" ").filter(Boolean)
      let scores = {}
      fuses.forEach((fuse) => querys.forEach((query) => {
        let results = fuse.search(query)
        let results_count = results.length
        results.forEach((result) => {
          let item = result.item
          if (!scores[item]) {
            scores[item] = 0
          }
          scores[item] += (1 - result.score) / results_count
        })
      }))
      let r = array_from_set(scores).sort((a, b) => scores[b] - scores[a])
      return r
    },
  }
}

const email_validation = /^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/

export const is_valid_email = (email) => email_validation.test(email)

export function action_invite_users(users) {
  return request.asynchronous("users/import", {users})
  .then((categories) => {
    let agency_name = store.getState().profile.agency.name
    if (categories.already_existing.length > 0) {
      store.dispatch(alert_info(human_plural(categories.already_existing.length, "%% candidat était déjà présent dans notre base de donnée et a reçu votre invitation directement dans son application.", "%% candidats étaient déjà présents dans notre base de donnée et ont reçu votre invitation directement dans leur application.")))
    }
    if (categories.already_invited.length > 0) {
      store.dispatch(alert_info(`${human_plural(categories.already_invited.length, "%% candidat avait déjà été invité", "%% candidats avaient déjà été invités")} à rejoindre ${agency_name}.`))
    }
    if (categories.already_added.length > 0) {
      store.dispatch(alert_info(`${human_plural(categories.already_added.length, `%% candidat avait déjà rejoint ${agency_name}. Nous ne lui`, `%% candidats avaient déjà rejoint ${agency_name}. Nous ne leur`)} avons pas renvoyé de mail d'invitation.`))
    }
    if (categories.newly_invited.length > 0) {
      store.dispatch(alert_success(`${human_plural(categories.newly_invited.length, "%% nouveau candidat a reçu", "%% nouveaux candidats ont reçu")} un mail d'invitation à installer l'application InstantJob.`))
    }

    [
      "already_added",
      "already_invited",
      "already_existing",
      "newly_invited",
    ].map((group) => {
      users = categories[group].map((user) => ({...user, active: true}))
      store.dispatch(update_users(users))
    })

  })
}

export function make_user_status(status) {
  let user_status = make_user_statuses()[status]
  return {
    status,
    description: user_status.name,
    icon: user_status.icon,
  }
}

export function get_user_status(user) {
  if (!user || empty_object(user)) {
    return {status: 'nonexistent', description: '', icon: null}
  }
  function get_status_name() {
    let {blacklisted_at, invitation_accepted_at, app_name, active, invitation_rejected_at, invitation_sent_at, temporary} = user
    if (blacklisted_at) {
      return 'blacklisted'
    }
    if (invitation_accepted_at) {
      if (app_name) {
        if (active) {
          return 'active'
        } else {
          return 'inactive'
        }
      } else {
        return 'mail'
      }
    } else {
      if (invitation_rejected_at) {
        return 'rejected'
      } else {
        if (invitation_sent_at) {
          // return 'pending'
          return 'mail'
        } else {
          if (temporary) {
            return
          } else {
            return 'applied'
          }
        }
      }
    }
  }
  return make_user_status(get_status_name())
}

export function make_user_statuses(custom_color = "") {
  const make_user_statuses_elements = make_memoized((custom_color) => {
    const make_color = ({name, tone}) => color(custom_color || name, tone)
    const icon_colors = map_hash({
      active: {name: 'primary'},
      mail: {name: 'primary', tone: 'light'},
      pending: {name: 'attention'},
      rejected: {name: 'important'},
      inactive: {name: 'black', tone: 'light'},
      blacklisted: {name: 'black'},
      invited: {name: 'black'},
      applied: {name: 'primary'},
      new: {name: 'action'},
    }, make_color)
    const names = {
      active: 'Actif sur l\'application',
      mail: 'Connecté par mail',
      pending: 'Invitation en attente',
      rejected: 'Invitation refusée',
      inactive: 'Inactif',
      blacklisted: 'Blacklisté',
      invited: 'Invitation envoyée',
      applied: 'Candidat',
      new: 'Pas encore importé',
    }
    const get_style_props = (status) => ({style: {color: icon_colors[status]}})
    const icons = create_hash(Object.keys(icon_colors), (status) => {
      let props = get_style_props(status)
      switch (status) {
        case 'active':
          return <div {...props}><InstantJob/></div>
        case 'mail':
          return <MdEmail {...props} />
        case 'pending':
          return <span {...props}>{"?"}</span>
        case 'rejected':
          return <MdClear {...props} />
        case 'inactive':
          return <div {...props}><InstantJob/></div>
        case 'blacklisted':
          return <MdThumbDown {...props} />
        case 'invited':
          return <MdGroup {...props} />
        case 'applied':
          return <div {...props}><InstantJob /></div>
        case 'new':
          return null
      }
    })
    return create_hash(Object.keys(names), (status) => ({
      name: names[status],
      icon_color: icon_colors[status],
      icon: icons[status],
    }))
  })
  return make_user_statuses_elements(custom_color)
}

export const user_full_name = ({first_name, last_name, email}) => `${first_name || ""} ${last_name || ""}`.trim() || email

export function action_update_user(user) {
  store.dispatch(update_user(user))
  request.put(`users/${user.id}`, {user})
}

export function action_toggle_blacklist_user(user) {
  const {blacklisted_at, id} = user
  store.dispatch(show_popover(
    blacklisted_at ? Whitelist : Blacklist,
    {
      id,
      on_dismiss: () => {
        const action = blacklisted_at ? 'whitelist' : 'blacklist'
        request.put(`users/${id}/${action}`)
        store.dispatch(update_user({id, blacklisted_at: blacklisted_at ? null : moment()}))
        store.dispatch(dismiss_popover())
      }
    },
    blacklisted_at ? 'Re-intégrer' : 'Blacklister',
  ))
}

export function action_open_chat({id}) {
  store.dispatch(set_current_recipient(id))
}
