import React, { useEffect, useState } from 'react'
import '@react-three/fiber'
import { Box, SegmentedControl, ThemeProvider } from '@primer/react'
import { FileBlob, MessageIds } from '../../chrome/types'
import { createPortal } from 'react-dom'
import { Loading } from '../Loading'
import { CadBlob } from './CadBlob'

function CadBlobPortal({
    element,
    owner,
    repo,
    sha,
    filename,
    classicUi,
}: {
    element: HTMLElement
    owner: string
    repo: string
    sha: string
    filename: string
    classicUi: boolean
}): React.ReactElement {
    const [richBlob, setRichBlob] = useState<FileBlob>()
    const [richSelected, setRichSelected] = useState(true)
    const [toolbarContainer, setToolbarContainer] = useState<HTMLElement>()
    const [blobContainer, setBlobContainer] = useState<HTMLElement>()
    const [sourceElements, setSourceElements] = useState<HTMLElement[]>([])

    useEffect(() => {
        let existingToggle: HTMLElement | undefined | null
        let toolbar: HTMLElement | undefined | null
        let blob: HTMLElement | undefined | null
        if (classicUi) {
            // no existing toggle
            toolbar = element.querySelector<HTMLElement>('.js-blob-header')
            blob = element.querySelector<HTMLElement>('.blob-wrapper')
        } else {
            existingToggle = element.querySelector<HTMLElement>(
                'ul[class*=SegmentedControl]'
            )
            toolbar = existingToggle?.parentElement
            blob = element.querySelector<HTMLElement>(
                'section[aria-labelledby="file-name-id"]'
            )
        }

        const isPreviewAlreadyEnabled =
            existingToggle && existingToggle.childElementCount > 2 // Preview, Code, Blame
        if (isPreviewAlreadyEnabled) {
            const existingPreview = element.querySelector<HTMLElement>('iframe')
            blob = existingPreview?.parentElement
            if (blob && blob.parentElement) {
                setBlobContainer(blob.parentElement)
                blob.style.display = 'none'
            }
            // No toolbar, no sourceElements. Only a replacement of the existing (STL) preview
            return
        }

        if (toolbar != null) {
            setToolbarContainer(toolbar)
            if (existingToggle) {
                existingToggle.style.display = 'none'
            }
        }

        if (blob != null) {
            setBlobContainer(blob)
            const sourceElements = Array.from(blob.children) as HTMLElement[]
            sourceElements.map(n => (n.style.display = 'none'))
            setSourceElements(sourceElements)
        }
    }, [element])

    useEffect(() => {
        ;(async () => {
            const response = await chrome.runtime.sendMessage({
                id: MessageIds.GetFileBlob,
                data: { owner, repo, sha, filename },
            })
            if ('error' in response) {
                console.log(response.error)
            } else {
                setRichBlob(response as FileBlob)
            }
        })()
    }, [owner, repo, sha, filename])

    return (
        <>
            {toolbarContainer &&
                createPortal(
                    <SegmentedControl
                        sx={{ mr: classicUi ? 2 : 0, order: -1 }} // prepend in flex
                        aria-label="File view"
                        onChange={(index: number) => {
                            if (index < 2) {
                                setRichSelected(index === 0)
                                sourceElements.map(
                                    n =>
                                        (n.style.display =
                                            index === 0 ? 'none' : 'block')
                                )
                                return
                            }
                            window.location.href = `https://github.com/${owner}/${repo}/blame/${sha}/${filename}`
                        }}
                    >
                        <SegmentedControl.Button selected={richSelected}>
                            Preview
                        </SegmentedControl.Button>
                        <SegmentedControl.Button selected={!richSelected}>
                            Code
                        </SegmentedControl.Button>
                        {!classicUi && (
                            <SegmentedControl.Button>
                                Blame
                            </SegmentedControl.Button>
                        )}
                    </SegmentedControl>,
                    toolbarContainer
                )}
            {blobContainer &&
                createPortal(
                    <Box
                        sx={{
                            display: richSelected ? 'block' : 'none',
                            width: '100%',
                        }}
                    >
                        {richBlob ? (
                            <CadBlob blob={richBlob.blob} />
                        ) : (
                            <Loading />
                        )}
                    </Box>,
                    blobContainer
                )}
        </>
    )
}

export type CadBlobPageProps = {
    element: HTMLElement
    owner: string
    repo: string
    sha: string
    filename: string
    classicUi: boolean
}

export function CadBlobPage({
    element,
    owner,
    repo,
    sha,
    filename,
    classicUi,
}: CadBlobPageProps): React.ReactElement {
    return (
        <ThemeProvider colorMode="auto">
            <CadBlobPortal
                element={element}
                owner={owner}
                repo={repo}
                sha={sha}
                filename={filename}
                classicUi={classicUi}
            />
        </ThemeProvider>
    )
}
