/**
 * Memory System State Management (Zustand)
 */
import { create } from 'zustand'
import { memoryService, MemorySystem, TimelineEvent, PendingThread, CharacterState, Foreshadowing, Relationship, CreateThreadRequest, UpdateThreadRequest, CreateForeshadowingRequest, ImportanceLevel } from '@/services/memoryService'

interface MemoryStore {
  // State
  projectId: string | null
  memorySystem: MemorySystem | null
  timeline: TimelineEvent[]
  threads: PendingThread[]
  characterStates: CharacterState[]
  foreshadowing: Foreshadowing[]
  relationships: Relationship[]
  statistics: MemorySystem | null

  loading: boolean
  error: string | null

  // Filters
  timelineFilters: {
    character?: string
    episode?: number
    importance?: ImportanceLevel
  }

  // Actions
  setProjectId: (projectId: string | null) => void
  fetchMemorySystem: (projectId: string) => Promise<void>
  fetchTimeline: (projectId: string, filters?: { character?: string; episode?: number; importance?: ImportanceLevel }) => Promise<void>
  fetchThreads: (projectId: string) => Promise<void>
  fetchCharacterStates: (projectId: string) => Promise<void>
  fetchForeshadowing: (projectId: string) => Promise<void>
  fetchRelationships: (projectId: string) => Promise<void>
  fetchStatistics: (projectId: string) => Promise<void>

  // Thread Actions
  createThread: (projectId: string, data: CreateThreadRequest) => Promise<PendingThread>
  updateThread: (projectId: string, threadId: string, data: UpdateThreadRequest) => Promise<void>
  deleteThread: (projectId: string, threadId: string) => Promise<void>
  resolveThread: (projectId: string, threadId: string) => Promise<void>

  // Foreshadowing Actions
  createForeshadowing: (projectId: string, data: CreateForeshadowingRequest) => Promise<Foreshadowing>
  updateForeshadowing: (projectId: string, foreshadowingId: string, data: any) => Promise<void>
  deleteForeshadowing: (projectId: string, foreshadowingId: string) => Promise<void>

  // Relationship Actions
  updateRelationship: (projectId: string, sourceCharacter: string, targetCharacter: string, data: any) => Promise<void>

  // Character Actions
  updateCharacterState: (projectId: string, characterName: string, state: string) => Promise<void>

  // Filter Actions
  setTimelineFilters: (filters: { character?: string; episode?: number; importance?: ImportanceLevel }) => void
  clearTimelineFilters: () => void

  // Clear
  clearMemory: () => void
}

export const useMemoryStore = create<MemoryStore>((set, get) => ({
  // Initial State
  projectId: null,
  memorySystem: null,
  timeline: [],
  threads: [],
  characterStates: [],
  foreshadowing: [],
  relationships: [],
  statistics: null,
  loading: false,
  error: null,
  timelineFilters: {},

  // Actions
  setProjectId: (projectId) => set({ projectId }),

  fetchMemorySystem: async (projectId) => {
    set({ loading: true, error: null, projectId })
    try {
      const memorySystem = await memoryService.getMemory(projectId)
      set({
        memorySystem,
        timeline: memorySystem.timeline,
        threads: memorySystem.pendingThreads,
        characterStates: memorySystem.characterStates,
        foreshadowing: memorySystem.foreshadowing,
        relationships: memorySystem.relationships,
        statistics: memorySystem.statistics,
        loading: false
      })
    } catch (error) {
      set({ error: (error as Error).message, loading: false })
    }
  },

  fetchTimeline: async (projectId, filters) => {
    set({ loading: true, error: null })
    try {
      const timeline = await memoryService.getTimeline(projectId, filters)
      set({ timeline, loading: false })
    } catch (error) {
      set({ error: (error as Error).message, loading: false })
    }
  },

  fetchThreads: async (projectId) => {
    set({ loading: true, error: null })
    try {
      const threads = await memoryService.getThreads(projectId)
      set({ threads, loading: false })
    } catch (error) {
      set({ error: (error as Error).message, loading: false })
    }
  },

  fetchCharacterStates: async (projectId) => {
    set({ loading: true, error: null })
    try {
      const characterStates = await memoryService.getCharacterStates(projectId)
      set({ characterStates, loading: false })
    } catch (error) {
      set({ error: (error as Error).message, loading: false })
    }
  },

  fetchForeshadowing: async (projectId) => {
    set({ loading: true, error: null })
    try {
      const foreshadowing = await memoryService.getForeshadowing(projectId)
      set({ foreshadowing, loading: false })
    } catch (error) {
      set({ error: (error as Error).message, loading: false })
    }
  },

  fetchRelationships: async (projectId) => {
    set({ loading: true, error: null })
    try {
      const relationships = await memoryService.getRelationships(projectId)
      set({ relationships, loading: false })
    } catch (error) {
      set({ error: (error as Error).message, loading: false })
    }
  },

  fetchStatistics: async (projectId) => {
    set({ loading: true, error: null })
    try {
      const statistics = await memoryService.getStatistics(projectId)
      set({ statistics, loading: false })
    } catch (error) {
      set({ error: (error as Error).message, loading: false })
    }
  },

  // Thread Actions
  createThread: async (projectId, data) => {
    set({ loading: true, error: null })
    try {
      const thread = await memoryService.createThread(projectId, data)
      set((state) => ({
        threads: [...state.threads, thread],
        loading: false
      }))
      return thread
    } catch (error) {
      set({ error: (error as Error).message, loading: false })
      throw error
    }
  },

  updateThread: async (projectId, threadId, data) => {
    set({ loading: true, error: null })
    try {
      const updatedThread = await memoryService.updateThread(projectId, threadId, data)
      set((state) => ({
        threads: state.threads.map(t => t.id === threadId ? updatedThread : t),
        loading: false
      }))
    } catch (error) {
      set({ error: (error as Error).message, loading: false })
    }
  },

  deleteThread: async (projectId, threadId) => {
    set({ loading: true, error: null })
    try {
      await memoryService.deleteThread(projectId, threadId)
      set((state) => ({
        threads: state.threads.filter(t => t.id !== threadId),
        loading: false
      }))
    } catch (error) {
      set({ error: (error as Error).message, loading: false })
    }
  },

  resolveThread: async (projectId, threadId) => {
    set({ loading: true, error: null })
    try {
      const resolvedThread = await memoryService.resolveThread(projectId, threadId)
      set((state) => ({
        threads: state.threads.map(t => t.id === threadId ? resolvedThread : t),
        loading: false
      }))
    } catch (error) {
      set({ error: (error as Error).message, loading: false })
    }
  },

  // Foreshadowing Actions
  createForeshadowing: async (projectId, data) => {
    set({ loading: true, error: null })
    try {
      const foreshadowing = await memoryService.createForeshadowing(projectId, data)
      set((state) => ({
        foreshadowing: [...state.foreshadowing, foreshadowing],
        loading: false
      }))
      return foreshadowing
    } catch (error) {
      set({ error: (error as Error).message, loading: false })
      throw error
    }
  },

  updateForeshadowing: async (projectId, foreshadowingId, data) => {
    set({ loading: true, error: null })
    try {
      const updated = await memoryService.updateForeshadowing(projectId, foreshadowingId, data)
      set((state) => ({
        foreshadowing: state.foreshadowing.map(f => f.id === foreshadowingId ? updated : f),
        loading: false
      }))
    } catch (error) {
      set({ error: (error as Error).message, loading: false })
    }
  },

  deleteForeshadowing: async (projectId, foreshadowingId) => {
    set({ loading: true, error: null })
    try {
      await memoryService.deleteForeshadowing(projectId, foreshadowingId)
      set((state) => ({
        foreshadowing: state.foreshadowing.filter(f => f.id !== foreshadowingId),
        loading: false
      }))
    } catch (error) {
      set({ error: (error as Error).message, loading: false })
    }
  },

  // Relationship Actions
  updateRelationship: async (projectId, sourceCharacter, targetCharacter, data) => {
    set({ loading: true, error: null })
    try {
      const updated = await memoryService.updateRelationship(projectId, sourceCharacter, targetCharacter, data)
      set((state) => ({
        relationships: state.relationships.map(r =>
          r.sourceCharacter === sourceCharacter && r.targetCharacter === targetCharacter ? updated : r
        ),
        loading: false
      }))
    } catch (error) {
      set({ error: (error as Error).message, loading: false })
    }
  },

  // Character Actions
  updateCharacterState: async (projectId, characterName, state) => {
    set({ loading: true, error: null })
    try {
      const updated = await memoryService.updateCharacterState(projectId, characterName, state)
      set((state) => ({
        characterStates: state.characterStates.map(cs =>
          cs.characterName === characterName ? updated : cs
        ),
        loading: false
      }))
    } catch (error) {
      set({ error: (error as Error).message, loading: false })
    }
  },

  // Filter Actions
  setTimelineFilters: (filters) => set({ timelineFilters: filters }),

  clearTimelineFilters: () => set({ timelineFilters: {} }),

  // Clear
  clearMemory: () => set({
    projectId: null,
    memorySystem: null,
    timeline: [],
    threads: [],
    characterStates: [],
    foreshadowing: [],
    relationships: [],
    statistics: null,
    error: null,
    timelineFilters: {}
  })
}))
