import { useEffect, useMemo, useState } from 'react'
import type { BackendArt } from '../../functions/BackendTypes'
import { KEY_PREFIX_UPLOAD, setTitle, stateRecover } from '../../functions/Route'
import { BackendFetch } from '../../functions/Backend'
import { wtEvent } from '../../functions/Watchtower'

import LayoutBrowser, { type RecoverForLayoutBrowser } from '../layout/LayoutBrowser'
import HeaderMessage from '../layout/HeaderMessage'
import HeaderLoading from '../layout/HeaderLoading'
import HeaderError from '../layout/HeaderError'

export default function ViewPersonal() {
    const recovered = stateRecover<RecoverForLayoutBrowser>()
    const [isLoading, setLoading] = useState(true)
    const [items, setItems] = useState(recovered?.items ?? [])
    const message = useMemo(() => `View: Personal <Count: ${items.length}>`, [items])

    useEffect(() => {
        Promise.allSettled(
            Object.keys(localStorage)
                .filter((key) => key.startsWith(KEY_PREFIX_UPLOAD))
                .map((key) => key.slice(KEY_PREFIX_UPLOAD.length))
                .sort((a, b) => Number(BigInt(b) - BigInt(a)))
                .map(
                    (id) =>
                        new Promise<BackendArt>(async (resolve, reject) => {
                            // Check Caches
                            const item = recovered?.items.find((i) => i.id === id)
                            if (item) {
                                return resolve(item)
                            }

                            // Fetch from API
                            const resp = await BackendFetch<BackendArt>(`/art/${id}`)
                            if (!resp.success) {
                                if (resp.status === 404) {
                                    // Was probably deleted, remove from storage so
                                    // this client can stop spamming the backend.
                                    localStorage.removeItem(KEY_PREFIX_UPLOAD + id)
                                }
                                console.error(`Request for Animation (${id}) failed:`, resp)
                                return reject()
                            }
                            resolve(resp.json)
                        }),
                ),
        ).then((p) => {
            const items = p.filter((p) => p.status === 'fulfilled').map((p) => p.value)
            setItems(items)
            setLoading(false)

            wtEvent('view_personal', {
                ids: items.map((i) => i.id),
                item_total: items.length,
                item_error: p.filter((p) => p.status === 'rejected').length,
                item_count: p.filter((p) => p.status === 'fulfilled').length,
                nsfw_count: items.filter((i) => i.rating >= 0.8).length,
                nsfw_rating: items.reduce((sum, i) => sum + i.rating, 0) / items.length || 0,
            })
        })
    }, [])

    if (isLoading) {
        return (
            <>
                <HeaderMessage label="Retrieving Uploads" />
                <HeaderLoading reason="" />
            </>
        )
    }

    if (!items.length) {
        return (
            <>
                <HeaderMessage label={message} />
                <HeaderError reason="No past uploads were found on this device. <br> Expecting something? Restore your lost data in Settings." />
            </>
        )
    }

    setTitle('Personal')
    return (
        <>
            <HeaderMessage label={message} />
            <LayoutBrowser items={items} position={recovered?.position ?? 0} />
        </>
    )
}
