import { create } from 'zustand'
import { supabaseProcessRepo } from '@/persistence/supabase/process-repo'
import { activityRepo, gatewayRepo, resourceRepo } from '@/persistence/repositories'
import type { Process, Activity, GatewayConfig, Resource } from '@/domain/types'

interface ProcessState {
  currentProcess: Process | null
  activities: Activity[]
  gateways: GatewayConfig[]
  resources: Resource[]
  isLoading: boolean
  error: string | null

  loadProcess: (processId: string) => Promise<void>
  setCurrentProcess: (process: Process) => Promise<void>
  updateProcess: (updates: Partial<Process>) => Promise<void>
  updateActivity: (activity: Activity) => Promise<void>
  updateGateway: (gateway: GatewayConfig) => Promise<void>
  addResource: (resource: Resource) => Promise<void>
  updateResource: (resource: Resource) => Promise<void>
  deleteResource: (resourceId: string) => Promise<void>
  reset: () => void
}

export const useProcessStore = create<ProcessState>((set, get) => ({
  currentProcess: null,
  activities: [],
  gateways: [],
  resources: [],
  isLoading: false,
  error: null,

  loadProcess: async (processId) => {
    set({ isLoading: true, error: null })
    try {
      const [process, activities, gateways, resources] = await Promise.all([
        supabaseProcessRepo.getById(processId),
        activityRepo.getByProcess(processId),
        gatewayRepo.getByProcess(processId),
        resourceRepo.getByProcess(processId),
      ])
      if (!process) throw new Error('Proceso no encontrado')
      set({ currentProcess: process, activities, gateways, resources, isLoading: false })
    } catch (err) {
      set({ error: err instanceof Error ? err.message : 'Error desconocido', isLoading: false })
    }
  },

  setCurrentProcess: async (process) => {
    await supabaseProcessRepo.save(process)
    const [activities, gateways, resources] = await Promise.all([
      activityRepo.getByProcess(process.id),
      gatewayRepo.getByProcess(process.id),
      resourceRepo.getByProcess(process.id),
    ])
    set({ currentProcess: process, activities, gateways, resources })
  },

  updateProcess: async (updates) => {
    const current = get().currentProcess
    if (!current) return
    const updated: Process = { ...current, ...updates, updatedAt: Date.now() }
    await supabaseProcessRepo.save(updated)
    set({ currentProcess: updated })
  },

  updateActivity: async (activity) => {
    await activityRepo.save(activity)
    const current = get().currentProcess
    if (current) {
      const updatedProcess = { ...current, updatedAt: Date.now() }
      await supabaseProcessRepo.save(updatedProcess)
      set((state) => ({
        activities: state.activities.map((a) => (a.id === activity.id ? activity : a)),
        currentProcess: updatedProcess,
      }))
    } else {
      set((state) => ({
        activities: state.activities.map((a) => (a.id === activity.id ? activity : a)),
      }))
    }
  },

  updateGateway: async (gateway) => {
    await gatewayRepo.save(gateway)
    const current = get().currentProcess
    if (current) {
      const updatedProcess = { ...current, updatedAt: Date.now() }
      await supabaseProcessRepo.save(updatedProcess)
      set((state) => ({
        gateways: state.gateways.map((g) => (g.id === gateway.id ? gateway : g)),
        currentProcess: updatedProcess,
      }))
    } else {
      set((state) => ({
        gateways: state.gateways.map((g) => (g.id === gateway.id ? gateway : g)),
      }))
    }
  },

  addResource: async (resource) => {
    await resourceRepo.save(resource)
    const current = get().currentProcess
    if (current) {
      const updatedProcess = { ...current, updatedAt: Date.now() }
      await supabaseProcessRepo.save(updatedProcess)
      set((state) => ({ resources: [...state.resources, resource], currentProcess: updatedProcess }))
    } else {
      set((state) => ({ resources: [...state.resources, resource] }))
    }
  },

  updateResource: async (resource) => {
    await resourceRepo.save(resource)
    const current = get().currentProcess
    if (current) {
      const updatedProcess = { ...current, updatedAt: Date.now() }
      await supabaseProcessRepo.save(updatedProcess)
      set((state) => ({
        resources: state.resources.map((r) => (r.id === resource.id ? resource : r)),
        currentProcess: updatedProcess,
      }))
    } else {
      set((state) => ({
        resources: state.resources.map((r) => (r.id === resource.id ? resource : r)),
      }))
    }
  },

  deleteResource: async (resourceId) => {
    await resourceRepo.delete(resourceId)
    const current = get().currentProcess
    if (current) {
      const updatedProcess = { ...current, updatedAt: Date.now() }
      await supabaseProcessRepo.save(updatedProcess)
      set((state) => ({
        resources: state.resources.filter((r) => r.id !== resourceId),
        currentProcess: updatedProcess,
      }))
    } else {
      set((state) => ({ resources: state.resources.filter((r) => r.id !== resourceId) }))
    }
  },

  reset: () => set({ currentProcess: null, activities: [], gateways: [], resources: [], error: null }),
}))
