import { create } from 'zustand'
import { supabaseProcessRepo } from '@/persistence/supabase/process-repo'
import { supabaseActivityRepo } from '@/persistence/supabase/activity-repo'
import { supabaseGatewayRepo } from '@/persistence/supabase/gateway-repo'
import { supabaseResourceRepo } from '@/persistence/supabase/resource-repo'
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, userId: string) => Promise<void>
  updateProcess: (updates: Partial<Process>, userId: string) => Promise<void>
  updateActivity: (activity: Activity, userId: string) => Promise<void>
  updateGateway: (gateway: GatewayConfig, userId: string) => Promise<void>
  addResource: (resource: Resource, userId: string) => Promise<void>
  updateResource: (resource: Resource, userId: string) => Promise<void>
  deleteResource: (resourceId: string, userId: 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),
        supabaseActivityRepo.getByProcess(processId),
        supabaseGatewayRepo.getByProcess(processId),
        supabaseResourceRepo.getAll(),
      ])
      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, userId) => {
    await supabaseProcessRepo.save(process, userId)
    const [activities, gateways, resources] = await Promise.all([
      supabaseActivityRepo.getByProcess(process.id),
      supabaseGatewayRepo.getByProcess(process.id),
      supabaseResourceRepo.getAll(),
    ])
    set({ currentProcess: process, activities, gateways, resources })
  },

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

  updateActivity: async (activity, userId) => {
    await supabaseActivityRepo.save(activity, userId)
    const current = get().currentProcess
    if (current) {
      const updatedProcess = { ...current, updatedAt: Date.now() }
      await supabaseProcessRepo.save(updatedProcess, userId)
      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, userId) => {
    await supabaseGatewayRepo.save(gateway)
    const current = get().currentProcess
    if (current) {
      const updatedProcess = { ...current, updatedAt: Date.now() }
      await supabaseProcessRepo.save(updatedProcess, userId)
      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, userId) => {
    await supabaseResourceRepo.save(resource, userId)
    const current = get().currentProcess
    if (current) {
      const updatedProcess = { ...current, updatedAt: Date.now() }
      await supabaseProcessRepo.save(updatedProcess, userId)
      set((state) => ({ resources: [...state.resources, resource], currentProcess: updatedProcess }))
    } else {
      set((state) => ({ resources: [...state.resources, resource] }))
    }
  },

  updateResource: async (resource, userId) => {
    await supabaseResourceRepo.save(resource, userId)
    const current = get().currentProcess
    if (current) {
      const updatedProcess = { ...current, updatedAt: Date.now() }
      await supabaseProcessRepo.save(updatedProcess, userId)
      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, userId) => {
    await supabaseResourceRepo.delete(resourceId)
    const current = get().currentProcess
    if (current) {
      const updatedProcess = { ...current, updatedAt: Date.now() }
      await supabaseProcessRepo.save(updatedProcess, userId)
      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 }),
}))
