import { useEffect, useRef, useState } from 'preact/hooks'

import _ from 'lodash'
import { differenceInMinutes, startOfDay } from 'date-fns'

import { hashString, normalizeCourseName, WEEK_DAYS } from '../../utils.jsx'
import { layoutIntervals } from '../../interval-layout.js'

export const WorkWeek = ({ events, selection, setSelection, hideOtherCourses }) => {
    const selectionSet = new Set(selection)

    const eventsByWeekday = _.groupBy(
        !hideOtherCourses ? events : events.filter(e => selectionSet.has(e.id)),
        event => event.start.getDay()
    )

    // const dayIntervalLayout = _.mapValues(Object.assign(base, eventsByWeekday), events =>
    const dayIntervalLayout = _.mapValues(eventsByWeekday, events =>
        layoutIntervals(
            events.map(e => ({
                start: differenceInMinutes(e.start, startOfDay(e.start)),
                end: differenceInMinutes(e.end, startOfDay(e.start)),
                data: e,
            }))
        )
    )

    const [currentlyHovered, setCurrentlyHovered] = useState(null)
    const element = useRef()

    useEffect(() => {
        if (element.current) {
            const l = e => {
                const $event = e.target.closest('.event')
                if ($event) {
                    setCurrentlyHovered($event.dataset.eventId)
                } else {
                    setCurrentlyHovered(null)
                }
            }

            element.current.addEventListener('mousemove', l)
            element.current.addEventListener('mouseleave', l)

            return () => {
                element.current.removeEventListener('mousemove', l)
                element.current.removeEventListener('mouseleave', l)
            }
        }
    }, [element.current])

    return (
        <div class="work-week-v-view" ref={element}>
            <div class="pivot"></div>
            <div class="left-header">
                <div class="blocks">
                    <div
                        class="block skip-border"
                        style={{
                            '--start': 9 - 7,
                            '--size': 2,
                        }}
                    >
                        9:00 &ndash; 11:00
                    </div>
                    <div
                        class="block"
                        style={{
                            '--start': 11 - 7,
                            '--size': 2,
                        }}
                    >
                        11:00 &ndash; 13:00
                    </div>
                    <div
                        class="block skip-border"
                        style={{
                            '--start': 14 - 7,
                            '--size': 2,
                        }}
                    >
                        14:00 &ndash; 16:00
                    </div>
                    <div
                        class="block"
                        style={{
                            '--start': 16 - 7,
                            '--size': 2,
                        }}
                    >
                        16:00 &ndash; 18:00
                    </div>
                </div>
            </div>
            {Object.entries(dayIntervalLayout).map(([index, layout]) => (
                <div class="day" style={{ '--size': Math.max(1, layout.length) }}>
                    <div class="top-header">{WEEK_DAYS[parseInt(index)]}</div>
                    <div class="events">
                        {layout.map((events, stackIndex) => (
                            <>
                                {events.map(event => (
                                    <div
                                        class={
                                            'event' +
                                            (currentlyHovered === event.data.id
                                                ? ' highlight'
                                                : '') +
                                            (selectionSet.has(event.data.id) ? ' selected' : '')
                                        }
                                        data-event-id={event.data.id}
                                        style={{
                                            '--start': event.start / 60 - 7,
                                            '--stack': stackIndex + 1,
                                            '--size': (event.end - event.start) / 60,
                                            '--hue':
                                                (Math.abs(hashString('seed3' + event.data.id)) %
                                                    360) +
                                                'deg',
                                        }}
                                        onClick={() => {
                                            if (!selectionSet.has(event.data.id))
                                                setSelection([...selection, event.data.id])
                                            else
                                                setSelection(
                                                    selection.filter(id => event.data.id !== id)
                                                )
                                        }}
                                    >
                                        <div class="title">
                                            {normalizeCourseName(event.data.name)}
                                        </div>
                                        <div class="aula">{event.data.aula}</div>
                                    </div>
                                ))}
                            </>
                        ))}

                        {/* Grid Tracks */}
                        {[1, 3, 5].map(i => (
                            <div class="grid-line-h" style={{ '--track': i }}></div>
                        ))}
                        {[6, 8, 10].map(i => (
                            <div class="grid-line-h" style={{ '--track': i }}></div>
                        ))}
                    </div>
                </div>
            ))}
        </div>
    )
}
