import { useCallback, useEffect, useState } from 'react'
import { save as saveDialog } from '@tauri-apps/plugin-dialog'
import { deleteSession, exportSession, listSessions, renameSession } from '../ipc'
import type { Config, SessionInfo } from '../types'
import { ConfirmDialog, Modal } from './Modal'
import { PreviewDialog } from './PreviewDialog'
import { IconDoc, IconEdit, IconEye, IconPlay, IconPlus, IconRefresh, IconTrash } from './Icons'

interface Props {
  projectPath: string
  config: Config
  onConfigChange: (c: Config) => void
  onNewSession: () => void
  onResume: (sessionId: string, title: string) => void
}

function formatTime(ms: number): string {
  if (!ms) return ''
  const d = new Date(ms)
  const pad = (n: number) => String(n).padStart(2, '0')
  return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}`
}

function formatSize(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 SessionList({ projectPath, config, onConfigChange, onNewSession, onResume }: Props) {
  const [sessions, setSessions] = useState<SessionInfo[]>([])
  const [filter, setFilter] = useState('')
  const [preview, setPreview] = useState<SessionInfo | null>(null)
  const [renaming, setRenaming] = useState<SessionInfo | null>(null)
  const [renameText, setRenameText] = useState('')
  const [deleting, setDeleting] = useState<SessionInfo | null>(null)

  const refresh = useCallback(() => {
    listSessions(projectPath).then(setSessions).catch(() => setSessions([]))
  }, [projectPath])

  useEffect(() => {
    refresh()
  }, [refresh])

  const titleOf = (s: SessionInfo) => config.titleOverrides[s.id] ?? s.title

  /** 导出为 Markdown：弹保存对话框后由 Rust 解析会话并写盘 */
  const doExport = async (s: SessionInfo) => {
    const safeName = titleOf(s).replace(/[\\/:*?"<>|]/g, '_').slice(0, 60)
    const dest = await saveDialog({
      title: '导出会话为 Markdown',
      defaultPath: `${safeName}.md`,
      filters: [{ name: 'Markdown', extensions: ['md'] }]
    })
    if (typeof dest === 'string' && dest) {
      await exportSession(projectPath, s.id, titleOf(s), dest)
    }
  }

  const shown = sessions.filter(
    (s) => !filter || titleOf(s).toLowerCase().includes(filter.toLowerCase())
  )

  return (
    <div className="page">
      <h2>历史会话</h2>
      <p className="page-desc">{projectPath}</p>
      <div className="toolbar">
        <button className="btn primary" onClick={onNewSession}>
          <IconPlus />
          新建会话
        </button>
        <button className="btn" title="刷新列表" onClick={refresh}>
          <IconRefresh />
        </button>
        <input
          className="input"
          style={{ width: 240 }}
          placeholder="按标题过滤"
          value={filter}
          onChange={(e) => setFilter(e.target.value)}
        />
        <div className="spacer" />
        <span style={{ color: 'var(--text-faint)', fontSize: 12 }}>{sessions.length} 个会话</span>
      </div>
      <div className="row-list">
        {shown.length === 0 && (
          <div className="empty-hint">{sessions.length === 0 ? '该项目还没有会话记录' : '没有匹配的会话'}</div>
        )}
        {shown.map((s) => (
          <div key={s.id} className="row">
            <div className="row-main">
              <div className="row-title">{titleOf(s)}</div>
              <div className="row-sub">
                {formatTime(s.mtime)} · {formatSize(s.size)} · {s.id}
              </div>
            </div>
            <div className="row-actions">
              <button className="btn small" title="恢复会话" onClick={() => onResume(s.id, titleOf(s))}>
                <IconPlay />
                恢复
              </button>
              <button className="btn small" title="只读预览" onClick={() => setPreview(s)}>
                <IconEye />
              </button>
              <button className="btn small" title="导出为 Markdown" onClick={() => void doExport(s)}>
                <IconDoc />
              </button>
              <button
                className="btn small"
                title="重命名（仅在 GUI 中生效）"
                onClick={() => {
                  setRenaming(s)
                  setRenameText(titleOf(s))
                }}
              >
                <IconEdit />
              </button>
              <button className="btn small danger" title="删除会话记录文件" onClick={() => setDeleting(s)}>
                <IconTrash />
              </button>
            </div>
          </div>
        ))}
      </div>

      {preview && (
        <PreviewDialog
          projectPath={projectPath}
          sessionId={preview.id}
          title={titleOf(preview)}
          onClose={() => setPreview(null)}
          onResume={() => {
            onResume(preview.id, titleOf(preview))
            setPreview(null)
          }}
        />
      )}

      {renaming && (
        <Modal
          title="重命名会话"
          onClose={() => setRenaming(null)}
          footer={
            <>
              <button className="btn" onClick={() => setRenaming(null)}>
                取消
              </button>
              <button
                className="btn primary"
                onClick={() => {
                  renameSession(renaming.id, renameText).then((c) => {
                    onConfigChange(c)
                    setRenaming(null)
                  })
                }}
              >
                保存
              </button>
            </>
          }
        >
          <p className="page-desc" style={{ marginTop: 0 }}>
            重命名仅影响 GUI 显示，不修改会话记录文件。清空则恢复原始标题。
          </p>
          <input
            className="input"
            style={{ width: '100%' }}
            value={renameText}
            autoFocus
            onChange={(e) => setRenameText(e.target.value)}
          />
        </Modal>
      )}

      {deleting && (
        <ConfirmDialog
          title="删除会话"
          message={`将永久删除会话记录文件：\n${titleOf(deleting)}\n\n此操作不可恢复。`}
          confirmText="删除"
          danger
          onCancel={() => setDeleting(null)}
          onConfirm={() => {
            deleteSession(projectPath, deleting.id).then(() => {
              setDeleting(null)
              refresh()
            })
          }}
        />
      )}
    </div>
  )
}
