import { useEffect, useRef } from 'react'
import { useDownload, useFileType } from '../../hooks/swrHooks';

import jsPreviewExcel from "@js-preview/excel"
import '@js-preview/excel/lib/index.css'

import jsPreviewDocx from "@js-preview/docx"
import '@js-preview/docx/lib/index.css'

import jsPreviewPdf from '@js-preview/pdf'
import { IDocument } from '../../interfaces/documents';
import { IconAlertTriangle, IconChevronLeft, IconChevronRight, IconX } from '@tabler/icons-react';
import { Button, Spinner, Text } from '@fluentui/react-components';

interface Props {
    open: boolean;
    setOpen: (state: boolean) => void;
    docs: IDocument[];
    currentFileNo: number;
    setCurrentFileNo: (state: number) => void;
}

interface ViewerProps {
    url: string | ArrayBuffer | Blob
}

function PdfViewer({
    url
}: ViewerProps) {
    const previewContainerRef = useRef(null)

    const pdfPreviewer = jsPreviewPdf

    useEffect(() => {
        if (previewContainerRef && previewContainerRef.current) {
            pdfPreviewer.init(previewContainerRef.current)
                .preview(url)
        }

        return () => {
            if (previewContainerRef && previewContainerRef.current) {
                previewContainerRef.current = null
            }
        }
    }, [previewContainerRef])

    return (
        <div ref={previewContainerRef} style={{
            width: '100%',
            height: '100%',
        }} />
    )
}

function DocxViewer({
    url
}: ViewerProps) {
    const previewContainerRef = useRef(null)

    useEffect(() => {
        if (previewContainerRef && previewContainerRef.current) {
            jsPreviewDocx.init(previewContainerRef.current, {
                breakPages: true,
                inWrapper: true,
                ignoreHeight: true,
            })
                .preview(url)
        }

        return () => {
            if (previewContainerRef && previewContainerRef.current) {
                previewContainerRef.current = null
            }
        }
    }, [])

    return (
        <div ref={previewContainerRef} style={{
            width: '100%',
            height: '100%',
        }} />
    )
}

export function ExcelViewer({
    url
}: ViewerProps) {
    const previewContainerRef = useRef(null)

    useEffect(() => {
        if (previewContainerRef && previewContainerRef.current) {
            jsPreviewExcel.init(previewContainerRef.current)
                .preview(url)
        }

        return () => {
            if (previewContainerRef && previewContainerRef.current) {
                previewContainerRef.current = null
            }
        }
    }, [])

    return (
        <div ref={previewContainerRef} style={{
            width: '100%',
            height: '100%',
        }} />
    )
}

function ImageViewer({
    url
}: ViewerProps) {
    return (
        <div style={{
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center',
            objectFit: 'contain',
            width: '100%',
            height: '100%'
        }}>
            <img alt='image-preview' src={url as string} style={{
                display: 'flex',
                maxWidth: '100%',
                maxHeight: '100%'
            }} />
        </div>
    )
}

export default function FileViewer({
    open,
    setOpen,
    docs,
    currentFileNo,
    setCurrentFileNo
}: Props) {
    const { file, isLoading: fileIsLoading } = useDownload(currentFileNo >= 0 ? docs[currentFileNo]?.document_folder_id : null, currentFileNo >= 0 ? docs[currentFileNo]?.id : null)

    const { fileType, isLoading: fileTypeIsLoading } = useFileType(currentFileNo >= 0 ? docs[currentFileNo]?.name : null, currentFileNo >= 0 ? file : null)

    const handleSave = async () => {
        const url = window.URL.createObjectURL(file)
        const link = document.createElement('a')
        link.href = url
        link.setAttribute('download', docs[currentFileNo].name)
        document.body.appendChild(link)
        link.click()
        link.remove()
    }

    return (
        <div style={{display: open ? 'flex' : 'none'}}>
            <div style={{
                display: 'grid',
                position: 'fixed',
                inset: 0,
                zIndex: '9999',
                background: 'var(--colorNeutralBackground1)',
                gridTemplateRows: 'min-content auto',
                width: '100vw',
                height: '100vh'
            }}>
                <div style={{ display: 'flex', padding: '1rem' }}>
                    <div style={{ width: '100%' }}>
                        <div style={{ display: 'flex', alignItems: 'center' }}>
                            <Text style={{ marginRight: 'auto' }}>
                                {currentFileNo != -1 && docs[currentFileNo].name}
                            </Text>

                            <div>
                                <Button
                                    icon={<IconChevronLeft />}
                                    appearance='transparent'
                                    onClick={() => {
                                        if (currentFileNo >= 0 && currentFileNo > 0) {
                                            setCurrentFileNo(currentFileNo - 1)
                                        }
                                    }}
                                    disabled={currentFileNo >= 0 && currentFileNo === 0}
                                />
                                <Button
                                    icon={<IconChevronRight />}
                                    appearance='transparent'
                                    onClick={() => {
                                        if (currentFileNo >= 0 && currentFileNo < docs.length) {
                                            setCurrentFileNo(currentFileNo + 1)
                                        }
                                    }}
                                    disabled={currentFileNo >= 0 && currentFileNo >= docs.length - 1}
                                />
                            </div>

                            <Button
                                autoFocus
                                appearance='subtle'
                                onClick={handleSave}
                            >
                                Сохранить
                            </Button>
                        </div>
                    </div>

                    <Button icon={<IconX />} appearance='subtle' onClick={() => setOpen(false)} />
                </div>

                <div style={{ display: 'flex', flexGrow: 1, height: '100%', overflow: 'auto', width: '100vw' }}>
                    {fileIsLoading || fileTypeIsLoading ?
                        <div style={{
                            display: 'flex',
                            width: '100%',
                            height: '100%',
                            alignItems: 'center',
                            justifyContent: 'center'
                        }}>
                            <Spinner />
                        </div>
                        :
                        fileType === 'application/pdf' ?
                            <PdfViewer url={window.URL.createObjectURL(file)} />
                            :
                            fileType === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ?
                                <ExcelViewer url={window.URL.createObjectURL(file)} />
                                :
                                fileType === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' ?
                                    <DocxViewer url={window.URL.createObjectURL(file)} />
                                    :
                                    fileType?.startsWith('image/') ?
                                        <ImageViewer url={window.URL.createObjectURL(file)} />
                                        :
                                        fileType && file ?
                                            <div style={{ display: 'flex', gap: '16px', flexDirection: 'column', padding: '1rem' }}>
                                                <div style={{ display: 'flex', gap: '16px', alignItems: 'center' }}>
                                                    <IconAlertTriangle />
                                                    <Text>
                                                        Предпросмотр данного файла невозможен.
                                                    </Text>
                                                </div>

                                                <div style={{ display: 'flex' }}>
                                                    <Button appearance='secondary' onClick={() => {
                                                        handleSave()
                                                    }}>
                                                        Сохранить
                                                    </Button>
                                                </div>
                                            </div>
                                            :
                                            null
                    }
                </div>
            </div>
        </div>
    )
}