import { select as e, put as t, take as o } from "redux-saga/effects"
import { getCoreBackend as i } from "../../../backend"
import { apiCall as s } from "../../../api/core"
import { logWarning as a, taskErrorSaga as r } from "../../error"
import { QUERY_FIRST_LOAD_COUNT as d } from "../chat.constant"
import { isSeqInRange as n, isUnsetRange as m } from "../chat.model"
import {
getCoreId as c,
sendChatMessageSuccess as l,
createFirstQuery as p,
createFirstMiddleQuery as h,
} from "../message"
import { ANCHOR_STATUS as y } from "./list-view.constant"
import { getChatMessageState as u, getChatMessageSeqLoaded as f } from "./list-view-data.selector"
import { getChatListViewState as g, getChatMessagesInView as w } from "./list-view.selector"
import { fetchMessagesCmd as q } from "./list-view-data.action"
import {
chatMessageJumpToBottomCmd as E,
chatMessageJumpToCmd as I,
chatMessageJumpToSeqCmd as b,
setChatMessageAnchor as L,
} from "./list-view.action"
import {
createAnchorToBottom as v,
createAnchorToMessage as J,
isChatListLive as D,
} from "./list-view.model"
import { sharedCoreMessagesUpdate as T } from "../../api/data.action"
export function* chatListViewJumpToSeqHandler(o) {
try {
const { count: i, byId: s, seqLoaded: a } = yield e(u),
{ mode: r } = yield e(g)
if (!D(r)) throw new Error(`chat is not running yet, mode=${r}`)
const { seq: m, pos: c, highlight: l } = o.payload
if (!Number.isInteger(m)) throw new Error("neither messageId nor seq provided")
let p
const f = n(a, m)
if (f) {
if (((p = Object.values(s).find((e) => e.seq === m)), !p))
throw new Error(`unable to get message data for seq=${m}`)
} else p = { seq: m }
const w = J({
highlight: l,
pos: c,
messageId: p.id || "",
seq: p.seq,
status: f ? y.LOADED : y.ASKED,
})
if ((yield t(L(w)), !f)) {
const e = p.seq < d ? d : p.seq,
o = h({ count: i, bottomSeq: e })
yield t(q(o))
}
} catch (e) {
yield r("chatMessageJumpToSeqHandler", e)
}
}
export function* chatListViewJumpToHandler(o, a) {
try {
const { count: r, byId: l } = yield e(u),
{ mode: p } = yield e(g)
if (!D(p)) throw new Error(`chat is not running yet, mode=${p}`)
const { messageId: E, pos: I, highlight: b } = a.payload
if (!E) throw new Error("no messageId provided")
let v = l[E]
if (!v) {
const { deviceId: e, seq: t } = c(E),
a = i()
if (
((v = yield s(a.getChatMessageById, o, { deviceId: e, seq: t })),
!v && !Number.isInteger(v.seq))
)
throw new Error(`unable to get message data for id=${E}`)
}
const T = yield e(f),
V = yield e(w)
let H = y.ASKED
const S = n(T, v.seq)
;(S && (H = y.LOADED), m(V) || V.bottom !== v.seq || (H = y.RENDERED))
const A = J({ highlight: b, pos: I, messageId: E, seq: v.seq, status: H })
if ((yield t(L(A)), !S)) {
const e = v.seq < d ? d : v.seq,
o = h({ count: r, bottomSeq: e })
yield t(q(o))
}
} catch (e) {
yield r("chatMessageJumpToHandler", e)
}
}
export function* chatListViewJumpToBottomHandler(o) {
try {
const { count: i, seqLoaded: s, ids: a } = yield e(u),
{ inView: r } = yield e(g)
if (m(r)) throw new Error(`Invalid inView range top=${r?.top} bottom=${r?.bottom}`)
const d = p({ count: i }),
n = o,
c = s.bottom === i - 1 ? a[0] : "",
l = c ? y.LOADED : y.ASKED,
h = v({ pos: n, status: l, messageId: c })
;(yield t(L(h)), i && !c && (yield t(q(d))))
} catch (e) {
yield r("chatMessageJumpToBottomHandler", e)
}
}
export function* chatListViewJump(i, s) {
const { mode: r, paused: d } = yield e(g)
d
? yield t(a({ message: "Attempt to add an anchor while the chat is paused." }))
: (D(r) || (yield o(T)),
E.match(s)
? yield chatListViewJumpToBottomHandler(s.payload?.pos)
: l.match(s)
? yield chatListViewJumpToBottomHandler()
: I.match(s)
? yield chatListViewJumpToHandler(i, s)
: b.match(s) && (yield chatListViewJumpToSeqHandler(s)))
}
export function* chatListViewJumpToEditingMessage({ payload: o }) {
const { messageId: i } = o,
s = yield e(w),
{ seq: a } = c(i)
n(s, a) || (yield t(I({ messageId: i })))
}