import { useState, useContext, useEffect, useRef, useCallback } from 'react'
import PropTypes from 'prop-types'
import { Flex, Button, Input, Select } from 'antd'
import PlusIcon from '../../Icons/PlusIcon.jsx'
import MinusIcon from '../../Icons/MinusIcon.jsx'
import InfoCircleIcon from '../../Icons/InfoCircleIcon.jsx'
import ObjectProperty from '../common/ObjectProperty.jsx'
import { ApiServerContext } from '../context/ApiServerContext.jsx'

const TemplatePreview = ({
  objectData,
  documentTemplate,
  loading,
  isEditing,
  onTestObjectOpen,
  onPreviewMessage,
  showTestObject = false,
  showPreviewSwitch = true
}) => {
  const iframeRef = useRef(null)
  const { fetchTemplatePreview, fetchTemplatePDF } =
    useContext(ApiServerContext)
  const [previewContentHTML, setPreviewContentHTML] = useState('')
  const [pdfBlob, setPDFBlob] = useState(null)
  const [reloadLoading, setReloadLoading] = useState(false)
  const [previewScale, setPreviewScale] = useState(1)
  const [previewType, setPreviewType] = useState('HTML')

  const updatePreviewContentHTML = (html) => {
    if (iframeRef.current) {
      // Save current scroll position
      const scrollY = iframeRef.current.contentWindow.scrollY
      const scrollX = iframeRef.current.contentWindow.scrollX

      // Update srcDoc
      setPreviewContentHTML(html)

      // Restore scroll position after iframe loads new content
      const handleLoad = () => {
        iframeRef.current.contentWindow.scrollTo(scrollX, scrollY)
        iframeRef.current.removeEventListener('load', handleLoad)
      }
      iframeRef.current.addEventListener('load', handleLoad)
    }
  }

  const reloadPreviewPDF = (content, testObject = {}) => {
    setReloadLoading(true)
    fetchTemplatePDF(documentTemplate._id, content, testObject, (result) => {
      setReloadLoading(false)
      if (result?.error) {
        // Handle error through parent component
        onPreviewMessage(result.error, true)
      } else {
        const pdfBlob = new Blob([result.pdf], { type: 'application/pdf' })
        const pdfUrl = URL.createObjectURL(pdfBlob)

        setPDFBlob(pdfUrl)
        onPreviewMessage('No issues found.', false)
      }
    })
  }

  const reloadPreview = useCallback(
    (content, testObject = {}, scale = 1) => {
      setReloadLoading(true)
      fetchTemplatePreview(
        documentTemplate._id,
        content,
        testObject,
        scale,
        (result) => {
          setReloadLoading(false)
          if (result?.error) {
            // Handle error through parent component
            onPreviewMessage(result.error, true)
          } else {
            updatePreviewContentHTML(result.html)
            onPreviewMessage('No issues found.', false)
          }
        }
      )
    },
    [fetchTemplatePreview, objectData?._id, onPreviewMessage]
  )

  // Move useEffect to component level and use state to track objectData changes
  useEffect(() => {
    if (documentTemplate?.content) {
      if (previewType == 'HTML') {
        reloadPreview(documentTemplate.content, objectData, previewScale)
      } else {
        reloadPreviewPDF(documentTemplate.content, objectData)
      }
    }
  }, [objectData, documentTemplate, previewScale, previewType])

  return (
    <Flex vertical gap={'middle'} style={{ height: '100%' }}>
      <Flex gap={'small'}>
        {showTestObject == true ? (
          <>
            {documentTemplate?.objectType ? (
              <ObjectProperty
                objectType={documentTemplate?.objectType}
                name={'testObject'}
                isEditing={true}
                objectData={objectData}
                disabled={!isEditing || objectData?.global}
                type={'object'}
              />
            ) : (
              <div style={{ flexGrow: 1 }}>
                <Input disabled={true} />
              </div>
            )}
            <Button
              icon={<InfoCircleIcon />}
              disabled={objectData?.global}
              onClick={() => {
                onTestObjectOpen()
              }}
            />
          </>
        ) : null}

        <Button
          icon={<PlusIcon />}
          onClick={() => {
            setPreviewScale((prev) => prev + 0.05)
          }}
          disabled={loading || reloadLoading || previewType == 'PDF'}
        />
        <Button
          icon={<MinusIcon />}
          onClick={() => {
            setPreviewScale((prev) => prev - 0.05)
          }}
          disabled={loading || reloadLoading || previewType == 'PDF'}
        />
        <Button
          readOnly={true}
          style={{ width: '65px' }}
          disabled={loading || reloadLoading || previewType == 'PDF'}
          onClick={() => {
            setPreviewScale(1)
          }}
        >
          {previewScale.toFixed(2)}x
        </Button>
        {showPreviewSwitch == true ? (
          <Select
            options={[
              { value: 'HTML', label: 'HTML' },
              { value: 'PDF', label: 'PDF' }
            ]}
            loading={loading || reloadLoading}
            disabled={loading || reloadLoading}
            value={previewType}
            onChange={(value) => {
              setPreviewType(value)
            }}
          />
        ) : null}
      </Flex>

      <iframe
        ref={iframeRef}
        srcDoc={previewType == 'HTML' ? previewContentHTML : undefined}
        src={previewType == 'PDF' ? pdfBlob : undefined}
        frameBorder='0'
        style={{
          width: '100%',
          flexGrow: 1,
          border: '1px solid #85858541',
          overflow: 'auto'
        }}
      />
    </Flex>
  )
}

TemplatePreview.propTypes = {
  loading: PropTypes.bool,
  objectData: PropTypes.object,
  documentTemplate: PropTypes.object,
  isEditing: PropTypes.bool,
  style: PropTypes.object,
  showTestObject: PropTypes.bool,
  onTestObjectOpen: PropTypes.func.isRequired,
  onPreviewMessage: PropTypes.func.isRequired,
  showPreviewSwitch: PropTypes.bool
}

export default TemplatePreview
