import { useEffect, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import type { TimelineConflict, TimelineEntry } from '@shared/timeline'
import { useAppStore } from '@renderer/stores/useAppStore'
import { useBookStore } from '@renderer/stores/useBookStore'
import { useEditStore } from '@renderer/stores/useEditStore'
import { ipcCall } from '@renderer/lib/ipc-client'

export function TimelineModal(): React.JSX.Element | null {
  const { t } = useTranslation()
  const open = useAppStore((s) => s.timelineModalOpen)
  const setOpen = useAppStore((s) => s.setTimelineModalOpen)
  const bookId = useBookStore((s) => s.currentBookId)
  const settings = useBookStore((s) => s.settings)
  const switchTarget = useEditStore((s) => s.switchTarget)
  const [entries, setEntries] = useState<TimelineEntry[]>([])
  const [conflicts, setConflicts] = useState<TimelineConflict[]>([])
  const [loading, setLoading] = useState(false)

  const conflictChapterIds = useMemo(
    () => new Set(conflicts.map((c) => c.chapterId)),
    [conflicts]
  )

  useEffect(() => {
    if (!open || !bookId) return
    setLoading(true)
    void Promise.all([
      ipcCall(() => window.electronAPI.timeline.list(bookId)),
      ipcCall(() => window.electronAPI.timeline.conflicts(bookId))
    ])
      .then(([list, conf]) => {
        setEntries(list)
        setConflicts(conf)
      })
      .finally(() => setLoading(false))
  }, [open, bookId])

  const handleJump = async (entry: TimelineEntry): Promise<void> => {
    if (!entry.chapterId) return
    await switchTarget({ kind: 'chapter', id: entry.chapterId })
    setOpen(false)
  }

  const handleAddEvent = async (): Promise<void> => {
    if (!bookId) return
    const title = window.prompt(t('timeline.eventTitlePrompt'))
    if (!title?.trim()) return
    const storyTime = window.prompt(t('timeline.storyTimePrompt')) ?? ''
    await ipcCall(() =>
      window.electronAPI.timeline.upsert(bookId, {
        title: title.trim(),
        storyTime: storyTime.trim() || null
      })
    )
    const list = await ipcCall(() => window.electronAPI.timeline.list(bookId))
    setEntries(list)
  }

  if (!open) return null

  return (
    <div className="modal-overlay" data-testid="timeline-modal" role="dialog" aria-modal="true">
      <div className="modal-content modal-content--wide">
        <div className="modal-header">
          <h3>{t('timeline.title')}</h3>
          <button type="button" className="modal-close" onClick={() => setOpen(false)}>
            ✕
          </button>
        </div>
        <div className="modal-body">
          {loading ? (
            <p>{t('cockpit.loading')}</p>
          ) : (
            <div className="timeline-list" data-testid="timeline-list">
              {entries.map((entry) => {
                const conflict = conflicts.find((c) => c.chapterId === entry.chapterId)
                const isConflict = entry.chapterId && conflictChapterIds.has(entry.chapterId)
                return (
                  <div
                    key={entry.id}
                    className={`timeline-item ${isConflict ? 'timeline-item--conflict' : ''}`}
                    data-testid={`timeline-item-${entry.id}`}
                  >
                    <div className="timeline-item-main">
                      <strong>{entry.title}</strong>
                      <span className="timeline-item-meta">
                        {entry.storyTime ? entry.storyTime : t('timeline.noTime')}
                        {entry.kind === 'manual' ? ` · ${t('timeline.manual')}` : ''}
                      </span>
                    </div>
                    {conflict && (
                      <div className="timeline-conflict-msg" data-testid="timeline-conflict-msg">
                        {conflict.message}
                      </div>
                    )}
                    {entry.chapterId && (
                      <button type="button" className="btn" onClick={() => void handleJump(entry)}>
                        {t('timeline.jumpChapter')}
                      </button>
                    )}
                  </div>
                )
              })}
              {entries.length === 0 && <p className="text-muted">{t('timeline.empty')}</p>}
            </div>
          )}
          {settings.filter((s) => s.type === 'character').length > 0 && (
            <p className="text-muted" style={{ marginTop: 12, fontSize: 12 }}>
              {t('timeline.characterHint')}
            </p>
          )}
        </div>
        <div className="modal-footer">
          <button type="button" className="btn" onClick={() => void handleAddEvent()}>
            {t('timeline.addEvent')}
          </button>
          <button type="button" className="btn btn-primary" onClick={() => setOpen(false)}>
            {t('dialog.cancel')}
          </button>
        </div>
      </div>
    </div>
  )
}
