import {removeById} from '@crumbs/core/collections'
import type {Reminder} from '@crumbs/core/schemas'

import {unwrap} from '@/lib/errors'
import {
  createKeyedDetailStore,
  keyedDetailHooks,
  patchData,
  setDetail,
} from '@/lib/keyed-resource'
import {rpc} from '@/lib/rpc'

export type {Reminder}

// pending (unsent) reminders per crumb; auto reminders are materialized
// server-side from the plan/event, manual ones are added here
const useRemindersStore = createKeyedDetailStore(
  async (crumbId: string) => {
    const {reminders} = await unwrap(
      rpc.crumbs[':id'].reminders.$get({param: {id: crumbId}}),
    )
    return reminders
  },
)

const addReminder = async (
  crumbId: string,
  remindAt: Date,
): Promise<void> => {
  const {reminder} = await unwrap(
    rpc.crumbs[':id'].reminders.$post({
      param: {id: crumbId},
      json: {remindAt: remindAt.toISOString()},
    }),
  )
  useRemindersStore.setState((s) => {
    const existing = s.byId[crumbId]?.data ?? []
    const next = [...existing, reminder].sort((a, b) =>
      a.remindAt.localeCompare(b.remindAt),
    )
    return {byId: setDetail(s.byId, crumbId, next)}
  })
}

const removeReminder = async (
  crumbId: string,
  reminderId: string,
): Promise<void> => {
  await unwrap(
    rpc.crumbs[':id'].reminders[':reminderId'].$delete({
      param: {id: crumbId, reminderId},
    }),
  )
  useRemindersStore.setState((s) => ({
    byId: patchData(s.byId, crumbId, (reminders) =>
      removeById(reminders, reminderId),
    ),
  }))
}

export const {useData: useReminders} =
  keyedDetailHooks(useRemindersStore)
export const useLoadReminders = () => useRemindersStore((s) => s.load)
export const useAddReminder = () => addReminder
export const useRemoveReminder = () => removeReminder
