import { useState } from 'react'

import { useSendRate, useUserRating } from '../hooks/api'
import { gotError, gotResponse } from '../hooks/useFetch'

import styles from '../styles/StarRating.module.css'

type StarProps = {
    filled: boolean,
    selected: boolean,
    selectRate?: () => void,
    sendMyRate?: () => void,
    disabled: boolean
}

function Star({ filled, selected, selectRate, disabled }: StarProps) {
    return (
        <button
            className={`${styles.star} ${filled ? styles.starFilled : ''} ${selected ? styles.starSelected : ''}`}
            onMouseEnter={selectRate}
            onFocus={selectRate}
            disabled={disabled}
        >&#9733;</button> // star
    )
}

type StarRatingProps = {
    userId: number,
    dynamic?: boolean,
}

function StarRating({ userId, dynamic = false }: StarRatingProps) {
    const rating = useUserRating(userId)

    const [selectedRate, setSelectedRate] = useState(0)
    const [myRate, setMyRate] = useState(0)
    const rated = myRate > 0

    const { doSendRate } = useSendRate()

    async function sendMyRate() {
        const res = await doSendRate(selectedRate, userId)

        if (res) {
            rating.refetch()
            setMyRate(selectedRate)
        }
    }

    if (!gotResponse(rating)) {
        return (
            <span>Загрузка...</span>
        )
    }

    if (gotError(rating)) {
        return (
            <span className='text-danger'>{rating.error}</span>
        )
    }

    return (
        <span
            className={styles.starContainer}

            onClick={() => dynamic && !rated && void sendMyRate()}

            onMouseEnter={() => rated && setSelectedRate(myRate)}
            onMouseLeave={() => setSelectedRate(0)}

            onFocus={() => rated && setSelectedRate(myRate)}
            onBlur={() => setSelectedRate(0)}

            onTouchStart={() => rated && setSelectedRate(myRate)}
            onTouchEnd={() => setSelectedRate(0)}

            title={`Пользователи: ${Math.round(rating.data)}\nВы: ${myRate}`}
            tabIndex={0}
        >
            {...Array(5).fill(5).map((_, i) => (
                <Star
                    key={i}
                    filled={i < Math.round(rating.data)}
                    selected={i < selectedRate}
                    selectRate={() => dynamic && !rated && setSelectedRate(i + 1)}
                    disabled={!dynamic || rated}
                />
            ))}
        </span >
    )
}

export default StarRating
