import { route } from 'preact-router'
import { useContext, useEffect, useState } from 'preact/hooks'
import { isAdministrator, Problem as ProblemModel, Solution as SolutionModel } from '../../shared/model'
import { prependBaseUrl } from '../../shared/utils'
import { server } from '../api'
import { Header } from '../components/Header'
import { MarkdownEditor } from '../components/MarkdownEditor'
import { Problem } from '../components/Problem'
import { Solution } from '../components/Solution'
import { MetadataContext, useListResource, useResource } from '../hooks'
import { useCurrentUser } from '../hooks/useCurrentUser'

type RouteProps = {
    id: string
}

export const ProblemPage = ({ id }: RouteProps) => {
    const metadata = useContext(MetadataContext)
    metadata.title = `Problem ${id}`
    metadata.description = 'Bacheca di problemi del PHC'

    const [user] = useCurrentUser()

    const [source, setSource] = useState('')

    const [problem, refreshProblem] = useResource<ProblemModel | null>(`/api/problem/${id}`, null, problem => {
        if (problem === null) {
            route(prependBaseUrl('/'))
        }
    })

    const [solutions, refreshSolutions, setSolutionHeuristic] = useListResource<SolutionModel>(`/api/solutions?problem=${id}`)
    const userSolutions: [number, SolutionModel][] = solutions.flatMap((s, index) => (user && s.sentBy === user.id ? [[index, s]] : []))
    const otherSolutions: [number, SolutionModel][] = solutions.flatMap((s, index) => (user && s.sentBy !== user.id ? [[index, s]] : []))

    const notLoggedSolutions: [number, SolutionModel][] = user ? [] : solutions.map((s, index) => [index, s])

    const sendSolution = async () => {
        if (source.trim().length === 0) {
            alert('La soluzione che hai inserito è vuota!')
            return
        }

        await server.post('/api/solution', {
            forProblem: id,
            content: source,
        })

        setSource('')

        refreshSolutions()
    }

    const [editing, setEditing] = useState<boolean>(false)
    const [modifiedProblemSource, setModifiedProblemSource] = useState<string>('')
    const [modifiedProblemTitle, setModifiedProblemTitle] = useState<string>(problem?.title ?? '')

    useEffect(() => {
        if (problem) {
            setModifiedProblemSource(problem.content)
        }
    }, [problem?.content])

    const updateProblem = async () => {
        await server.patch(`/api/problem/${id}`, {
            content: modifiedProblemSource,
            title: modifiedProblemTitle,
        })
        refreshProblem()
        setEditing(false)
    }

    const deleteProblem = async () => {
        if (confirm('Sei veramente sicuro di voler eliminare questo problema?')) {
            await server.delete(`/api/problem/${id}`)
            route(prependBaseUrl('/'))
        }
    }

    return (
        <>
            <Header />
            <main class="page-problem">
                <div class="subtitle">Testo del problema</div>
                {!editing ? (
                    <>
                        {problem && <Problem {...problem} />}
                        {user && isAdministrator(user.role) && (
                            <>
                                <button onClick={() => setEditing(true)}>Modifica problema</button>
                                <button onClick={() => deleteProblem()}>Elimina problema</button>
                            </>
                        )}
                    </>
                ) : (
                    <>
                        <div class="problem-title">
                            <label>Titolo</label>
                            <input
                                type="text"
                                value={modifiedProblemTitle}
                                onInput={e => setModifiedProblemTitle(e.target instanceof HTMLInputElement ? e.target.value : '')}
                                placeholder="Problema..."
                            />
                        </div>
                        <MarkdownEditor
                            placeholder="Modifica testo del problema..."
                            source={modifiedProblemSource}
                            setSource={setModifiedProblemSource}
                        />
                        <div class="col">
                            <button onClick={() => updateProblem()}>Aggiorna problema</button>
                            <button onClick={() => setEditing(false)}>Annulla</button>
                        </div>
                    </>
                )}
                {userSolutions.length > 0 && (
                    <details open>
                        <summary>Le tue soluzioni</summary>
                        <div class="solution-list">
                            {userSolutions.map(([index, s]) => (
                                <Solution
                                    {...s}
                                    adminControls={user !== null && isAdministrator(user.role)}
                                    refreshSolution={refreshSolutions}
                                    setSolution={solFn => setSolutionHeuristic(index, solFn)}
                                />
                            ))}
                        </div>
                    </details>
                )}
                {otherSolutions.length > 0 && (
                    <details>
                        <summary>Altre soluzioni</summary>
                        <div class="solution-list">
                            {otherSolutions.map(([index, s]) => (
                                <Solution
                                    {...s}
                                    adminControls={user !== null && isAdministrator(user.role)}
                                    refreshSolution={refreshSolutions}
                                    setSolution={solFn => setSolutionHeuristic(index, solFn)}
                                />
                            ))}
                        </div>
                    </details>
                )}
                {notLoggedSolutions.length > 0 && (
                    <details>
                        <summary>Soluzioni</summary>
                        <div class="solution-list">
                            {notLoggedSolutions.map(([index, s]) => (
                                <Solution
                                    {...s}
                                    adminControls={user !== null && isAdministrator(user.role)}
                                    refreshSolution={refreshSolutions}
                                    setSolution={solFn => setSolutionHeuristic(index, solFn)}
                                />
                            ))}
                        </div>
                    </details>
                )}
                {user && (
                    <>
                        <hr />
                        <div class="subtitle">Invia una soluzione al problema</div>
                        <MarkdownEditor placeholder="Scrivi una soluzione al problema..." {...{ source, setSource }} />
                        <button onClick={sendSolution}>Invia Soluzione</button>
                        <p class="icon-text">
                            <span class="material-symbols-outlined">warning</span>
                            Attenzione, una soluzione inviata non può essere modificata!
                        </p>
                    </>
                )}
            </main>
        </>
    )
}
