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

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

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

export const WorkWeekTranspose = ({ events }) => {
    const eventsByWeekday = _.groupBy(events, event => event.start.getDay())

    // For each weekday compute the interval layout
    const rowLayouts = _.mapValues(eventsByWeekday, events =>
        layoutIntervals(
            events.map(e => ({
                start: differenceInMinutes(e.start, startOfDay(e.start)),
                end: differenceInMinutes(e.end, startOfDay(e.start)),
                data: e,
            }))
        )
    )

    return (
        <div class="work-week-h-view">
            <div class="week">
                {WEEK_DAYS.slice(1, 6).map((label, index) => (
                    <div class="day" style={{ '--size': rowLayouts[index + 1]?.length ?? 0 }}>
                        {label}
                    </div>
                ))}
            </div>
            <div class="events">
                <div class="header">
                    <div class="label" style={{ 'grid-column': '2 / span 2' }}>
                        9:00 &ndash; 11:00
                    </div>
                    <div class="label" style={{ 'grid-column': '4 / span 2' }}>
                        11:00 &ndash; 13:00
                    </div>
                    <div class="label" style={{ 'grid-column': '7 / span 2' }}>
                        14:00 &ndash; 16:00
                    </div>
                    <div class="label" style={{ 'grid-column': '9 / span 2' }}>
                        16:00 &ndash; 18:00
                    </div>
                </div>
                <div class="days">
                    {Object.values(rowLayouts).map(layout => (
                        <div class="day" style={{ '--size': layout.length }}>
                            {layout.map((events, rowIndex) =>
                                events.map(event => {
                                    const Local = () => {
                                        const eventRef = useRef()

                                        const updateMinWidth = () => {
                                            eventRef.current.style.minWidth =
                                                eventRef.current.offsetWidth + 'px'
                                        }

                                        useEffect(() => {
                                            if (eventRef.current) {
                                                setTimeout(updateMinWidth, 100)
                                                window.addEventListener('resize', updateMinWidth)

                                                return () => {
                                                    window.removeEventListener(
                                                        'resize',
                                                        updateMinWidth
                                                    )
                                                }
                                            }
                                        }, [eventRef.current])

                                        return (
                                            <div
                                                class="event"
                                                style={{
                                                    '--row': rowIndex + 1,
                                                    '--start': event.start / 60 - 7,
                                                    '--size': (event.end - event.start) / 60,
                                                    '--hue':
                                                        (Math.abs(
                                                            hashString('seed3' + event.data.id)
                                                        ) %
                                                            360) +
                                                        'deg',
                                                }}
                                                ref={eventRef}
                                            >
                                                {prettyCourseName(event.data.name)}
                                            </div>
                                        )
                                    }

                                    return <Local />
                                })
                            )}
                        </div>
                    ))}
                </div>
            </div>
        </div>
    )
}
