/**
 * Review System State Management (Zustand)
 */
import { create } from 'zustand'
import { reviewService, ReviewConfiguration, ReviewResult, ReviewRule, CreateRuleRequest, UpdateRuleRequest, ReviewPreset } from '@/services/reviewService'

interface ReviewStore {
  // State
  projectId: string | null
  configuration: ReviewConfiguration | null
  currentResult: ReviewResult | null
  ruleTemplates: ReviewRule[]
  testResult: any

  loading: boolean
  error: string | null

  // Actions
  setProjectId: (projectId: string | null) => void

  // Configuration
  fetchConfiguration: (projectId: string) => Promise<void>
  updateConfiguration: (projectId: string, data: Partial<ReviewConfiguration>) => Promise<void>
  applyPreset: (projectId: string, preset: ReviewPreset) => Promise<void>

  // Rules
  fetchRules: (projectId: string) => Promise<void>
  fetchRuleTemplates: () => Promise<void>
  createRule: (projectId: string, data: CreateRuleRequest) => Promise<ReviewRule>
  updateRule: (projectId: string, ruleId: string, data: UpdateRuleRequest) => Promise<void>
  deleteRule: (projectId: string, ruleId: string) => Promise<void>
  testRule: (projectId: string, rule: ReviewRule, sampleContent: string) => Promise<void>

  // Review Execution
  executeReview: (projectId: string, episodeNumber?: number) => Promise<void>
  fetchLatestResult: (projectId: string, episodeNumber?: number) => Promise<void>

  // Issue Management
  ignoreIssue: (projectId: string, issueId: string) => Promise<void>
  unignoreIssue: (projectId: string, issueId: string) => Promise<void>
  autoFixIssue: (projectId: string, issueId: string) => Promise<void>
  applyBatchDecisions: (projectId: string, decisions: { issueId: string; action: 'accept' | 'reject' | 'ignore' }[]) => Promise<void>

  // Export
  exportReport: (projectId: string, reviewId: string, format: 'json' | 'pdf' | 'markdown', includeIgnored?: boolean) => Promise<void>

  // Clear
  clearReview: () => void
}

export const useReviewStore = create<ReviewStore>((set, get) => ({
  // Initial State with default configuration
  projectId: null,
  configuration: {
    preset: 'standard',
    dimensions: {
      character_consistency: { name: '角色一致性', enabled: true, strictness: 50, weight: 0.8 },
      plot_coherence: { name: '剧情连贯性', enabled: true, strictness: 50, weight: 0.9 },
      dialogue_quality: { name: '对话质量', enabled: true, strictness: 50, weight: 0.7 },
      pacing: { name: '节奏控制', enabled: true, strictness: 50, weight: 0.6 },
      emotional_depth: { name: '情感深度', enabled: true, strictness: 50, weight: 0.7 },
      thematic_strength: { name: '主题强度', enabled: true, strictness: 50, weight: 0.8 }
    },
    customRules: [],
    createdAt: new Date().toISOString(),
    updatedAt: new Date().toISOString()
  },
  currentResult: null,
  ruleTemplates: [],
  testResult: null,
  loading: false,
  error: null,

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

  // Configuration
  fetchConfiguration: async (projectId) => {
    set({ loading: true, error: null, projectId })
    try {
      const configuration = await reviewService.getConfiguration(projectId)
      set({ configuration, loading: false })
    } catch (error) {
      set({ error: (error as Error).message, loading: false })
    }
  },

  updateConfiguration: async (projectId, data) => {
    set({ loading: true, error: null })
    try {
      const configuration = await reviewService.updateConfiguration(projectId, data)
      set({ configuration, loading: false })
    } catch (error) {
      set({ error: (error as Error).message, loading: false })
    }
  },

  applyPreset: async (projectId, preset) => {
    set({ loading: true, error: null })
    try {
      const configuration = await reviewService.applyPreset(projectId, preset)
      set({ configuration, loading: false })
    } catch (error) {
      set({ error: (error as Error).message, loading: false })
    }
  },

  // Rules
  fetchRules: async (projectId) => {
    set({ loading: true, error: null })
    try {
      const rules = await reviewService.getRules(projectId)
      set((state) => ({
        configuration: state.configuration ? { ...state.configuration, customRules: rules } : null,
        loading: false
      }))
    } catch (error) {
      set({ error: (error as Error).message, loading: false })
    }
  },

  fetchRuleTemplates: async () => {
    // Don't set loading state for rule templates as it's not critical
    try {
      const ruleTemplates = await reviewService.getRuleTemplates()
      set({ ruleTemplates })
    } catch (error) {
      // Silently fail for rule templates - not critical for core functionality
      console.warn('Failed to fetch rule templates:', error)
      set({ ruleTemplates: [] })
    }
  },

  createRule: async (projectId, data) => {
    set({ loading: true, error: null })
    try {
      const rule = await reviewService.createRule(projectId, data)
      set((state) => ({
        configuration: state.configuration
          ? { ...state.configuration, customRules: [...state.configuration.customRules, rule] }
          : null,
        loading: false
      }))
      return rule
    } catch (error) {
      set({ error: (error as Error).message, loading: false })
      throw error
    }
  },

  updateRule: async (projectId, ruleId, data) => {
    set({ loading: true, error: null })
    try {
      const updatedRule = await reviewService.updateRule(projectId, ruleId, data)
      set((state) => ({
        configuration: state.configuration
          ? {
              ...state.configuration,
              customRules: state.configuration.customRules.map(r => r.id === ruleId ? updatedRule : r)
            }
          : null,
        loading: false
      }))
    } catch (error) {
      set({ error: (error as Error).message, loading: false })
    }
  },

  deleteRule: async (projectId, ruleId) => {
    set({ loading: true, error: null })
    try {
      await reviewService.deleteRule(projectId, ruleId)
      set((state) => ({
        configuration: state.configuration
          ? { ...state.configuration, customRules: state.configuration.customRules.filter(r => r.id !== ruleId) }
          : null,
        loading: false
      }))
    } catch (error) {
      set({ error: (error as Error).message, loading: false })
    }
  },

  testRule: async (projectId, rule, sampleContent) => {
    set({ loading: true, error: null, testResult: null })
    try {
      const testResult = await reviewService.testRule(projectId, { rule, sampleContent })
      set({ testResult, loading: false })
    } catch (error) {
      set({ error: (error as Error).message, loading: false })
    }
  },

  clearTestResult: () => set({ testResult: null }),

  // Review Execution
  executeReview: async (projectId, episodeNumber) => {
    set({ loading: true, error: null })
    try {
      const currentResult = await reviewService.executeReview(projectId, { episodeNumber })
      set({ currentResult, loading: false })
    } catch (error) {
      set({ error: (error as Error).message, loading: false })
    }
  },

  fetchLatestResult: async (projectId, episodeNumber) => {
    set({ loading: true, error: null })
    try {
      const currentResult = await reviewService.getLatestReviewResult(projectId, episodeNumber)
      set({ currentResult, loading: false })
    } catch (error) {
      set({ error: (error as Error).message, loading: false })
    }
  },

  // Issue Management
  ignoreIssue: async (projectId, issueId) => {
    set({ loading: true, error: null })
    try {
      await reviewService.ignoreIssue(projectId, issueId)
      set((state) => ({
        currentResult: state.currentResult
          ? {
              ...state.currentResult,
              issues: state.currentResult.issues.map(i =>
                i.id === issueId ? { ...i, ignored: true } : i
              )
            }
          : null,
        loading: false
      }))
    } catch (error) {
      set({ error: (error as Error).message, loading: false })
    }
  },

  unignoreIssue: async (projectId, issueId) => {
    set({ loading: true, error: null })
    try {
      await reviewService.unignoreIssue(projectId, issueId)
      set((state) => ({
        currentResult: state.currentResult
          ? {
              ...state.currentResult,
              issues: state.currentResult.issues.map(i =>
                i.id === issueId ? { ...i, ignored: false } : i
              )
            }
          : null,
        loading: false
      }))
    } catch (error) {
      set({ error: (error as Error).message, loading: false })
    }
  },

  autoFixIssue: async (projectId, issueId) => {
    set({ loading: true, error: null })
    try {
      const result = await reviewService.autoFixIssue(projectId, issueId)
      if (result.fixed && result.fixedText) {
        set((state) => ({
          currentResult: state.currentResult
            ? {
                ...state.currentResult,
                issues: state.currentResult.issues.map(i =>
                  i.id === issueId ? { ...i, originalText: result.fixedText! } : i
                )
              }
            : null,
          loading: false
        }))
      } else {
        set({ loading: false })
      }
    } catch (error) {
      set({ error: (error as Error).message, loading: false })
    }
  },

  applyBatchDecisions: async (projectId, decisions) => {
    set({ loading: true, error: null })
    try {
      await reviewService.applyBatchDecisions(projectId, decisions)
      await get().fetchLatestResult(projectId)
    } catch (error) {
      set({ error: (error as Error).message, loading: false })
    }
  },

  // Export
  exportReport: async (projectId, reviewId, format, includeIgnored = false) => {
    set({ loading: true, error: null })
    try {
      const blob = await reviewService.exportReport(projectId, reviewId, { format, includeIgnored })
      const url = window.URL.createObjectURL(blob)
      const a = document.createElement('a')
      a.href = url
      a.download = `review-report.${format}`
      document.body.appendChild(a)
      a.click()
      document.body.removeChild(a)
      window.URL.revokeObjectURL(url)
      set({ loading: false })
    } catch (error) {
      set({ error: (error as Error).message, loading: false })
    }
  },

  // Clear
  clearReview: () => set({
    projectId: null,
    configuration: null,
    currentResult: null,
    ruleTemplates: [],
    testResult: null,
    error: null
  })
}))
