import {
    Card,
    Col,
    Spin,
    Upload,
    type UploadFile,
    Image,
    Flex,
    Row,
    Tooltip,
} from 'antd'
import {
    CloudUploadOutlined,
    DeleteOutlined,
    EyeOutlined,
} from '@ant-design/icons'
import { ErrorMessage } from '../Utils/Notification'
import React, { useState } from 'react'
import './upload.less'
import { uploadFileToS3 } from '../Config/AwsConfig'
import { type RcFile } from 'antd/es/upload/interface'
import layoutStyles from '../Layouts/Less/style.less'
import FullWidthModal from './FullWidthModal'
import styles from './Less/s3Upload.less'
import { ReactComponent as PDFImage } from '../Assest/Svg/pdfIm.svg'
const { Dragger } = Upload

interface S3UploadInterface {
    name: string
    value?: string[]
    setFormData: (name: string, locations: string[]) => void
    setBase64?: (base64: string[] | undefined) => void
    corporate: string
    corporateid: number
    documenttype: string
    documentbaseId: number
    memberpersonId: number
}

const UploadComponent = (props: S3UploadInterface): React.ReactElement => {
    const {
        name,
        setFormData,
        setBase64,
        corporate,
        corporateid,
        documenttype,
        memberpersonId,
        documentbaseId,
    } = props
    const [dragging, setDragging] = useState(false)
    const [value, setValue] = useState<string[]>([])
    const [isLoading, setIsLoading] = useState<boolean>(false)
    const [deleteModalStatus, setDeleteModalStatus] = useState(false)
    const [fileUrl, setFileUrl] = useState('')
    const dynamicPath = `Document${corporate !== '' ? `/${corporate}` : ''}${
        corporateid !== 0 ? `/${corporateid}` : ''
    }${documenttype !== '' ? `/${documenttype}` : ''}${
        memberpersonId !== 0 ? `/${memberpersonId}` : ''
    }${documentbaseId !== 0 ? `/${documentbaseId}` : ''}`

    const convertBase64 = async (file: File): Promise<string> => {
        return await new Promise<string>((resolve, reject) => {
            const fileReader = new FileReader()
            fileReader.readAsDataURL(file)
            fileReader.onload = () => {
                resolve(fileReader.result as string)
            }
            fileReader.onerror = (error) => {
                reject(error)
            }
        })
    }

    const fileOnChange = async (fileList: UploadFile[]): Promise<void> => {
        setIsLoading(true)

        const base64List: string[] = []
        const uploadPromises = fileList?.map(async (file) => {
            if (setBase64 != null) {
                const base64 = await convertBase64(
                    file?.originFileObj as RcFile
                )
                base64List.push(base64)
            }
            return await uploadFileToS3(
                file.originFileObj as RcFile,
                dynamicPath
            )
        })
        try {
            const responses = await Promise.all(uploadPromises)
            const locations = responses?.map(
                (response) => response?.Location as string
            )
            setFormData(name, [...value, ...locations]) // Append new files to the existing state
            if (setBase64 != null) {
                setBase64([...value, ...base64List]) // Append new base64 strings to the existing state
            }
            setValue([...value, ...locations]) // Append new file locations to the existing state
        } catch (error) {
            console.error('Upload error: ', error)
            throw error // Throw the error to catch in onChange
        } finally {
            setIsLoading(false)
        }
    }
    const handleRemove = (fileUrl: string): void => {
        setFileUrl(fileUrl)
        setDeleteModalStatus(!deleteModalStatus)
    }

    const deleteotherCompanyId = (): void => {
        const updatedValue = value.filter((url) => url !== fileUrl)
        setValue(updatedValue)
        setFormData(name, updatedValue)
        handleRemove('')
    }
    const DraggerProps = {
        name: 'file',
        multiple: true,
        accept: '.pdf,.jpg,.jpeg,.png',
        showUploadList: false,
        beforeUpload: (file: { type: string }) => {
            const isPdfOrImage =
                file.type === 'application/pdf' ||
                file.type === 'image/jpeg' ||
                file.type === 'image/png' ||
                file.type === 'image/jpg'
            if (!isPdfOrImage) {
                ErrorMessage(
                    'You can only upload PDF, JPG, JPEG, or PNG files!'
                )
            }
            return isPdfOrImage || Upload.LIST_IGNORE // Prevents file from being added to upload list
        },
        async onChange(info: any) {
            const { status } = info.file
            if (status !== 'uploading') {
                try {
                    await fileOnChange(info.fileList)
                    // Update file status to done if upload was successful
                    info.file.status = 'done'
                    // SuccessMessage(
                    //     `${info.file.name} file uploaded successfully.`
                    // )
                } catch (error) {
                    ErrorMessage(`${info.file.name} file upload failed.`)
                }
            }
        },
    }

    const handleDragOver = (e: React.DragEvent<HTMLDivElement>): void => {
        e.preventDefault()
        setDragging(true)
    }

    const handleDragLeave = (): void => {
        setDragging(false)
    }

    const handleDrop = (e: React.DragEvent<HTMLDivElement>): void => {
        e.preventDefault()
        setDragging(false)
        const files = e.dataTransfer.files
        if (files?.length > 0) {
            const isAllValid = Array.from(files).every((file) => {
                const isPdfOrImage =
                    file.type === 'application/pdf' ||
                    file.type === 'image/jpeg' ||
                    file.type === 'image/png' ||
                    file.type === 'image/jpg'
                if (!isPdfOrImage) {
                    ErrorMessage(
                        'You can only upload PDF, JPG, JPEG, or PNG files!'
                    )
                }
                return isPdfOrImage
            })

            if (isAllValid) {
                // Manually trigger the file input change event
                const fileList = Array.from(files)
                const uploadComponent = document.querySelector(
                    '.ant-upload input[type="file"]'
                ) as HTMLInputElement
                if (uploadComponent !== null) {
                    Object.defineProperty(uploadComponent, 'files', {
                        value: fileList,
                        writable: false,
                    })
                    uploadComponent.dispatchEvent(
                        new Event('change', { bubbles: true })
                    )
                }
            }
        }
    }

    const getFileExtension = (url: string | undefined): string | undefined => {
        if (url != null) {
            return url.split('.').pop()?.toLowerCase()
        }
        return undefined
    }
    const handleDownload = (url: string): void => {
        // Create a temporary anchor element
        const link = document.createElement('a')
        link.href = url
        link.download = url.split('/').pop() ?? 'document.pdf' // Set the default file name if not available in URL
        link.target = '_blank'

        // Append the link to the document body and trigger the download
        document.body.appendChild(link)
        link.click()

        // Remove the link from the document body
        document.body.removeChild(link)
    }
    const renderFilePreview = (url: string, index: number): JSX.Element => {
        const fileExtension = getFileExtension(url)
        if (fileExtension === 'pdf') {
            return (
                <Col key={index}>
                    <Card
                        style={{ width: 200, marginTop: 16 }}
                        cover={
                            <PDFImage
                                width={200}
                                height={200}
                                style={{ cursor: 'pointer' }}
                            />
                        }
                        actions={[
                            <DeleteOutlined
                                key="delete"
                                onClick={() => {
                                    handleRemove(url)
                                }}
                            />,
                            <Tooltip
                                key="view"
                                title="View and Download Document"
                            >
                                <EyeOutlined
                                    onClick={() => {
                                        handleDownload(url)
                                    }}
                                    key="view"
                                />
                            </Tooltip>,
                        ]}
                    />
                </Col>
            )
        } else {
            return (
                <Col key={index} style={{ marginLeft: '5px' }}>
                    <Card
                        style={{ width: 200, marginTop: 16 }}
                        cover={
                            <Image
                                src={url}
                                alt={`preview-${index}`}
                                className={styles.previewImage}
                                width={200}
                                height={200}
                            />
                        }
                        actions={[
                            <DeleteOutlined
                                key="delete"
                                onClick={() => {
                                    handleRemove(url)
                                }}
                            />,
                        ]}
                    />
                </Col>
            )
        }
    }
    return (
        <>
            <div
                className={`upload-container ${dragging ? 'dragging' : ''}`}
                onDragOver={handleDragOver}
                onDragLeave={handleDragLeave}
                onDrop={handleDrop}
            >
                <Dragger {...DraggerProps}>
                    <p className="ant-upload-drag-icon">
                        <CloudUploadOutlined />
                    </p>
                    <p className="ant-upload-text">
                        Click or drag file to this area to upload
                    </p>
                    <p className="ant-upload-hint">
                        Support for a single or bulk upload. Only PDF, JPG,
                        JPEG, or PNG files are allowed.
                    </p>
                    {isLoading && (
                        <div className={layoutStyles.overlay}>
                            <Spin />
                        </div>
                    )}
                </Dragger>
            </div>
            <Row
                gutter={[16, 16]}
                style={{
                    marginTop: 20,
                    height: 'auto',
                    width: 'auto',
                    overflow: 'auto',
                }}
            >
                <Flex gap={5}>
                    {value.map((url, index) => renderFilePreview(url, index))}
                </Flex>
            </Row>

            <FullWidthModal
                modalStatus={deleteModalStatus}
                closeModal={handleRemove}
                tittle="Are you sure you want to remove this file. Click 'Yes' to continue."
                smallTittle="Warning: This action cannot be undone!"
                yesButtonFunction={deleteotherCompanyId}
            />
        </>
    )
}

export default UploadComponent
