import { useState } from 'preact/hooks'
import { JSX } from 'preact/jsx-runtime'
import { ProblemId, Solution as SolutionModel, SolutionId, SolutionStatus, UserId } from '../../shared/model'
import { prependBaseUrl } from '../../shared/utils'
import { server } from '../api'
import { useLoggedInUser } from '../hooks/useCurrentUser'
import { Markdown } from './Markdown'

const STATUS_SELECT_OPTIONS: Record<SolutionStatus, JSX.Element> = {
    ['pending']: <div class="pending">In attesa di correzione</div>,
    ['correct']: <div class="correct">Corretta</div>,
    ['wrong']: <div class="wrong">Sbagliata</div>,
}

type Props = {
    id: SolutionId
    createdAt: string
    sentBy?: UserId
    forProblem: ProblemId
    content: string
    status?: SolutionStatus
    visible?: boolean
    adminControls: boolean
    setSolution?: (solutionFn: (prev: SolutionModel) => SolutionModel) => void
    refreshSolution?: () => void
}

export const Solution = ({
    id,
    createdAt,
    sentBy,
    forProblem,
    content,
    status,
    visible,
    adminControls,
    setSolution,
    refreshSolution,
}: Props) => {
    const [user] = useLoggedInUser()

    const markAsCorrect = async () => {
        setSolution?.(prevSolution => ({ ...prevSolution, status: 'correct' }))

        await server.patch(`/api/solution/${id}`, {
            status: 'correct',
        })

        refreshSolution?.()
    }

    const markAsWrong = async () => {
        setSolution?.(prevSolution => ({ ...prevSolution, status: 'wrong' }))

        await server.patch(`/api/solution/${id}`, {
            status: 'wrong',
        })

        refreshSolution?.()
    }

    const changeVisibility = async () => {
        setSolution?.(prevSolution => ({ ...prevSolution, visible: !visible }))

        await server.patch(`/api/solution/${id}`, {
            visible: !visible,
        })

        refreshSolution?.()
    }

    const deleteSolution = async () => {
        if (confirm('Sei proprio sicuro di voler eliminare questa soluzione?')) {
            await server.delete(`/api/solution/${id}`)
            refreshSolution?.()
        }
    }

    const [viewRaw, setViewRaw] = useState<boolean>(false)

    const toggleViewRaw = () => {
        setViewRaw(prev => !prev)
    }

    const d = new Date(createdAt)

    return (
        <div class={['solution', status].join(' ')}>
            <div class="solution-header">
                <div>
                    <span title={id} class="dotted">
                        Soluzione
                    </span>
                    {sentBy && (
                        <>
                            {' '}
                            di <a href={prependBaseUrl(`/u/${sentBy}`)}>@{sentBy}</a>
                        </>
                    )}
                    {forProblem && (
                        <>
                            {' '}
                            per il <a href={prependBaseUrl(`/problem/${forProblem}`)}>Problema {forProblem}</a>
                        </>
                    )}
                    {!isNaN(d as any) && (
                        <>
                            {' del '}
                            <span title={!isNaN(d as any) ? d.toISOString() : undefined} class="dotted">
                                {d.getFullYear()}/{d.getMonth().toString().padStart(2, '0')}/{d.getDate().toString().padStart(2, '0')}{' '}
                                {d.getHours().toString().padStart(2, '0')}:{d.getMinutes().toString().padStart(2, '0')}
                            </span>
                        </>
                    )}
                </div>
            </div>
            <div class="solution-content">
                {viewRaw ? (
                    <pre>
                        <code>{content}</code>
                    </pre>
                ) : (
                    <Markdown source={content} />
                )}
            </div>
            {status && (
                <div class="solution-footer">
                    <div class="row">
                        <div class="status-label">{STATUS_SELECT_OPTIONS[status]}</div>
                        {adminControls && (
                            <>
                                <button title="Segna come corretta" disabled={status === 'correct'} class="icon" onClick={markAsCorrect}>
                                    <span class="material-symbols-outlined correct">check_circle</span>
                                </button>
                                <button title="Segna come sbagliata" disabled={status === 'wrong'} class="icon" onClick={markAsWrong}>
                                    <span class="material-symbols-outlined wrong">cancel</span>
                                </button>
                                {status !== 'pending' && (
                                    <button
                                        title={visible ? 'Nascondi al pubblico' : 'Rendi visibile al pubblico'}
                                        class="icon"
                                        onClick={changeVisibility}
                                    >
                                        <span class="material-symbols-outlined">{visible ? 'visibility' : 'visibility_off'}</span>
                                    </button>
                                )}
                            </>
                        )}
                        {user && (user.role === 'admin' || sentBy === user.id) && (
                            <>
                                <button class="icon" title="Elimina questa soluzione" onClick={() => deleteSolution()}>
                                    <span class="material-symbols-outlined wrong">delete</span>
                                </button>
                            </>
                        )}
                        <div class="vr"></div>
                        <button
                            class="icon"
                            onClick={toggleViewRaw}
                            title={!viewRaw ? 'Mostra markdown grezzo' : 'Mostra testo matematicoso'}
                        >
                            <span class="material-symbols-outlined">{!viewRaw ? 'data_object' : 'functions'}</span>
                        </button>
                    </div>
                </div>
            )}
        </div>
    )
}
