import { useState, useEffect, Fragment } from 'react';
import dayjs from 'dayjs';
import localeData from 'dayjs/plugin/localeData';
import customParseFormat from 'dayjs/plugin/customParseFormat';

import { useSettingsStore } from 'stores';

import { Legend, Center } from 'components';
import {
	Wrapper,
	Container,
	Date,
	Times,
	DateLabel,
	DayLabel,
	Time,
	Spacer,
	Tooltip,
	TooltipTitle,
	TooltipDate,
	TooltipContent,
	TimeLabels,
	TimeLabel,
	TimeSpace,
  People,
  Person,
  StyledMain,
} from './availabilityViewerStyle';

dayjs.extend(localeData);
dayjs.extend(customParseFormat);

const AvailabilityViewer = ({
	times,
	timeLabels,
	dates,
  isSpecificDates,
	people = [],
	min = 0,
	max = 0,
	...props
}) => {
	const [tooltip, setTooltip] = useState(null);
  const timeFormat = useSettingsStore(state => state.timeFormat);
  const [filteredPeople, setFilteredPeople] = useState([]);
  const [touched, setTouched] = useState(false);
  const [tempFocus, setTempFocus] = useState(null);
  const [focusCount, setFocusCount] = useState(null);

  useEffect(() => {
    setFilteredPeople(people.map(p => p.name));
    setTouched(people.length <= 1);
  }, [people]);

	return (
    <>
      <StyledMain>
        <Legend
          min={Math.min(min, filteredPeople.length)}
          max={Math.min(max, filteredPeople.length)}
          total={people.filter(p => p.availability.length > 0).length}
          onSegmentFocus={count => setFocusCount(count)}
        />
        <Center>Hover or tap the calendar below to see who is available</Center>
        {people.length > 1 && (
          <>
            <Center>Click the names below to view people individually</Center>
            <People>
              {people.map((person, i) =>
                <Person
                  key={i}
                  filtered={filteredPeople.includes(person.name)}
                  onClick={() => {
                    setTempFocus(null);
                    if (filteredPeople.includes(person.name)) {
                      if (!touched) {
                        setTouched(true);
                        setFilteredPeople([person.name]);
                      } else {
                        setFilteredPeople(filteredPeople.filter(n => n !== person.name));
                      }
                    } else {
                      setFilteredPeople([...filteredPeople, person.name]);
                    }
                  }}
                  onMouseOver={() => setTempFocus(person.name)}
                  onMouseOut={() => setTempFocus(null)}
                >{person.name}</Person>
              )}
            </People>
          </>
        )}
      </StyledMain>

  		<Wrapper>
  			<Container>
  				<TimeLabels>
  					{!!timeLabels.length && timeLabels.map((label, i) =>
  						<TimeSpace key={i}>
  							{label.label?.length !== '' && <TimeLabel>{label.label}</TimeLabel>}
  						</TimeSpace>
  					)}
  				</TimeLabels>
  				{dates.map((date, i) => {
  					const parsedDate = isSpecificDates ? dayjs(date, 'DDMMYYYY') : dayjs().day(date);
  					const last = dates.length === i+1 || (isSpecificDates ? dayjs(dates[i+1], 'DDMMYYYY') : dayjs().day(dates[i+1])).diff(parsedDate, 'day') > 1;
  					return (
  						<Fragment key={i}>
  							<Date>
  								{isSpecificDates && <DateLabel>{parsedDate.format('MMM D')}</DateLabel>}
  								<DayLabel>{parsedDate.format('ddd')}</DayLabel>

  								<Times>
  									{timeLabels.map((timeLabel, i) => {
  										if (!timeLabel.time) return null;
  										if (!times.includes(`${timeLabel.time}-${date}`)) {
  											return (
  												<TimeSpace key={i} />
  											);
  										}
  										const time = `${timeLabel.time}-${date}`;
  										const peopleHere = tempFocus !== null
                        ? people.filter(person => person.availability.includes(time) && tempFocus === person.name).map(person => person.name)
                        : people.filter(person => person.availability.includes(time) && filteredPeople.includes(person.name)).map(person => person.name);

  										return (
  											<Time
  												key={i}
  												time={time}
  												className="time"
  												peopleCount={focusCount !== null && focusCount !== peopleHere.length ? 0 : peopleHere.length}
  												aria-label={peopleHere.join(', ')}
  												maxPeople={tempFocus !== null ? 1 : Math.min(max, filteredPeople.length)}
  												minPeople={tempFocus !== null ? 0 : Math.min(min, filteredPeople.length)}
  												onMouseEnter={(e) => {
  													const cellBox = e.currentTarget.getBoundingClientRect();
                            const timeText = timeFormat === '12h' ? 'h:mma' : 'HH:mm';
  													setTooltip({
  														x: Math.round(cellBox.x + cellBox.width/2),
  														y: Math.round(cellBox.y + cellBox.height)+6,
  														available: `${peopleHere.length} / ${people.length} available`,
  														date: parsedDate.hour(time.slice(0, 2)).minute(time.slice(2, 4)).format(isSpecificDates ? `${timeText} ddd, D MMM YYYY` : `${timeText} ddd`),
  														people: peopleHere.join(', '),
  													});
  												}}
  												onMouseLeave={() => {
  													setTooltip(null);
  												}}
  											/>
  										);
  									})}
  								</Times>
  							</Date>
  							{last && dates.length !== i+1 && (
  								<Spacer />
  							)}
  						</Fragment>
  					);
  				})}
  			</Container>
  			{tooltip && (
  				<Tooltip
  					x={tooltip.x}
  					y={tooltip.y}
  				>
  					<TooltipTitle>{tooltip.available}</TooltipTitle>
  					<TooltipDate>{tooltip.date}</TooltipDate>
  					<TooltipContent>{tooltip.people}</TooltipContent>
  				</Tooltip>
  			)}
  		</Wrapper>
    </>
	);
};

export default AvailabilityViewer;
