"use client" import { create } from "zustand" import { persist } from "zustand/middleware" import { debouncedPersistJSONStorage } from "@/lib/stores/debounced-json-storage" import type { FullContact } from "./types" import { mergePairKey } from "./duplicate-detection" type ContactsView = "list" | "view" | "create" | "edit" export type ContactCreateDraft = { firstName?: string lastName?: string emails?: { value: string; label: string }[] } export interface DeletedContact { contact: FullContact deletedAt: number reason: string } interface ContactsState { deletedContacts: DeletedContact[] ignoredMergePairs: string[] panelOpen: boolean view: ContactsView activeContactId: string | null searchQuery: string searchMode: boolean createDraft: ContactCreateDraft | null } interface ContactsActions { togglePanel: () => void openPanel: () => void closePanel: () => void openContactDetail: (contactId: string) => void openCreateContact: (draft?: ContactCreateDraft | null) => void clearCreateDraft: () => void setView: (view: ContactsView, activeContactId?: string | null) => void showContactsList: () => void setSearchQuery: (q: string) => void setSearchMode: (active: boolean) => void softDeleteContact: (contact: FullContact, reason?: string) => void restoreContact: (id: string) => void emptyTrash: () => void ignoreMergePair: (idA: string, idB: string) => void } export type ContactsStore = ContactsState & ContactsActions export const useContactsStore = create()( persist( (set) => ({ deletedContacts: [], ignoredMergePairs: [], panelOpen: false, view: "list", activeContactId: null, searchQuery: "", searchMode: false, createDraft: null, togglePanel: () => set((s) => s.panelOpen ? { panelOpen: false, view: "list", activeContactId: null, searchQuery: "", searchMode: false, createDraft: null, } : { panelOpen: true } ), openPanel: () => set({ panelOpen: true }), closePanel: () => set({ panelOpen: false, view: "list", activeContactId: null, searchQuery: "", searchMode: false, createDraft: null, }), openContactDetail: (contactId) => set({ panelOpen: true, view: "view", activeContactId: contactId, searchQuery: "", searchMode: false, createDraft: null, }), openCreateContact: (draft = null) => set({ panelOpen: true, view: "create", activeContactId: null, searchQuery: "", searchMode: false, createDraft: draft, }), clearCreateDraft: () => set({ createDraft: null }), setView: (view, activeContactId = null) => set({ view, activeContactId, createDraft: null }), showContactsList: () => set({ view: "list", activeContactId: null, searchQuery: "", searchMode: false, createDraft: null, }), setSearchQuery: (searchQuery) => set({ searchQuery }), setSearchMode: (searchMode) => set(searchMode ? { searchMode } : { searchMode, searchQuery: "" }), softDeleteContact: (contact, reason = "Supprimé manuellement") => set((s) => ({ deletedContacts: [ ...s.deletedContacts, { contact, deletedAt: Date.now(), reason }, ], activeContactId: s.activeContactId === contact.id ? null : s.activeContactId, view: s.activeContactId === contact.id ? "list" : s.view, })), restoreContact: (id) => set((s) => { const entry = s.deletedContacts.find((d) => d.contact.id === id) if (!entry) return s return { deletedContacts: s.deletedContacts.filter((d) => d.contact.id !== id), } }), emptyTrash: () => set({ deletedContacts: [] }), ignoreMergePair: (idA, idB) => set((s) => { const key = mergePairKey(idA, idB) if (s.ignoredMergePairs.includes(key)) return s return { ignoredMergePairs: [...s.ignoredMergePairs, key] } }), }), { name: "contacts-store", storage: debouncedPersistJSONStorage, partialize: (state) => ({ deletedContacts: state.deletedContacts, ignoredMergePairs: state.ignoredMergePairs, }), } ) )