"use client"

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

export type ScheduleSendPayload = {
  sendAtIso: string
  to: { name: string; email: string }[]
  subject: string
  previewText: string
  bodyHtml: string
}

type ScheduledStoreState = {
  scheduledEmails: Email[]
  snoozedEmails: Email[]
  sentPlaceholderEmails: Email[]
}

function rowToSchedulePayload(row: Email): ScheduleSendPayload {
  const email = row.senderEmail?.trim() ?? ""
  const name = row.scheduledToName ?? row.sender
  return {
    sendAtIso: row.scheduledSendAt ?? new Date().toISOString(),
    to: email ? [{ name, email }] : [],
    subject: row.subject,
    previewText: row.preview,
    bodyHtml: row.body ?? `<p></p>`,
  }
}

type ScheduledStoreActions = {
  createScheduledSend: (payload: ScheduleSendPayload) => { id: string }
  deleteScheduledSend: (id: string) => void
  archiveScheduledSend: (id: string) => void
  snoozeScheduledSend: (id: string) => void
  rescheduleScheduledSend: (id: string, sendAtIso: string) => void
  markScheduledReadState: (id: string, read: boolean) => void
  getScheduledEditPayload: (id: string) => ScheduleSendPayload | null
  updateScheduledSend: (id: string, payload: ScheduleSendPayload) => void
  sendScheduledNow: (id: string) => void
  removeScheduledLocal: (id: string) => void
  /** Mettre en attente depuis la boîte (clone id `snz-…` dans En attente ; l’appelant masque l’id source). */
  snoozeMailboxEmail: (row: Email) => void
  /** Quitter « En attente » : réaffiche dans la Boîte (snz-) ou parmi Planifiés (ex-envoi différé snoozé). */
  restoreSnoozedToInbox: (row: Email) => void
}

export const useScheduledStore = create<ScheduledStoreState & ScheduledStoreActions>()(
  persist(
    (set, get) => ({
      scheduledEmails: [],
      snoozedEmails: [],
      sentPlaceholderEmails: [],

      createScheduledSend: (payload) => {
        const id = `sched-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`
        const first = payload.to[0]
        const toName = first?.name?.trim() || first?.email || "Destinataire"
        const row: Email = {
          id,
          sender: toName,
          senderEmail: first?.email,
          subject: payload.subject.trim() || "(Sans objet)",
          preview: payload.previewText.slice(0, 200),
          body: payload.bodyHtml,
          date: payload.sendAtIso,
          read: true,
          starred: false,
          important: false,
          labels: ["scheduled"],
          scheduledSendAt: payload.sendAtIso,
          scheduledToName: toName,
        }
        set((s) => ({
          scheduledEmails: [row, ...s.scheduledEmails.filter((e) => e.id !== id)],
        }))
        return { id }
      },

      deleteScheduledSend: (id) =>
        set((s) => ({
          scheduledEmails: s.scheduledEmails.filter((e) => e.id !== id),
        })),

      archiveScheduledSend: (id) =>
        set((s) => ({
          scheduledEmails: s.scheduledEmails.filter((e) => e.id !== id),
        })),

      snoozeScheduledSend: (id) =>
        set((s) => {
          const row = s.scheduledEmails.find((e) => e.id === id)
          if (!row) return s
          const wake = new Date(Date.now() + 24 * 60 * 60 * 1000)
          return {
            scheduledEmails: s.scheduledEmails.filter((e) => e.id !== id),
            snoozedEmails: [
              {
                ...row,
                labels: ["snoozed"],
                scheduledSendAt: undefined,
                scheduledToName: undefined,
                snoozeWakeAt: wake.toISOString(),
                sender: row.scheduledToName ?? row.sender,
                read: true,
              },
              ...s.snoozedEmails,
            ],
          }
        }),

      rescheduleScheduledSend: (id, sendAtIso) =>
        set((s) => ({
          scheduledEmails: s.scheduledEmails.map((e) =>
            e.id === id ? { ...e, scheduledSendAt: sendAtIso } : e
          ),
        })),

      markScheduledReadState: (id, read) =>
        set((s) => ({
          scheduledEmails: s.scheduledEmails.map((e) =>
            e.id === id ? { ...e, read } : e
          ),
        })),

      getScheduledEditPayload: (id) => {
        const row = get().scheduledEmails.find((e) => e.id === id)
        if (!row) return null
        return rowToSchedulePayload(row)
      },

      updateScheduledSend: (id, payload) =>
        set((s) => {
          const first = payload.to[0]
          const toName = first?.name?.trim() || first?.email || "Destinataire"
          return {
            scheduledEmails: s.scheduledEmails.map((e) =>
              e.id === id
                ? {
                    ...e,
                    sender: toName,
                    senderEmail: first?.email,
                    subject: payload.subject.trim() || "(Sans objet)",
                    preview: payload.previewText.slice(0, 200),
                    body: payload.bodyHtml,
                    scheduledSendAt: payload.sendAtIso,
                    scheduledToName: toName,
                  }
                : e
            ),
          }
        }),

      sendScheduledNow: (id) =>
        set((s) => {
          const row = s.scheduledEmails.find((e) => e.id === id)
          if (!row) return s
          const now = new Date()
          return {
            scheduledEmails: s.scheduledEmails.filter((e) => e.id !== id),
            sentPlaceholderEmails: [
              {
                id: `sent-now-${Date.now()}-${Math.random().toString(36).slice(2, 5)}`,
                sender: row.scheduledToName ?? row.sender,
                senderEmail: row.senderEmail,
                subject: row.subject,
                preview: row.preview,
                body: row.body,
                date: now.toISOString(),
                read: true,
                starred: false,
                important: false,
                labels: ["sent"],
              },
              ...s.sentPlaceholderEmails,
            ],
          }
        }),

      removeScheduledLocal: (id) =>
        set((s) => ({
          scheduledEmails: s.scheduledEmails.filter((e) => e.id !== id),
        })),

      snoozeMailboxEmail: (row) =>
        set((s) => {
          const persistedId = row.id.startsWith("snz-") ? row.id : `snz-${row.id}`
          const wake = new Date(Date.now() + 24 * 60 * 60 * 1000)
          const wakeIso = wake.toISOString()
          const copy: Email = {
            ...row,
            id: persistedId,
            labels: ["snoozed"],
            snoozeWakeAt: wakeIso,
            scheduledSendAt: undefined,
            scheduledToName: undefined,
            read: true,
          }
          return {
            snoozedEmails: [
              copy,
              ...s.snoozedEmails.filter((e) => e.id !== persistedId),
            ],
          }
        }),

      restoreSnoozedToInbox: (row) =>
        set((s) => {
          const nextSnoozed = s.snoozedEmails.filter((e) => e.id !== row.id)
          if (row.id.startsWith("snz-")) {
            return { snoozedEmails: nextSnoozed }
          }
          const resumeAt =
            row.snoozeWakeAt ??
            new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString()
          const back: Email = {
            ...row,
            labels: ["scheduled"],
            scheduledSendAt: resumeAt,
            scheduledToName: row.sender,
            snoozeWakeAt: undefined,
            date: "",
            read: true,
          }
          return {
            snoozedEmails: nextSnoozed,
            scheduledEmails: [
              back,
              ...s.scheduledEmails.filter((e) => e.id !== row.id),
            ],
          }
        }),
    }),
    {
      name: "ultimail-scheduled-state",
      storage: debouncedPersistJSONStorage,
      version: 1,
    }
  )
)
