import _ from 'lodash'
import React, { Component } from 'react'
import { connect } from 'react-redux'
import reducers from './reducers.jsx'
import MapVisualization from './MapVisualization.js'
import MapRoomInfo from './MapRoomInfo.jsx'
import Config from './Config.jsx'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faTimes } from '@fortawesome/free-solid-svg-icons'

class Map extends Component {
    constructor(props) {
        super(props)
        this.state = {
            highlighted: null,
            users: []
        }
    }

    componentDidMount() {
        this.rooms = Object.keys(this.props.rooms)
            .filter(key => _.has(this.props.rooms[key], 'map'))
            .map(key => {
                const room = _.cloneDeep(this.props.rooms[key])
                room.key = key
                return room
            })

        const width = document.querySelector('.map').clientWidth / Config.mapSizeRatio.width
        const height = document.querySelector('.map').clientHeight / Config.mapSizeRatio.height
        const padding = 10;
        const mouseEvents = {
            onRoomClick: room => {
                if (room !== 'room314') {
                    this.props.onRoomClick(room)
                    this.props.handleCloseMap()
                }
            },
            onRoomEnter: room => {
                this.setState({ highlighted: room })
            },
            onRoomLeave: () => {
                this.setState({ highlighted: null })
            }
        }

        this.map = new MapVisualization(
            '#d3-map',
            width,
            height,
            padding,
            mouseEvents
        )
        this.map.draw(this.rooms)
        this.updateMap(false)
    }

    updateMap(transition) {
        this.map.update(
            _.pickBy(this.props.users, (val, key) => key !== 'hallway'),
            transition
        )
    }

    getGlobalStats() {
        const users = this.props.users

        const numInHouse = _.sumBy(Object.keys(users), room => users[room].length)
        const numInHallways = (users.hallway || []).length
        const numInRooms = numInHouse - numInHallways

        const { stats: config } = Config.map

        const mapStats = [
            {
                key: 'numberInHouse',
                count: numInHouse
            },
            {
                key: 'numberInRooms',
                count: numInRooms
            },
            {
                key: 'numberInHallways',
                count: numInHallways
            }
        ]
            .filter(({ key }) => config[key].display)
            .map(({ key, count }) => (
                config[key].text.replace('{count}', count)
            ))

        config.additionalStats.forEach(({ text, match }) => {
            const rooms = _.isArray(match) ?
                _.intersection(Object.keys(users), match) :
                Object.keys(users).filter(room => new RegExp(match).test(room))
            const count = _.sumBy(rooms, room => users[room].length)
            mapStats.push(text.replace('{count}', count))
        })

        return (
            <div className="map-stats">
                {mapStats.map((text, index) => (
                    <div key={`stat-${index}`} className="map-stat-column">
                        {text}
                    </div>
                ))}
            </div>
        )
    }

    render() {
        if (this.map) {
            this.updateMap(true)
        }

        const roomId = this.state.highlighted
        const room = (this.props.rooms || {})[roomId]
        // TODO not lock unvisited rooms for now; this can be a future feature
        const isVisited = true;
        // const isVisited = this.props.visited && this.props.visited[roomId]
        const currentRoomUsers = this.props.users[roomId] || []
        const eventsForRoom = this.props.events.filter(event => event.room === roomId)

        return (
            <div className="map">
                <div className="map-header">
                    {this.getGlobalStats()}
                    <button className="map-close-button" onClick={this.props.handleCloseMap}>
                        <FontAwesomeIcon icon={faTimes} />
                    </button>
                </div>
                <div className="map-area">
                    <div id="d3-map"></div>
                    <MapRoomInfo
                        room={room}
                        events={eventsForRoom}
                        users={currentRoomUsers}
                        isVisited={isVisited}>
                    </MapRoomInfo>
                </div>
            </div>
        )
    }
}

export default connect(
    state => state,
    {
        updateCurrentRoom: reducers.updateCurrentRoomActionCreator
    })(Map)