"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<ContactsStore>()(
  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,
      }),
    }
  )
)
