import { create } from 'zustand'
import { persist } from 'zustand/middleware'
import { User, AuthTokens } from '@/types/auth'

interface AuthState {
  user: User | null
  token: string | null
  refreshToken: string | null
  isAuthenticated: boolean
  isLoading: boolean
  error: string | null
  
  // Actions
  login: (email: string, password: string) => Promise<void>
  logout: () => Promise<void>
  register: (data: RegisterData) => Promise<void>
  refreshTokens: () => Promise<void>
  updateProfile: (data: Partial<User>) => Promise<void>
  changePassword: (currentPassword: string, newPassword: string) => Promise<void>
  resetPassword: (email: string) => Promise<void>
  confirmPasswordReset: (token: string, newPassword: string) => Promise<void>
  clearError: () => void
  setLoading: (loading: boolean) => void
}

interface RegisterData {
  email: string
  password: string
  name: string
  terms: boolean
}

export const useAuthStore = create<AuthState>()(
  persist(
    (set, get) => ({
      user: null,
      token: null,
      refreshToken: null,
      isAuthenticated: false,
      isLoading: false,
      error: null,

      login: async (email: string, password: string) => {
        set({ isLoading: true, error: null })
        
        try {
          const response = await fetch('/api/auth/login', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ email, password })
          })

          const data = await response.json()
          
          if (data.success) {
            set({
              user: data.data.user,
              token: data.data.tokens.accessToken,
              refreshToken: data.data.tokens.refreshToken,
              isAuthenticated: true,
              isLoading: false,
              error: null
            })
          } else {
            throw new Error(data.error || '登录失败')
          }
        } catch (error: any) {
          set({
            error: error.message,
            isLoading: false
          })
          throw error
        }
      },

      register: async (data: RegisterData) => {
        set({ isLoading: true, error: null })
        
        try {
          const response = await fetch('/api/auth/register', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify(data)
          })

          const result = await response.json()
          
          if (result.success) {
            set({
              user: result.data.user,
              token: result.data.tokens.accessToken,
              refreshToken: result.data.tokens.refreshToken,
              isAuthenticated: true,
              isLoading: false,
              error: null
            })
          } else {
            throw new Error(result.error || '注册失败')
          }
        } catch (error: any) {
          set({
            error: error.message,
            isLoading: false
          })
          throw error
        }
      },

      logout: async () => {
        const { token } = get()
        
        try {
          if (token) {
            await fetch('/api/auth/logout', {
              method: 'POST',
              headers: {
                'Authorization': `Bearer ${token}`,
                'Content-Type': 'application/json'
              }
            })
          }
        } catch (error) {
          console.error('Logout error:', error)
        } finally {
          set({
            user: null,
            token: null,
            refreshToken: null,
            isAuthenticated: false,
            error: null
          })
        }
      },

      refreshTokens: async () => {
        const { refreshToken } = get()
        
        if (!refreshToken) {
          throw new Error('No refresh token available')
        }

        try {
          const response = await fetch('/api/auth/refresh', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ refreshToken })
          })

          const data = await response.json()
          
          if (data.success) {
            set({
              token: data.data.accessToken,
              refreshToken: data.data.refreshToken
            })
          } else {
            throw new Error(data.error || '令牌刷新失败')
          }
        } catch (error) {
          // 刷新失败，清除认证状态
          set({
            user: null,
            token: null,
            refreshToken: null,
            isAuthenticated: false,
            error: '会话已过期，请重新登录'
          })
          throw error
        }
      },

      updateProfile: async (profileData: Partial<User>) => {
        const { token } = get()
        set({ isLoading: true, error: null })
        
        try {
          const response = await fetch('/api/auth/profile', {
            method: 'PUT',
            headers: {
              'Content-Type': 'application/json',
              'Authorization': `Bearer ${token}`
            },
            body: JSON.stringify(profileData)
          })

          const data = await response.json()
          
          if (data.success) {
            set(state => ({
              user: state.user ? { ...state.user, ...data.data } : null,
              isLoading: false
            }))
          } else {
            throw new Error(data.error || '更新资料失败')
          }
        } catch (error: any) {
          set({ 
            error: error.message,
            isLoading: false 
          })
          throw error
        }
      },

      changePassword: async (currentPassword: string, newPassword: string) => {
        const { token } = get()
        set({ isLoading: true, error: null })
        
        try {
          const response = await fetch('/api/auth/change-password', {
            method: 'PUT',
            headers: {
              'Content-Type': 'application/json',
              'Authorization': `Bearer ${token}`
            },
            body: JSON.stringify({ 
              currentPassword, 
              newPassword,
              confirmPassword: newPassword 
            })
          })

          const data = await response.json()
          
          if (data.success) {
            set({ isLoading: false })
          } else {
            throw new Error(data.error || '密码修改失败')
          }
        } catch (error: any) {
          set({ 
            error: error.message,
            isLoading: false 
          })
          throw error
        }
      },

      resetPassword: async (email: string) => {
        set({ isLoading: true, error: null })
        
        try {
          const response = await fetch('/api/auth/reset-password', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ email })
          })

          const data = await response.json()
          
          if (!data.success) {
            throw new Error(data.error || '发送重置邮件失败')
          }
          
          set({ isLoading: false })
        } catch (error: any) {
          set({ 
            error: error.message,
            isLoading: false 
          })
          throw error
        }
      },

      confirmPasswordReset: async (token: string, newPassword: string) => {
        set({ isLoading: true, error: null })
        
        try {
          const response = await fetch('/api/auth/reset-password', {
            method: 'PUT',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ 
              token, 
              newPassword,
              confirmPassword: newPassword 
            })
          })

          const data = await response.json()
          
          if (!data.success) {
            throw new Error(data.error || '密码重置失败')
          }
          
          set({ isLoading: false })
        } catch (error: any) {
          set({ 
            error: error.message,
            isLoading: false 
          })
          throw error
        }
      },

      clearError: () => set({ error: null }),
      
      setLoading: (loading: boolean) => set({ isLoading: loading })
    }),
    {
      name: 'auth-storage',
      partialize: (state) => ({
        user: state.user,
        token: state.token,
        refreshToken: state.refreshToken,
        isAuthenticated: state.isAuthenticated
      })
    }
  )
)

// 自动刷新令牌的拦截器
export const setupAuthInterceptor = () => {
  const originalFetch = window.fetch
  
  window.fetch = async function(input: RequestInfo | URL, init?: RequestInit) {
    const { token, refreshTokens, logout } = useAuthStore.getState()
    
    // 为需要认证的请求添加 Authorization header
    if (init?.headers && token) {
      const headers = new Headers(init.headers)
      if (!headers.has('Authorization')) {
        headers.set('Authorization', `Bearer ${token}`)
        init.headers = headers
      }
    }
    
    const response = await originalFetch(input, init)
    
    // 如果返回401，尝试刷新令牌
    if (response.status === 401 && token) {
      try {
        await refreshTokens()
        // 重新发送原请求
        const { token: newToken } = useAuthStore.getState()
        if (newToken && init?.headers) {
          const headers = new Headers(init.headers)
          headers.set('Authorization', `Bearer ${newToken}`)
          init.headers = headers
          return originalFetch(input, init)
        }
      } catch (error) {
        // 刷新失败，登出用户
        logout()
      }
    }
    
    return response
  }
}