import { create } from 'zustand'

export type ModelFormat = 'gltf' | 'glb' | 'obj' | 'fbx' | 'ply' | 'las' | 'laz' | 'splat'

export interface Model3D {
  id: string
  name: string
  description?: string
  format: ModelFormat
  url: string
  shareUrl?: string
  thumbnailUrl?: string
  metadata?: {
    location?: string
    captureDate?: string
    droneModel?: string
    software?: string
    polygons?: number
    points?: number
    fileSize?: string
  }
  createdAt: Date
  fileSize?: number
}

export type ViewMode = 'gallery' | 'viewer'
export type ToolMode = 'orbit' | 'pan' | 'zoom' | 'measure' | 'annotate'

interface ViewerSettings {
  showGrid: boolean
  showAxes: boolean
  backgroundColor: string
  ambientIntensity: number
  pointSize: number
  wireframe: boolean
  autoRotate: boolean
}

interface AppState {
  // Navigation
  viewMode: ViewMode
  setViewMode: (mode: ViewMode) => void
  
  // Models
  models: Model3D[]
  selectedModel: Model3D | null
  isLoading: boolean
  error: string | null
  
  // Actions (static mode: local-only; no backend required)
  loadModels: () => Promise<void>
  addModel: (model: Model3D) => void
  uploadModel: (file: File, metadata?: any) => Promise<Model3D>
  removeModel: (id: string) => Promise<void>
  selectModel: (model: Model3D | null) => void
  
  // Viewer
  toolMode: ToolMode
  setToolMode: (mode: ToolMode) => void
  loadingProgress: number
  setLoadingProgress: (progress: number) => void
  
  // Settings
  settings: ViewerSettings
  updateSettings: (settings: Partial<ViewerSettings>) => void
  
  // UI
  sidebarOpen: boolean
  setSidebarOpen: (open: boolean) => void
}

const supportedExtensions: ModelFormat[] = ['glb', 'gltf', 'obj', 'fbx', 'ply', 'las', 'laz', 'splat']

const guessFormat = (filename: string): ModelFormat | null => {
  const ext = filename.split('.').pop()?.toLowerCase() as ModelFormat | undefined
  if (!ext) return null
  return supportedExtensions.includes(ext) ? ext : null
}

export const useStore = create<AppState>((set, get) => ({
  // Navigation
  viewMode: 'gallery',
  setViewMode: (mode) => set({ viewMode: mode }),
  
  // Models
  models: [],
  selectedModel: null,
  isLoading: false,
  error: null,
  
  // Static mode: no backend. Keep as no-op.
  loadModels: async () => {
    // intentionally empty
  },
  
  addModel: (model) => set((state) => ({ models: [model, ...state.models] })),
  
  uploadModel: async (file: File, metadata?: any) => {
    set({ isLoading: true, error: null })
    try {
      const format = guessFormat(file.name)
      if (!format) throw new Error('Unsupported file type')

      const model: Model3D = {
        id: `local-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`,
        name: metadata?.name || file.name.replace(/\.[^/.]+$/, ''),
        description: metadata?.description,
        format,
        url: URL.createObjectURL(file),
        metadata: {
          ...(metadata?.metadata || {}),
          fileSize: `${(file.size / (1024 * 1024)).toFixed(1)} MB`,
          captureDate: new Date().toISOString().split('T')[0],
        },
        createdAt: new Date(),
        fileSize: file.size,
      }

      set((state) => ({
        models: [model, ...state.models],
        isLoading: false,
      }))

      return model
    } catch (error: any) {
      set({ error: error?.message || 'Failed to add model', isLoading: false })
      throw error
    }
  },
  
  removeModel: async (id: string) => {
    set((state) => ({
      models: state.models.filter((m) => m.id !== id),
      selectedModel: state.selectedModel?.id === id ? null : state.selectedModel,
    }))
  },
  
  selectModel: (model) => set({ selectedModel: model, viewMode: model ? 'viewer' : 'gallery' }),
  
  // Viewer
  toolMode: 'orbit',
  setToolMode: (mode) => set({ toolMode: mode }),
  loadingProgress: 0,
  setLoadingProgress: (progress) => set({ loadingProgress: progress }),
  
  // Settings
  settings: {
    showGrid: true,
    showAxes: false,
    backgroundColor: '#f8fafc',
    ambientIntensity: 0.6,
    pointSize: 1,
    wireframe: false,
    autoRotate: false
  },
  updateSettings: (newSettings) => set((state) => ({
    settings: { ...state.settings, ...newSettings }
  })),
  
  // UI
  sidebarOpen: true,
  setSidebarOpen: (open) => set({ sidebarOpen: open })
}))
