import { create } from 'zustand'
import { HISTORY_MAX_ENTRIES, type HistoryEntry } from '@shared/ipc'
import { isPreview as PREVIEW } from '../isPreview'
import { logError } from '../reportError'
import { revealFile } from '../reveal'
import { createReconciler } from '../lib/reconcile'

// Mock history so the History tab has content during UI design. Gated on
// `import.meta.env.DEV` too so Rollup drops it from the production build (L128).
const seed: HistoryEntry[] =
  import.meta.env.DEV && PREVIEW
    ? [
        {
          id: 'h1',
          title: 'How yt-dlp Works Under the Hood',
          channel: 'Open Source Weekly',
          url: 'https://youtube.com/watch?v=zzz9999',
          kind: 'video',
          quality: '720p · mp4 · 184 MB',
          sizeLabel: '184 MB',
          filePath: 'C:\\Users\\you\\Downloads\\How yt-dlp Works Under the Hood.mp4',
          completedAt: Date.now() - 1000 * 60 * 42
        },
        {
          id: 'h2',
          title: 'Deep Focus — Ambient Mix',
          channel: 'ChillStudio',
          url: 'https://youtube.com/watch?v=aaa1111',
          kind: 'audio',
          quality: 'Best',
          sizeLabel: '142 MB',
          filePath: 'C:\\Users\\you\\Downloads\\Deep Focus — Ambient Mix.mp3',
          completedAt: Date.now() - 1000 * 60 * 60 * 26
        },
        {
          id: 'h3',
          title: 'Conference Keynote 2026 (Full)',
          channel: 'TechConf',
          url: 'https://youtube.com/watch?v=bbb2222',
          kind: 'video',
          quality: '1080p · mp4 · 1.2 GB',
          sizeLabel: '1.2 GB',
          filePath: 'C:\\Users\\you\\Downloads\\Conference Keynote 2026 (Full).mp4',
          completedAt: Date.now() - 1000 * 60 * 60 * 24 * 3
        }
      ]
    : []

// Cap the optimistic in-memory list at the same shared limit main persists to
// (HISTORY_MAX_ENTRIES) so a long session can't grow it past what a reload would
// show (L141). De-duping by url as well as id keeps it consistent with main's add
// (M35), so the optimistic list matches the reload.
interface HistoryState {
  entries: HistoryEntry[]
  add: (entry: HistoryEntry) => void
  remove: (id: string) => void
  removeMany: (ids: string[]) => void
  clear: () => void
  openFile: (id: string) => void
  showInFolder: (id: string) => void
}

// Every mutation applies main's authoritative return (validated/capped/de-duped)
// through a latest-wins reconciler, so the optimistic list can't silently diverge
// from what a reload would show (L142, the M34 pattern extended off settings).
const reconcile = createReconciler()

export const useHistory = create<HistoryState>((set, get) => ({
  entries: seed,

  add: (entry) => {
    set((s) => ({
      entries: [entry, ...s.entries.filter((e) => e.id !== entry.id && e.url !== entry.url)].slice(
        0,
        HISTORY_MAX_ENTRIES
      )
    }))
    if (!PREVIEW)
      reconcile(
        'entries',
        window.api.addHistory(entry),
        (entries) => set({ entries }),
        logError('addHistory')
      )
  },

  remove: (id) => {
    set((s) => ({ entries: s.entries.filter((e) => e.id !== id) }))
    if (!PREVIEW)
      reconcile(
        'entries',
        window.api.removeHistory(id),
        (entries) => set({ entries }),
        logError('removeHistory')
      )
  },

  removeMany: (ids) => {
    const remove = new Set(ids)
    set((s) => ({ entries: s.entries.filter((e) => !remove.has(e.id)) }))
    if (!PREVIEW)
      reconcile(
        'entries',
        window.api.removeManyHistory(ids),
        (entries) => set({ entries }),
        logError('removeManyHistory')
      )
  },

  clear: () => {
    set({ entries: [] })
    if (!PREVIEW)
      reconcile(
        'entries',
        window.api.clearHistory(),
        (entries) => set({ entries }),
        logError('clearHistory')
      )
  },

  openFile: (id) => {
    const e = get().entries.find((x) => x.id === id)
    if (!PREVIEW && e?.filePath) revealFile('open', e.filePath)
  },

  showInFolder: (id) => {
    const e = get().entries.find((x) => x.id === id)
    if (!PREVIEW && e?.filePath) revealFile('folder', e.filePath)
  }
}))

// Load persisted history on startup.
if (!PREVIEW) {
  window.api.listHistory().then((entries) => useHistory.setState({ entries }))
}
