import React, {Component} from 'react'
import classNames from 'classnames/bind'
import {connect} from 'react-redux'
import {browserHistory} from 'react-router'
import styled from 'styled-components'
import {MdFlag, MdAddCircle, MdFileDownload, MdEdit, MdDone, MdDoneAll, MdSend} from 'react-icons/lib/md'
import FilterableList from 'components/filterable_list/filterable_list'
import {get_filter_on_click} from 'components/filterable_list/make_filter_maker_from_field'
import Button from 'components/utils/button'
import Tag from 'components/utils/tag'
import MissionStatus from 'components/mission_status/mission_status'
import persistent_state from 'common/persistent_state'
import {set_from_array, property_getter, set_count, set_intersection} from 'common/utilities'
import auto_bind from 'common/auto_bind'
import request from 'common/request'
import store from 'common/store'
import moment from 'common/moment'
import {
  get_mission_status_elements, mission_period, action_create_deal, action_cancel_drafts,
} from 'common/missions'
import {action_export_field} from 'common/fields'
import {link} from 'common/styles'
import {dismiss_popover, show_popover} from 'actions/display'
import {get_missions_filter_fields, get_exports_fields} from 'selectors/fields'
import {get_initially_selected_recruiters} from 'selectors/missions'
import {get_recruiters} from 'selectors/recruiters'

const cx = classNames.bind(require('styles/filterable_table.scss'))

export const get_initial_state = (props) => ({
  exclusive_filters: {
    status: set_from_array(['draft', 'sent', 'pending_assignement', 'pending_selection', 'assigned']),
    recruiter: set_from_array(props.initially_selected_recruiters),
  },
  order_by({status}) {
    return get_mission_status_elements(status).priority
  },
  loading_export_missions: {},
  ascending: true,
})

export function get_filters_and_deals({deals, fields, workplaces, recruiters, state, setState}) {
  const status_filter_maker = FilterableList.make_filter_maker_from_field({
    id: 'status',
    name: 'Statut',
    category: 'exclusive',
    value_ids: ['draft', 'pending_selection', 'pending_assignement', 'sent', 'assigned'],
    get_value_props(status, selected = false) {
      const {name, icon} = get_mission_status_elements(status) || {}
      return {
        id: status,
        name: (
          <Tag icon={icon}>
            {name}
          </Tag>
        ),
      }
    },
    get_item_values({status}) {
      return [status]
    },
  })
  const initial_make_status_filter_props = status_filter_maker.make_filter_props
  status_filter_maker.make_filter_props = (args) => ({
    ...initial_make_status_filter_props(args),
    onClick: get_filter_on_click('status', args.setState, ({status}) => {
      return get_mission_status_elements(status).priority
    })
  })
  const workplace_filter_maker = FilterableList.make_filter_maker_from_field({
    id: 'workplace',
    category: 'exclusive',
    name: 'Lieu de travail',
    value_ids: Object.keys(workplaces),
    tolerant: true,
    get_value_props(id) {
      return workplaces[id]
    },
    get_item_values({workplace_ids}) {
      return workplace_ids || []
    },
  })
  const recruiter_filter_maker = FilterableList.make_filter_maker_from_field({
    id: 'recruiter',
    category: 'exclusive',
    name: 'Recruteur',
    value_ids: Object.keys(recruiters),
    get_value_props(id) {
      const recruiter = recruiters[id] || {}
      return {...recruiter, name: recruiter.full_name}
    },
    get_item_values({recruiter}) {
      return [recruiter.id]
    },
  })
  const filter_makers = [
    status_filter_maker,
    workplace_filter_maker,
    recruiter_filter_maker,
    ...[
      {id: 'created_at', category: 'date', name: 'Date de création', get_item_value: property_getter('created_at')},
      {id: 'start', category: 'date', name: 'Date de début', get_item_value: property_getter('start')},
      {id: 'end', category: 'date', name: 'Date de fin', get_item_value: property_getter('end')},
    ].map(FilterableList.make_filter_maker_from_field),
    ...fields.map(FilterableList.make_filter_maker_from_field).filter(Boolean)
  ]

  return {
    filters: FilterableList.get_filters(filter_makers, deals, state, setState),
    deals: FilterableList.get_filtered_items(
      filter_makers,
      deals,
      state,
    ),
  }
}

class DealsList extends Component {
  constructor(props) {
    super(props)
    this.state = persistent_state.get(props.persistent_state_key, {
      ...FilterableList.initial_state,
      ...get_initial_state(props),
    })
    auto_bind(this)
  }

  componentWillUnmount() {
    persistent_state.store(this.props.persistent_state_key, this.state)
  }

  set_state(arg) {
    this.setState(arg)
  }

  get_filters_and_deals() {
    const {deals, fields, workplaces, recruiters} = this.props
    return get_filters_and_deals({deals, fields, workplaces, recruiters, state: this.state, setState: this.set_state})
  }

  get_statistics({users_count, waiting_count, accepted_count, assigned_count, empty_count, status}) {
    const assigned = {count: assigned_count, icon: <MdDoneAll />}
    switch (status) {
      case 'draft':
        return [{count: users_count, icon: <MdEdit />}]
      case 'pending_assignement':
      case 'sent':
        return [
          {count: accepted_count, icon: <MdDone />},
          {count: waiting_count, icon: "?"},
          assigned,
        ]
      case 'pending_selection':
        return [
          {count: empty_count, icon: <MdSend />},
          assigned,
        ]
      case 'assigned':
        return [assigned]
      default:

    }
  }

  get_selected_count(selected_deal_ids) {
    return set_count(set_intersection(selected_deal_ids, set_from_array(this.props.deals.map(property_getter('id')))))
  }

  render_deal({id, workplace, recruiter, created_at, ...deal}) {
    workplace = workplace || {}
    return (
      <Deal onClick={() => browserHistory.push(`/deals/${id}`)}>
        <MissionStatus simple {...deal} />
        <Information>
          <Top>
            <Workplace>
              <WorkplaceName>
                {workplace.name}
              </WorkplaceName>
              <WorkplaceAddress>
                {workplace.address}
              </WorkplaceAddress>
            </Workplace>
            <Statistics>
              {this.get_statistics(deal).filter(property_getter('count')).map(({count, icon}, index) => (
                <Statistic key={index}>
                  {count}
                  <StatisticIcon>
                    {icon}
                  </StatisticIcon>
                </Statistic>
              ))}
            </Statistics>
          </Top>
          <Bottom>
            <Period>
              {mission_period(deal)}
            </Period>
            <Creation>
              Créée {moment(created_at).calendar().toLowerCase()} par {recruiter.full_name}
            </Creation>
          </Bottom>
        </Information>
      </Deal>
    )
  }

  make_export_action({name, id}) {
    return ({length}) => ({
      onClick: (deal_ids, unselect_deals) => {
        unselect_deals()
        this.setState({loading_export_missions: {[id]: true}})
        action_export_field(id, deal_ids)
        .then(() => this.setState({loading_export_missions: {[id]: false}}))
      },
      label: `Exporter ${name} pour les missions sélectionnées`,
      loading: this.state.loading_export_missions[id],
      disabled: !length,
    })
  }

  render() {
    const {export_fields} = this.props
    const {filters, deals} = this.get_filters_and_deals()
    return (
      <FilterableList
        icon={MdFlag}
        empty_text={"Aucune mission"}
        filters={filters}
        secondary_actions={[
          ({length}) => ({onClick: action_cancel_drafts, label: 'Supprimer les brouillons sélectionnés', disabled: !length}),
          ...export_fields.map(this.make_export_action),
        ]}
        main_action={{icon: MdAddCircle, onClick: action_create_deal, label: 'Nouvelle Mission', action: true}}
        render_item={this.render_deal}
        selectable
        get_selected_count={this.get_selected_count}
      >
        {deals}
      </FilterableList>
    )
  }
}

export default connect(
  (state) => ({
    workplaces: state.missions.workplaces,
    recruiters: get_recruiters(state),
    fields: get_missions_filter_fields(state),
    export_fields: get_exports_fields(state),
    agency_id: state.profile.agency.id,
    initially_selected_recruiters: get_initially_selected_recruiters(state)
  })
)(DealsList)

const Workplace = styled.div`
  display: flex;
  align-items: baseline;
`
const WorkplaceName = styled.div`
  font-size: 18px;
  margin-right: 6px;
`
const WorkplaceAddress = styled.div``
const Period = styled.div``
const Creation = styled.div``

const Deal = styled.div`
  flex: 1;
  ${({onClick}) => onClick ? link : ''}
  display: flex;
  align-items: center;
  padding-right: 5px;
`
const Information = styled.div`
  flex: 1;
  display: flex;
  align-items: stretch;
  justify-content: space-between;
  flex-direction: column;
  margin-left: 10px;
  height: 50px;
`
const Top = styled.div`
  display: flex;
  align-items: center;
  justify-content: space-between;
`
const Statistics = styled.div`
  display: flex;
  align-items: center;
`
const Statistic = styled.div`
  display: flex;
  align-items: center;
  margin-left: 10px;
`
const StatisticIcon = styled.div`
  margin-left: 3px;
  font-size: 16px;
`
const Bottom = styled.div`
  display: flex;
  align-items: center;
  justify-content: space-between;
`
