import { create } from 'zustand'
import {
  AppVersion,
  CreateVersionInput,
  UpdateVersionInput,
  UploadVersionInput,
  Platform,
} from '@/domain'
import { getVersionRepository, AppType } from '@/infrastructure'

interface VersionState {
  versions: AppVersion[]
  selectedVersion: AppVersion | null
  isLoading: boolean
  error: string | null
  appType: AppType
  filter: {
    platform?: Platform
    includeDisabled: boolean
  }

  // Actions
  setAppType: (appType: AppType) => void
  fetchVersions: () => Promise<void>
  fetchVersionById: (id: string) => Promise<void>
  createVersion: (input: CreateVersionInput) => Promise<AppVersion>
  updateVersion: (id: string, input: UpdateVersionInput) => Promise<AppVersion>
  deleteVersion: (id: string) => Promise<void>
  toggleVersion: (id: string, isEnabled: boolean) => Promise<void>
  uploadVersion: (input: UploadVersionInput) => Promise<AppVersion>
  setFilter: (filter: Partial<VersionState['filter']>) => void
  setSelectedVersion: (version: AppVersion | null) => void
  clearError: () => void
}

export const useVersionStore = create<VersionState>((set, get) => ({
  versions: [],
  selectedVersion: null,
  isLoading: false,
  error: null,
  appType: 'mobile',
  filter: {
    platform: undefined,
    includeDisabled: true,
  },

  setAppType: (appType: AppType) => {
    set({ appType, versions: [], selectedVersion: null, error: null })
  },

  fetchVersions: async () => {
    set({ isLoading: true, error: null })
    try {
      const { filter, appType } = get()
      const repository = getVersionRepository(appType)
      const versions = await repository.list(filter)
      set({ versions, isLoading: false })
    } catch (err) {
      set({
        error: err instanceof Error ? err.message : 'Failed to fetch versions',
        isLoading: false,
      })
    }
  },

  fetchVersionById: async (id: string) => {
    set({ isLoading: true, error: null })
    try {
      const { appType } = get()
      const repository = getVersionRepository(appType)
      const version = await repository.getById(id)
      set({ selectedVersion: version, isLoading: false })
    } catch (err) {
      set({
        error: err instanceof Error ? err.message : 'Failed to fetch version',
        isLoading: false,
      })
    }
  },

  createVersion: async (input: CreateVersionInput) => {
    set({ isLoading: true, error: null })
    try {
      const { appType } = get()
      const repository = getVersionRepository(appType)
      const version = await repository.create(input)
      const { versions } = get()
      set({ versions: [version, ...versions], isLoading: false })
      return version
    } catch (err) {
      set({
        error: err instanceof Error ? err.message : 'Failed to create version',
        isLoading: false,
      })
      throw err
    }
  },

  updateVersion: async (id: string, input: UpdateVersionInput) => {
    set({ isLoading: true, error: null })
    try {
      const { appType } = get()
      const repository = getVersionRepository(appType)
      const version = await repository.update(id, input)
      const { versions } = get()
      set({
        versions: versions.map((v) => (v.id === id ? version : v)),
        selectedVersion: version,
        isLoading: false,
      })
      return version
    } catch (err) {
      set({
        error: err instanceof Error ? err.message : 'Failed to update version',
        isLoading: false,
      })
      throw err
    }
  },

  deleteVersion: async (id: string) => {
    set({ isLoading: true, error: null })
    try {
      const { appType } = get()
      const repository = getVersionRepository(appType)
      await repository.delete(id)
      const { versions, selectedVersion } = get()
      set({
        versions: versions.filter((v) => v.id !== id),
        selectedVersion: selectedVersion?.id === id ? null : selectedVersion,
        isLoading: false,
      })
    } catch (err) {
      set({
        error: err instanceof Error ? err.message : 'Failed to delete version',
        isLoading: false,
      })
      throw err
    }
  },

  toggleVersion: async (id: string, isEnabled: boolean) => {
    set({ isLoading: true, error: null })
    try {
      const { appType } = get()
      const repository = getVersionRepository(appType)
      await repository.toggle(id, isEnabled)
      const { versions } = get()
      set({
        versions: versions.map((v) =>
          v.id === id ? { ...v, isEnabled } : v
        ),
        isLoading: false,
      })
    } catch (err) {
      set({
        error: err instanceof Error ? err.message : 'Failed to toggle version',
        isLoading: false,
      })
      throw err
    }
  },

  uploadVersion: async (input: UploadVersionInput) => {
    set({ isLoading: true, error: null })
    try {
      const { appType } = get()
      const repository = getVersionRepository(appType)
      const version = await repository.upload(input)
      const { versions } = get()
      set({ versions: [version, ...versions], isLoading: false })
      return version
    } catch (err) {
      set({
        error: err instanceof Error ? err.message : 'Failed to upload version',
        isLoading: false,
      })
      throw err
    }
  },

  setFilter: (filter) => {
    set((state) => ({
      filter: { ...state.filter, ...filter },
    }))
  },

  setSelectedVersion: (version) => {
    set({ selectedVersion: version })
  },

  clearError: () => {
    set({ error: null })
  },
}))
