import { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import type { ImportPreviewResult, ImportSplitMode } from '@shared/types'
import { useAppStore } from '@renderer/stores/useAppStore'
import { useBookStore } from '@renderer/stores/useBookStore'
import { useTabStore } from '@renderer/stores/useTabStore'
import { ipcCall } from '@renderer/lib/ipc-client'

const LARGE_FILE_BYTES = 20 * 1024 * 1024

function formatFileSize(bytes: number): string {
  if (bytes < 1024) return `${bytes} B`
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`
  return `${(bytes / (1024 * 1024)).toFixed(1)} MB`
}

export function ImportBookModal(): React.JSX.Element | null {
  const { t } = useTranslation()
  const open = useAppStore((s) => s.importBookModalOpen)
  const setOpen = useAppStore((s) => s.setImportBookModalOpen)
  const showToast = useAppStore((s) => s.showToast)
  const setView = useAppStore((s) => s.setView)
  const { loadBooks, openBook } = useBookStore()
  const { openBookTab } = useTabStore()

  const [filePath, setFilePath] = useState('')
  const [fileName, setFileName] = useState('')
  const [bookName, setBookName] = useState('')
  const [category, setCategory] = useState('玄幻')
  const [splitMode, setSplitMode] = useState<ImportSplitMode>('auto')
  const [customRegex, setCustomRegex] = useState('')
  const [preview, setPreview] = useState<ImportPreviewResult | null>(null)
  const [importing, setImporting] = useState(false)
  const [progress, setProgress] = useState<{ current: number; total: number } | null>(null)

  useEffect(() => {
    if (!open) return
    setFilePath('')
    setFileName('')
    setBookName('')
    setCategory('玄幻')
    setSplitMode('auto')
    setCustomRegex('')
    setPreview(null)
    setProgress(null)
  }, [open])

  useEffect(() => {
    if (!open) return
    const unsub = window.electronAPI.onImportProgress((payload) => {
      setProgress(payload)
    })
    return unsub
  }, [open])

  const handlePickFile = async (): Promise<void> => {
    const result = await ipcCall(() => window.electronAPI.import.pickFile())
    if (result.canceled || !result.filePath) return
    setFilePath(result.filePath)
    const name = result.filePath.split(/[/\\]/).pop() ?? ''
    setFileName(name)
    const baseName = name.replace(/\.(txt|md|docx)$/i, '')
    if (!bookName.trim()) setBookName(baseName)
  }

  const handlePreview = async (): Promise<void> => {
    if (!filePath) return
    const result = await ipcCall(() =>
      window.electronAPI.import.preview(filePath, splitMode, customRegex || undefined)
    )
    setPreview(result)
  }

  const handleImport = async (): Promise<void> => {
    if (!filePath || !bookName.trim()) return
    if (preview && preview.fileSizeBytes > LARGE_FILE_BYTES) {
      const ok = confirm(
        t('import.largeFileConfirm', { size: formatFileSize(preview.fileSizeBytes) })
      )
      if (!ok) return
    }
    setImporting(true)
    setProgress(null)
    try {
      if (!preview) await handlePreview()
      const bookId = await ipcCall(() =>
        window.electronAPI.import.execute({
          filePath,
          bookName: bookName.trim(),
          category,
          splitMode,
          customRegex: customRegex || undefined
        })
      )
      await loadBooks()
      const meta = useBookStore.getState().books.find((b) => b.id === bookId)
      await openBook(bookId)
      openBookTab(bookId, meta?.name ?? bookName.trim())
      setView('editor')
      showToast(t('import.success'))
      setOpen(false)
    } catch {
      showToast(t('import.failed'))
    } finally {
      setImporting(false)
      setProgress(null)
    }
  }

  if (!open) return null

  const previewTitles = preview?.chapters.slice(0, 5).map((ch) => ch.title) ?? []

  return (
    <div
      className="modal-overlay"
      id="importModal"
      data-testid="import-book-modal"
      role="dialog"
      aria-modal="true"
      aria-label={t('import.title')}
    >
      <div className="modal-content modal-content--wide">
        <div className="modal-header">
          <h3>{t('import.title')}</h3>
          <button type="button" className="modal-close" onClick={() => setOpen(false)}>
            ✕
          </button>
        </div>
        <div className="modal-body">
          <div className="import-file-row">
            <input
              className="form-control"
              readOnly
              value={fileName || t('import.noFile')}
              data-testid="import-file-path"
            />
            <button
              type="button"
              className="btn"
              data-testid="import-pick-file"
              onClick={() => void handlePickFile()}
            >
              {t('import.pickFile')}
            </button>
          </div>
          <label className="form-label">{t('dialog.newBook.name')}</label>
          <input
            className="form-control form-control--wide"
            data-testid="import-book-name"
            value={bookName}
            onChange={(e) => setBookName(e.target.value)}
          />
          <label className="form-label">{t('dialog.newBook.category')}</label>
          <input
            className="form-control form-control--wide"
            data-testid="import-book-category"
            value={category}
            onChange={(e) => setCategory(e.target.value)}
          />
          <label className="form-label">{t('import.splitMode')}</label>
          <select
            className="form-control form-control--wide"
            data-testid="import-split-mode"
            value={splitMode}
            onChange={(e) => setSplitMode(e.target.value as ImportSplitMode)}
          >
            <option value="auto">{t('import.splitAuto')}</option>
            <option value="paragraph">{t('import.splitParagraph')}</option>
            <option value="regex">{t('import.splitRegex')}</option>
          </select>
          {splitMode === 'regex' && (
            <>
              <label className="form-label">{t('import.customRegex')}</label>
              <input
                className="form-control form-control--wide"
                data-testid="import-custom-regex"
                value={customRegex}
                onChange={(e) => setCustomRegex(e.target.value)}
                placeholder="^第.+章"
              />
            </>
          )}
          <button
            type="button"
            className="btn"
            data-testid="import-preview-btn"
            disabled={!filePath}
            onClick={() => void handlePreview()}
          >
            {t('import.preview')}
          </button>
          {preview && (
            <div className="import-preview" data-testid="import-preview">
              <p>
                {t('import.chapterCount', { count: preview.chapters.length })}
                {preview.warnings.length > 0 && ` (${preview.warnings.join(', ')})`}
              </p>
              <ul className="import-preview-list">
                {previewTitles.map((title, i) => (
                  <li key={i}>{title}</li>
                ))}
              </ul>
            </div>
          )}
          {progress && (
            <div className="import-progress" data-testid="import-progress-bar">
              <div
                className="import-progress-fill"
                style={{ width: `${(progress.current / progress.total) * 100}%` }}
              />
              <span>{t('import.progress', { current: progress.current, total: progress.total })}</span>
            </div>
          )}
        </div>
        <div className="modal-footer">
          <button type="button" className="btn" onClick={() => setOpen(false)}>
            {t('dialog.cancel')}
          </button>
          <button
            type="button"
            className="btn btn-primary"
            data-testid="import-execute-btn"
            disabled={!filePath || !bookName.trim() || importing}
            onClick={() => void handleImport()}
          >
            {importing ? t('import.importing') : t('import.start')}
          </button>
        </div>
      </div>
    </div>
  )
}
