import { create } from 'zustand'
import { persist } from 'zustand/middleware'

/**
 * Letterboxd-flavoured watch diary. Each entry is a dated record of a
 * single watch session with optional rating + note + emoji. Entries
 * are append-only; older ones aren't mutated when newer ones arrive,
 * so a "watched it again" entry sits beside the original without
 * overwriting context.
 *
 * Storage shape: a single `entries` array, sorted newest-first when
 * read via the convenience selectors.
 */

export interface DiaryEntry {
  id: string
  itemId: string
  itemName: string
  /** ISO timestamp when the watch happened (defaults to now on creation). */
  watchedAt: string
  /** Optional 1-10 rating attached to this specific watch. */
  rating?: number
  /** Free-text note. */
  note?: string
  /** Single emoji glyph. We don't validate; the picker constrains it. */
  emoji?: string
  /** Whether this watch was logged as a rewatch. Mirrors personal-data
   *  but kept here too so diary stats can sum cleanly without joining. */
  rewatch?: boolean
}

interface State {
  entries: DiaryEntry[]
  add: (entry: Omit<DiaryEntry, 'id' | 'watchedAt'> & { watchedAt?: string }) => DiaryEntry
  update: (id: string, patch: Partial<Omit<DiaryEntry, 'id'>>) => void
  remove: (id: string) => void
  /** Convenience: chronological for an item, newest-first. */
  byItem: (itemId: string) => DiaryEntry[]
}

function uid() {
  return 'd_' + Math.random().toString(36).slice(2, 10) + Date.now().toString(36)
}

export const useDiary = create<State>()(
  persist(
    (set, get) => ({
      entries: [],
      add: input => {
        const entry: DiaryEntry = {
          id: uid(),
          watchedAt: input.watchedAt || new Date().toISOString(),
          itemId: input.itemId,
          itemName: input.itemName,
          rating: input.rating,
          note: input.note,
          emoji: input.emoji,
          rewatch: input.rewatch,
        }
        set(s => ({ entries: [...s.entries, entry] }))
        return entry
      },
      update: (id, patch) =>
        set(s => ({
          entries: s.entries.map(e => (e.id === id ? { ...e, ...patch } : e)),
        })),
      remove: id =>
        set(s => ({ entries: s.entries.filter(e => e.id !== id) })),
      byItem: itemId =>
        get().entries
          .filter(e => e.itemId === itemId)
          .sort((a, b) => b.watchedAt.localeCompare(a.watchedAt)),
    }),
    { name: 'diary-v1' },
  ),
)
