"use client"

import { create } from "zustand"
import { persist } from "zustand/middleware"
import { debouncedPersistJSONStorage } from "@/lib/stores/debounced-json-storage"

/**
 * Persistent mail store — survives across navigations and page reloads.
 * Tracks user-driven mutations on top of the static `emails` array from email-data.ts.
 * Designed for future server sync: every action is a discrete delta.
 */

export type LabelEditState = {
  additions: Record<string, string[]>
  removals: Record<string, string[]>
}

type MailStoreState = {
  readOverrides: Record<string, boolean>
  starredIds: string[]
  importantIds: string[]
  labelEdits: LabelEditState
  hiddenEmailIds: string[]
  seenEmailIds: string[]
  /** Ids marqués comme non-spam (réintégration boîte de réception dans l’UI). */
  notSpamEmailIds: string[]
  recentMoveTargets: string[]
  /** Dernières boîtes visitées (clés `mailNavVisitKey`), la plus récente en tête. */
  recentFolderVisits: string[]
}

type MailStoreActions = {
  setReadOverride: (id: string, read: boolean) => void
  setReadOverrides: (overrides: Record<string, boolean>) => void
  toggleStar: (id: string) => void
  setStar: (id: string, starred: boolean) => void
  toggleImportant: (id: string) => void
  setImportant: (id: string, important: boolean) => void
  addLabel: (emailId: string, label: string) => void
  removeLabel: (emailId: string, label: string) => void
  setLabelEdits: (updater: (prev: LabelEditState) => LabelEditState) => void
  hideEmail: (id: string) => void
  hideEmails: (ids: string[]) => void
  unhideEmail: (id: string) => void
  markSeen: (id: string) => void
  /** Réintègre le message comme non-spam (liste / boîte de réception). */
  markNotSpam: (id: string) => void
  resetHidden: () => void
  pushRecentMoveTarget: (targetId: string) => void
  pushRecentFolderVisit: (visitKey: string) => void
}

export const useMailStore = create<MailStoreState & MailStoreActions>()(
  persist(
    (set) => ({
      readOverrides: {},
      starredIds: [],
      importantIds: [],
      labelEdits: { additions: {}, removals: {} },
      hiddenEmailIds: [],
      seenEmailIds: [],
      notSpamEmailIds: [],
      recentMoveTargets: [],
      recentFolderVisits: [],

      setReadOverride: (id, read) =>
        set((s) => ({ readOverrides: { ...s.readOverrides, [id]: read } })),

      setReadOverrides: (overrides) =>
        set((s) => ({ readOverrides: { ...s.readOverrides, ...overrides } })),

      toggleStar: (id) =>
        set((s) => ({
          starredIds: s.starredIds.includes(id)
            ? s.starredIds.filter((x) => x !== id)
            : [...s.starredIds, id],
        })),

      setStar: (id, starred) =>
        set((s) => ({
          starredIds: starred
            ? s.starredIds.includes(id) ? s.starredIds : [...s.starredIds, id]
            : s.starredIds.filter((x) => x !== id),
        })),

      toggleImportant: (id) =>
        set((s) => ({
          importantIds: s.importantIds.includes(id)
            ? s.importantIds.filter((x) => x !== id)
            : [...s.importantIds, id],
        })),

      setImportant: (id, important) =>
        set((s) => ({
          importantIds: important
            ? s.importantIds.includes(id) ? s.importantIds : [...s.importantIds, id]
            : s.importantIds.filter((x) => x !== id),
        })),

      addLabel: (emailId, label) =>
        set((s) => {
          const curr = s.labelEdits.additions[emailId] ?? []
          if (curr.some((l) => l.toLowerCase() === label.toLowerCase())) return s
          return {
            labelEdits: {
              additions: { ...s.labelEdits.additions, [emailId]: [...curr, label] },
              removals: {
                ...s.labelEdits.removals,
                [emailId]: (s.labelEdits.removals[emailId] ?? []).filter(
                  (r) => r.toLowerCase() !== label.toLowerCase()
                ),
              },
            },
          }
        }),

      removeLabel: (emailId, label) =>
        set((s) => {
          const curr = s.labelEdits.removals[emailId] ?? []
          if (curr.some((l) => l.toLowerCase() === label.toLowerCase())) return s
          return {
            labelEdits: {
              removals: { ...s.labelEdits.removals, [emailId]: [...curr, label] },
              additions: {
                ...s.labelEdits.additions,
                [emailId]: (s.labelEdits.additions[emailId] ?? []).filter(
                  (a) => a.toLowerCase() !== label.toLowerCase()
                ),
              },
            },
          }
        }),

      setLabelEdits: (updater) =>
        set((s) => ({ labelEdits: updater(s.labelEdits) })),

      hideEmail: (id) =>
        set((s) => ({
          hiddenEmailIds: s.hiddenEmailIds.includes(id)
            ? s.hiddenEmailIds
            : [...s.hiddenEmailIds, id],
        })),

      hideEmails: (ids) =>
        set((s) => {
          const existing = new Set(s.hiddenEmailIds)
          const toAdd = ids.filter((id) => !existing.has(id))
          return toAdd.length > 0
            ? { hiddenEmailIds: [...s.hiddenEmailIds, ...toAdd] }
            : s
        }),

      unhideEmail: (id) =>
        set((s) => ({
          hiddenEmailIds: s.hiddenEmailIds.filter((x) => x !== id),
        })),

      markNotSpam: (id) =>
        set((s) =>
          s.notSpamEmailIds.includes(id)
            ? s
            : { notSpamEmailIds: [...s.notSpamEmailIds, id] }
        ),

      markSeen: (id) =>
        set((s) => ({
          seenEmailIds: s.seenEmailIds.includes(id)
            ? s.seenEmailIds
            : [...s.seenEmailIds, id],
        })),

      resetHidden: () => set({ hiddenEmailIds: [] }),

      pushRecentMoveTarget: (targetId) =>
        set((s) => {
          const MAX = 5
          const filtered = s.recentMoveTargets.filter((t) => t !== targetId)
          return { recentMoveTargets: [targetId, ...filtered].slice(0, MAX) }
        }),

      pushRecentFolderVisit: (visitKey) =>
        set((s) => {
          const MAX = 4
          const filtered = s.recentFolderVisits.filter((k) => k !== visitKey)
          return { recentFolderVisits: [visitKey, ...filtered].slice(0, MAX) }
        }),
    }),
    {
      name: "ultimail-mail-state",
      storage: debouncedPersistJSONStorage,
      version: 3,
      migrate: (persisted, version) => {
        const state = persisted as MailStoreState & { notSpamEmailIds?: string[] }
        if (version < 2) {
          return { ...state, recentFolderVisits: [], notSpamEmailIds: [] }
        }
        if (version < 3) {
          return { ...state, notSpamEmailIds: state.notSpamEmailIds ?? [] }
        }
        return state
      },
    }
  )
)
