import {
select as e,
put as i,
take as l,
getContext as t,
call as a,
takeLatest as n,
takeEvery as o,
delay as r,
fork as d,
race as c,
} from "redux-saga/effects"
import { getAppCurrentRoomId as y, hasAppCurrentRoomCallMatch as s } from "../app"
import { getRoomCanCall as m, getRoomItemById as g } from "../room"
import { taskErrorSaga as u } from "../error"
import {
getCallStatus as p,
getCallId as C,
callJoinCmd as f,
callLeave as S,
CALL_STATUS as v,
openCallSettings as R,
isCallJoinedMode as A,
updateCallRemoteMedia as E,
removeCallRemoteMedia as b,
STREAM_TYPE as h,
callCancel as w,
} from "../call"
import {
uiLeaveAndJoinNewCall as N,
uiShowMicPermissionBottomSheet as O,
uiShowCallOnGoingBottomSheet as _,
uiStartCall as I,
uiCallWebrtcCleared as L,
uiExpoDeviceVibrateSuccess as x,
uiNavigateToRoute as M,
uiShowCallPreview as T,
uiCallFetchAudioOutputs as F,
uiUpdateWorklet as k,
} from "./ui.action"
import { APP_CONTEXT_KEY as H } from "../constants"
import { userErrorNotification as J, userInfoNotification as V } from "../notification"
import {
setUIIsCallLoading as j,
setUICallAudioOutputs as D,
setUICallCurrentAudioOutput as K,
getUIAppNavigatorCurrentRoute as P,
setUICallScreenVideoTrackId as U,
} from "./ui.reducer"
import { requestMicPermissionSaga as W } from "../media/media-permissions.saga"
import { getCallApi as B, getCoreBackend as X } from "../../backend"
import { apiTakeMatch as q } from "../lib/external-src"
import { setupWebrtcCallInfra as z } from "./ui-call.utils"
export const MAX_ACTIVE_CALL_WAIT = 2e4
export function* waitForActiveCallSync(e) {
try {
const n = X(),
o = yield c({
hasActiveCall: q([n.subscribeActiveCalls, e], {
matchFn: (e) => e.length > 0,
onError: (e) => u("waitForActiveCallSync: subscribeActiveCalls", e),
}),
cancelled: l(w),
timedout: r(2e4),
})
if (o.timedout) {
const { navigationHelpers: e, webRTC: l, localeManager: n } = yield t(H),
o = n.getStrings(),
{ timedoutJoinCall: r } = o.call
;(yield i(J({ message: r })),
e.back(),
yield a(l.setInCall, { enabled: !1 }),
yield i(L()),
yield i(k()))
}
return o
} catch (e) {
return (yield u("waitForActiveCallSync", e), { timedout: !0 })
}
}
function* G(l) {
try {
const { payload: n } = l || {},
o = yield e(y),
r = n?.answeringCallRing
if (o) {
const { localeManager: l, navigationConstants: d } = yield t(H),
c = l.getStrings(),
y = yield e(g(o))
if (!y.canCall) return void (yield i(V({ message: c.room.callDisabledNotification })))
const m = yield e(p),
u = yield e(s)
if (m === v.JOINED && !u) return void (yield i(_()))
if ((yield i(j(!0)), !(yield W()))) return void (yield i(O()))
if (r) {
const { timedout: e, cancelled: i } = yield a(waitForActiveCallSync, o)
if (e || i) return
}
;(yield i(f()),
yield i(M({ routeName: d.SCREEN_ROOM_CALL, params: { roomId: o } })),
yield a(z, {
roomTitle: y.title,
hasExistingCallKit: r,
answeringInAppCallRing: n?.answeringInAppCallRing,
}))
}
} catch (e) {
yield u("startCallSaga", e)
} finally {
yield i(j(!1))
}
}
function* Q() {
try {
const { navigationConstants: e, navigationHelpers: a } = yield t(H)
;(yield i(S()), yield l(L), yield r(500), yield i(R()), a.navigate(e.SCREEN_ROOM_CALL_PREVIEW))
} catch (e) {
yield u("leaveAndJoinNewCallSaga", e)
}
}
function* Y() {
try {
const {
navigationConstants: l,
navigationHelpers: n,
webRTC: o,
callBackgroundHandler: r,
} = yield t(H)
;((yield e(P)) === l.SCREEN_ROOM_CALL && n.back(),
yield a(o.setInCall, { enabled: !1 }),
yield a(r.stopService),
yield a(o.setKeepScreenOn, !1),
yield i(L()))
} catch (e) {
yield u("uiCallLeaveSaga", e)
}
}
function* Z(l) {
try {
const { payload: a } = l || {},
n = a?.joinCall,
o = yield e(y),
r = yield e(p),
d = yield e(s),
c = yield A(r),
g = yield e(m(o)),
{ navigationConstants: u, navigationHelpers: C, localeManager: f } = yield t(H),
S = f.getStrings()
;(yield i(x(o)),
c && !d
? yield i(_())
: g
? (yield i(R()), C.navigate(u.SCREEN_ROOM_CALL_PREVIEW, { joinCall: n }))
: yield i(V({ message: S.room.callDisabledNotification })))
} catch (e) {
yield u("showCallPreviewSaga", e)
}
}
function* $() {
try {
const { webRTC: e } = yield t(H),
l = yield a(e.listAudioRoutes)
yield i(D(l))
const n = yield a(e.getAudioOutput)
yield i(K(n.type))
} catch (e) {
yield u("uiCallFetchAudioOutputsSaga", e)
}
}
function* ee(i) {
try {
if (!i.payload?.resume) return
const l = yield e(y),
t = yield e(g(l))
yield d(z, { roomTitle: t.title, hasExistingCallKit: !1, answeringInAppCallRing: !1 })
} catch (e) {
yield u("resumeCallJoinSaga", e)
}
}
export function* screenStreamUpdateSaga(l) {
try {
const { streamName: t, streamId: a, videoMuted: n } = l.payload
if (t !== h.SCREEN) return
if (n) return void (yield i(U(null)))
const o = yield e(C)
if (!o || !a) return
const r = B().getRemoteSrcObject(o, a),
d = r?.getVideoTracks?.()[0]
yield i(U(d ? String(d) : null))
} catch (e) {
yield u("screenStreamUpdateSaga", e)
}
}
export function* screenStreamRemoveSaga(e) {
e.payload?.streamName === h.SCREEN && (yield i(U(null)))
}
export function* uiCallSaga() {
;(yield n(I, G),
yield n(S, Y),
yield n(N, Q),
yield n(T, Z),
yield n(F, $),
yield n(f, ee),
yield o(E, screenStreamUpdateSaga),
yield o(b, screenStreamRemoveSaga))
}